From 8f02b2eb5f172fcfadcbe12c4cc50b54941a4562 Mon Sep 17 00:00:00 2001 From: Andrea Fazzi Date: Sat, 7 Dec 2019 11:44:19 +0100 Subject: [PATCH] Working on participant subscription workflow of school user --- errors/errors.go | 11 +++++-- handlers/role.go | 2 +- i18n/i18n.go | 5 ++++ orm/participant.go | 33 ++++++++++++++++++--- orm/role.go | 38 +++++++++++++++++++++++++ orm/school.go | 12 +++++++- renderer/funcmap.go | 5 ++++ templates/layout/base.html.tpl | 15 +++++++++- templates/layout/show_header.html.tpl | 2 ++ templates/participants_show.html.tpl | 11 ++++++- templates/schools_add_update.html.tpl | 27 ++++++++++++++++-- templates/schools_show.html.tpl | 41 +++++++++++++++++++-------- 12 files changed, 177 insertions(+), 25 deletions(-) create mode 100644 orm/role.go diff --git a/errors/errors.go b/errors/errors.go index ff060828..584aae79 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -1,5 +1,12 @@ package errors -import "errors" +import ( + "errors" -var RecordExists = errors.New("Record already exists!") + "git.andreafazzi.eu/andrea/oef/i18n" +) + +var ( + RecordExists = errors.New("Record already exists!") + NotAuthorized = errors.New(i18n.Authorization["notAuthorized"]["it"]) +) diff --git a/handlers/role.go b/handlers/role.go index ab5c4776..0056f0dd 100644 --- a/handlers/role.go +++ b/handlers/role.go @@ -21,7 +21,7 @@ var ( }, "school": map[string][]int{ - "Participant": []int{PermissionCreate, PermissionRead, PermissionReadAll, PermissionUpdate, PermissionDelete}, + "Participant": []int{PermissionCreate, PermissionRead, PermissionUpdate, PermissionDelete}, "School": []int{PermissionRead, PermissionUpdate}, }, diff --git a/i18n/i18n.go b/i18n/i18n.go index c893bd22..ef0b1606 100644 --- a/i18n/i18n.go +++ b/i18n/i18n.go @@ -17,4 +17,9 @@ var ( "it": "il %02d/%02d/%d alle ore %02d:%02d", }, } + Authorization = map[string]map[string]string{ + "notAuthorized": map[string]string{ + "it": "Non si è autorizzati ad accedere a questa pagina", + }, + } ) diff --git a/orm/participant.go b/orm/participant.go index 2d69f3fe..4a7682bf 100644 --- a/orm/participant.go +++ b/orm/participant.go @@ -2,11 +2,13 @@ package orm import ( "fmt" + "strconv" "net/http" "strings" "git.andreafazzi.eu/andrea/oef/config" + "git.andreafazzi.eu/andrea/oef/errors" "git.andreafazzi.eu/andrea/oef/i18n" "git.andreafazzi.eu/andrea/oef/renderer" "github.com/jinzhu/gorm" @@ -122,8 +124,19 @@ func (model *Participant) Create(args map[string]string, w http.ResponseWriter, if err := DB().Find(&participant.AllContests).Error; err != nil { return nil, err } - if err := DB().Find(&participant.AllSchools).Error; err != nil { - return nil, err + if isSchool(r) { + schoolID, err := strconv.Atoi(getUserIDFromToken(r)) + if err != nil { + return nil, err + } + if err := DB().Find(&participant.AllSchools, schoolID).Error; err != nil { + return nil, err + } + + } else { + if err := DB().Find(&participant.AllSchools).Error; err != nil { + return nil, err + } } return participant, nil } else { @@ -161,6 +174,18 @@ func (model *Participant) Read(args map[string]string, w http.ResponseWriter, r id := args["id"] + // School user can access to its participants only! + if isSchool(r) { + if err := DB().Preload("School").First(&participant, id).Error; err != nil { + return nil, err + } + + if strconv.Itoa(int(participant.SchoolID)) != getUserIDFromToken(r) { + setFlashMessage(w, r, "notAuthorized") + return nil, errors.NotAuthorized + } + } + if err := DB().Preload("User").Preload("School").Preload("Responses").Preload("Contests").First(&participant, id).Error; err != nil { return nil, err } @@ -228,7 +253,7 @@ func (model *Participant) Update(args map[string]string, w http.ResponseWriter, return nil, err } - participant.(*School).UserModifierUpdate = NewUserModifierUpdate(r) + participant.(*Participant).UserModifierUpdate = NewUserModifierUpdate(r) _, err = SaveParticipant(participant) if err != nil { @@ -271,7 +296,7 @@ func CreateParticipant(participant *Participant) (*Participant, error) { func SaveParticipant(participant interface{}) (interface{}, error) { participant.(*Participant).FiscalCode = strings.ToUpper(participant.(*Participant).FiscalCode) - if err := DB(). /*.Omit("Something")*/ Save(participant).Error; err != nil { + if err := DB().Omit("School").Save(participant).Error; err != nil { return nil, err } return participant, nil diff --git a/orm/role.go b/orm/role.go new file mode 100644 index 00000000..3d11821c --- /dev/null +++ b/orm/role.go @@ -0,0 +1,38 @@ +package orm + +import ( + "net/http" + + "github.com/dgrijalva/jwt-go" +) + +func getClaims(r *http.Request) jwt.MapClaims { + return r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims) +} + +func isRole(role string, r *http.Request) bool { + if r.Context().Value("user") != nil { + return getClaims(r)["role"].(string) == role + } + return false +} + +func isAdministrator(r *http.Request) bool { + return isRole("administrator", r) +} + +func isParticipant(r *http.Request) bool { + return isRole("participant", r) +} + +func isSchool(r *http.Request) bool { + return isRole("school", r) +} + +func isSubscriber(r *http.Request) bool { + return isRole("subscriber", r) +} + +func getUserIDFromToken(r *http.Request) string { + return getClaims(r)["user_id"].(string) +} diff --git a/orm/school.go b/orm/school.go index 2d863c1d..f1d0e430 100644 --- a/orm/school.go +++ b/orm/school.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "git.andreafazzi.eu/andrea/oef/errors" "git.andreafazzi.eu/andrea/oef/mail" "git.andreafazzi.eu/andrea/oef/renderer" "github.com/jinzhu/gorm" @@ -69,6 +70,10 @@ func (model *School) BeforeSave(tx *gorm.DB) error { return err } model.UserID = user.ID + + // School code is always uppercase + model.Code = strings.ToUpper(model.Code) + return nil } @@ -134,6 +139,11 @@ func (model *School) Read(args map[string]string, w http.ResponseWriter, r *http id := args["id"] + if isSchool(r) && id != getUserIDFromToken(r) { + setFlashMessage(w, r, "notAuthorized") + return nil, errors.NotAuthorized + } + if err := DB().Preload("User").Preload("Participants").First(&school, id).Error; err != nil { return nil, err } @@ -222,7 +232,7 @@ func CreateSchool(school *School) (*School, error) { } func SaveSchool(school interface{}) (interface{}, error) { - school.(*School).Code = strings.ToUpper(school.(*School).Code) + // school.(*School).Code = strings.ToUpper(school.(*School).Code) if err := DB(). /*.Omit("Something")*/ Save(school).Error; err != nil { return nil, err } diff --git a/renderer/funcmap.go b/renderer/funcmap.go index 05012702..5e144897 100644 --- a/renderer/funcmap.go +++ b/renderer/funcmap.go @@ -54,6 +54,7 @@ var ( "isAdmin": isAdmin, "isParticipant": isParticipant, "isSubscriber": isSubscriber, + "isSchool": isSchool, "attr": attr, } ) @@ -70,6 +71,10 @@ func isParticipant(claims jwt.MapClaims) bool { return claims["role"].(string) == "participant" } +func isSchool(claims jwt.MapClaims) bool { + return claims["role"].(string) == "school" +} + func isSubscriber(claims jwt.MapClaims) bool { return claims["role"].(string) == "subscriber" } diff --git a/templates/layout/base.html.tpl b/templates/layout/base.html.tpl index 3bccf7bc..d1dfe2e8 100644 --- a/templates/layout/base.html.tpl +++ b/templates/layout/base.html.tpl @@ -1,4 +1,10 @@ {{define "base"}} + +{{$isAdmin := .Claims|isAdmin}} +{{$isSubscriber := .Claims|isSubscriber}} +{{$isSchool := .Claims|isSchool}} +{{$isParticipant := .Claims|isParticipant}} + @@ -12,7 +18,14 @@