Add role.go

This commit is contained in:
Andrea Fazzi 2019-12-04 12:20:34 +01:00
parent 519f6438b5
commit 98114bfab1
3 changed files with 86 additions and 9 deletions

View file

@ -28,6 +28,15 @@ type PathPattern struct {
PathPattern string
RedirectPattern string
Methods []string
Permission int
}
var (
permissions map[string]map[string]bool
)
func init() {
permissions = make(map[string]map[string]bool, 0)
}
func (pp PathPattern) RedirectPath(model string, id ...uint) string {
@ -57,11 +66,11 @@ func pluralizedModelName(s interface{}) string {
func generateHandler(r *mux.Router, model interface{}) {
var (
patterns []PathPattern = []PathPattern{
PathPattern{"/%s", "", []string{"GET"}},
PathPattern{"/%s/{id}", "", []string{"GET"}},
PathPattern{"/%s/create/", "/%s/%d?format=html&tpl_layout=base&tpl_content=%s_show", []string{"GET", "POST"}},
PathPattern{"/%s/{id}/update", "/%s/%d?format=html&tpl_layout=base&tpl_content=%s_show", []string{"GET", "POST"}},
PathPattern{"/%s/{id}/delete", "/%s?format=html&tpl_layout=base&tpl_content=%s", []string{"DELETE"}},
PathPattern{"/%s", "", []string{"GET"}, PermissionReadAll},
PathPattern{"/%s/{id}", "", []string{"GET"}, PermissionRead},
PathPattern{"/%s/create/", "/%s/%d?format=html&tpl_layout=base&tpl_content=%s_show", []string{"GET", "POST"}, PermissionCreate},
PathPattern{"/%s/{id}/update", "/%s/%d?format=html&tpl_layout=base&tpl_content=%s_show", []string{"GET", "POST"}, PermissionUpdate},
PathPattern{"/%s/{id}/delete", "/%s?format=html&tpl_layout=base&tpl_content=%s", []string{"DELETE"}, PermissionDelete},
}
apiPatterns []PathPattern
@ -70,7 +79,7 @@ func generateHandler(r *mux.Router, model interface{}) {
// Generate API patterns prefixing "api" path
for _, p := range patterns {
apiPatterns = append(apiPatterns, PathPattern{path.Join("/", "api", p.PathPattern), "", p.Methods})
apiPatterns = append(apiPatterns, PathPattern{path.Join("/", "api", p.PathPattern), "", p.Methods, p.Permission})
}
// Install standard paths
@ -102,6 +111,25 @@ func generateHandler(r *mux.Router, model interface{}) {
)))).Methods(pattern.Methods...)
}
// Set permissions
for role, modelPermissions := range RolePermissions {
for m, perm := range modelPermissions {
if m == modelName(model) {
for _, p := range perm {
for _, pattern := range patterns {
if pattern.Permission == p {
if permissions[role] == nil {
permissions[role] = make(map[string]bool)
}
permissions[role][pattern.Path(pluralizedModelName(model))] = true
}
}
}
}
}
}
}
func Handlers(models []interface{}) *mux.Router {
@ -192,6 +220,14 @@ func setFlashMessage(w http.ResponseWriter, r *http.Request, key string) error {
return nil
}
func hasPermission(role, path string) bool {
if permissions[role] == nil {
return false
}
return permissions[role][path]
}
func get(w http.ResponseWriter, r *http.Request, model string, pattern PathPattern) {
format := r.URL.Query().Get("format")
getFn, err := orm.GetFunc(pattern.Path(model))
@ -202,9 +238,9 @@ func get(w http.ResponseWriter, r *http.Request, model string, pattern PathPatte
claims := r.Context().Value("user").(*jwt.Token).Claims.(jwt.MapClaims)
role := claims["role"].(string)
if role == "participant" {
if !hasPermission(role, pattern.Path(model)) {
setFlashMessage(w, r, "notAuthorized")
renderer.Render[format](w, r, fmt.Errorf("%s", "Errore"))
renderer.Render[format](w, r, fmt.Errorf("%s", "Errore di autorizzazione"))
} else {
data, err := getFn(mux.Vars(r), w, r)

36
handlers/role.go Normal file
View file

@ -0,0 +1,36 @@
package handlers
const (
PermissionCreate = iota
PermissionRead
PermissionReadAll
PermissionUpdate
PermissionDelete
)
var (
RolePermissions map[string]map[string][]int = map[string]map[string][]int{
"administrator": map[string][]int{
"Contest": []int{PermissionCreate, PermissionRead, PermissionReadAll, PermissionUpdate, PermissionDelete},
"Participant": []int{PermissionCreate, PermissionRead, PermissionReadAll, PermissionUpdate, PermissionDelete},
"School": []int{PermissionCreate, PermissionRead, PermissionReadAll, PermissionUpdate, PermissionDelete},
"Question": []int{PermissionCreate, PermissionRead, PermissionReadAll, PermissionUpdate, PermissionDelete},
"Answer": []int{PermissionCreate, PermissionRead, PermissionReadAll, PermissionUpdate, PermissionDelete},
"Response": []int{PermissionCreate, PermissionRead, PermissionReadAll, PermissionUpdate, PermissionDelete},
},
"school": map[string][]int{
"Participant": []int{PermissionCreate, PermissionRead, PermissionReadAll, PermissionUpdate, PermissionDelete},
"School": []int{PermissionRead, PermissionUpdate},
},
"participant": map[string][]int{
"Response": []int{PermissionUpdate},
},
"subscriber": map[string][]int{
"School": []int{PermissionCreate, PermissionRead},
},
}
)

View file

@ -36,8 +36,13 @@
{{$options := ` { name: "Email",id: "school_email",label: "Indirizzo email",placeholder: "Inserire l'indirizzo di posta istituzionale",type: "email",required: "true"} `}}
{{template "input" dict "options" ($options|yaml) "value" (.Data|field "Email") "update" $update}}
{{if .Data.Role|isSubscriber}}
{{$options := ` { saveTitle: "Invia iscrizione", model: "School" } `}}
{{template "submit_cancel_buttons" dict "options" ($options|yaml) "id" (.Data|field "ID") "update" $update}}
{{else}}
{{$options := ` { cancelTitle: "Annulla", saveTitle: "Salva", model: "School" } `}}
{{template "submit_cancel_buttons" dict "options" ($options|yaml) "id" (.Data|field "ID") "update" $update}}
{{template "submit_cancel_buttons" dict "options" ($options|yaml) "id" (.Data|field "ID") "update" $update}}
{{end}}
</form>