From 17679eb924dcf66e9b07157401ec6198f03d6ca4 Mon Sep 17 00:00:00 2001 From: reesporte Date: Wed, 29 Dec 2021 13:38:11 -0600 Subject: [PATCH] create a Permissions type makes it nice to say p.Satisfies(otherPerm) --- authz/authorization.go | 92 +++++++++++++++---------------------- authz/authorization_test.go | 50 ++++++++++---------- http/handler.go | 2 +- 3 files changed, 63 insertions(+), 81 deletions(-) diff --git a/authz/authorization.go b/authz/authorization.go index 5dc9ce765..727d4db3f 100644 --- a/authz/authorization.go +++ b/authz/authorization.go @@ -25,19 +25,34 @@ import ( ) type GroupPermissions struct { - Permissions map[string]map[string]string `yaml:"user-groups"` - Admin string `yaml:"admin"` + Permissions map[string]map[string]Permission `yaml:"user-groups"` + Admin string `yaml:"admin"` } -type Permission int64 +type Permission string const ( - None Permission = iota - Read - Write - Admin + None Permission = "" + Read Permission = "read" + Write Permission = "write" + Admin Permission = "admin" ) +// Satisfies returns whether `p` satisfies the permissions required by `b` +func (p Permission) Satisfies(b Permission) bool { + switch p { + case "": + return b == "" + case "read": + return b == "" || b == "read" + case "write": + return b == "" || b == "read" || b == "write" + case "admin": + return b == "" || b == "read" || b == "write" || b == "admin" + } + return false +} + func (p *GroupPermissions) ReadPermissionsFile(permsFile io.Reader) (err error) { permsData, err := ioutil.ReadAll(permsFile) @@ -53,19 +68,18 @@ func (p *GroupPermissions) ReadPermissionsFile(permsFile io.Reader) (err error) return } -func (p *GroupPermissions) GetPermissions(groups []authn.Group, index string) (permission string, errors error) { - +func (p *GroupPermissions) GetPermissions(groups []authn.Group, index string) (permission Permission, errors error) { if admin := p.IsAdmin(groups); admin { - return "admin", nil + return Admin, nil } - allPermissions := map[string]bool{ - "write": false, - "read": false, + allPermissions := map[Permission]bool{ + Write: false, + Read: false, } if len(groups) == 0 { - return "", fmt.Errorf("user is not part of any groups in identity provider") + return None, fmt.Errorf("user is not part of any groups in identity provider") } var groupsDenied []string @@ -74,7 +88,7 @@ func (p *GroupPermissions) GetPermissions(groups []authn.Group, index string) (p if perm, ok := p.Permissions[group.GroupID][index]; ok { allPermissions[perm] = true } else { - return "", fmt.Errorf("user %s does not have permission to index %s", group.UserID, index) + return None, fmt.Errorf("user %s does not have permission to index %s", group.UserID, index) } } else { groupsDenied = append(groupsDenied, group.GroupID) @@ -82,15 +96,15 @@ func (p *GroupPermissions) GetPermissions(groups []authn.Group, index string) (p } if len(groupsDenied) == len(groups) { - return "", fmt.Errorf("group(s) %s does not have permission to FeatureBase", groupsDenied) + return None, fmt.Errorf("group(s) %s does not have permission to FeatureBase", groupsDenied) } - if allPermissions["write"] { - return "write", nil - } else if allPermissions["read"] { - return "read", nil + if allPermissions[Write] { + return Write, nil + } else if allPermissions[Read] { + return Read, nil } else { - return "", fmt.Errorf("no permissions found") + return None, fmt.Errorf("no permissions found") } } @@ -103,7 +117,7 @@ func (p *GroupPermissions) IsAdmin(groups []authn.Group) bool { return false } -func (p *GroupPermissions) GetAuthorizedIndexList(groups []authn.Group, desiredPermission string) (indexList []string) { +func (p *GroupPermissions) GetAuthorizedIndexList(groups []authn.Group, desiredPermission Permission) (indexList []string) { // if user is admin, find all indexes in permissions file and return them if admin := p.IsAdmin(groups); admin { for groupId := range p.Permissions { @@ -117,9 +131,7 @@ func (p *GroupPermissions) GetAuthorizedIndexList(groups []authn.Group, desiredP for _, group := range groups { if _, ok := p.Permissions[group.GroupID]; ok { for index, permission := range p.Permissions[group.GroupID] { - if permission == desiredPermission { - indexList = append(indexList, index) - } else if permission == "write" && desiredPermission == "read" { + if permission >= desiredPermission { indexList = append(indexList, index) } } @@ -127,33 +139,3 @@ func (p *GroupPermissions) GetAuthorizedIndexList(groups []authn.Group, desiredP } return indexList } - -func IsComparable(from, to string) bool { - switch from { - case "admin": - return true - case "write": - if to == "write" || to == "read" { - return true - } - case "read": - if to == "read" { - return true - } - } - return false -} - -func (p Permission) String() string { - switch p { - case Read: - return "read" - case Write: - return "write" - case Admin: - return "admin" - case None: - return "none" - } - return "unknown" -} diff --git a/authz/authorization_test.go b/authz/authorization_test.go index bfda894a9..b8b9f5491 100644 --- a/authz/authorization_test.go +++ b/authz/authorization_test.go @@ -40,16 +40,16 @@ admin: "ac97c9e2-346b-42a2-b6da-18bcb61a32fe"` admin: "ac97c9e2-346b-42a2-b6da-18bcb61a32fe"` singlePermission := authz.GroupPermissions{ - Permissions: map[string]map[string]string{ - "dca35310-ecda-4f23-86cd-876aee55906b": {"test": "read"}, + Permissions: map[string]map[string]authz.Permission{ + "dca35310-ecda-4f23-86cd-876aee55906b": {"test": authz.Read}, }, Admin: "ac97c9e2-346b-42a2-b6da-18bcb61a32fe", } multiPermission := authz.GroupPermissions{ - Permissions: map[string]map[string]string{ - "dca35310-ecda-4f23-86cd-876aee55906b": {"test": "read", "test2": "write"}, - "dca35310-ecda-4f23-86cd-876aee559900": {"test": "write"}}, + Permissions: map[string]map[string]authz.Permission{ + "dca35310-ecda-4f23-86cd-876aee55906b": {"test": authz.Read, "test2": authz.Write}, + "dca35310-ecda-4f23-86cd-876aee559900": {"test": authz.Write}}, Admin: "ac97c9e2-346b-42a2-b6da-18bcb61a32fe", } @@ -123,56 +123,56 @@ admin: "ac97c9e2-346b-42a2-b6da-18bcb61a32fe"` yamlData string groups []authn.Group index string - userAccess string + userAccess authz.Permission err string }{ { permissions1, groupsList1, "test", - "", + authz.None, "user is not part of any groups in identity provider", }, { permissions1, groupsList3, "test1", - "", + authz.None, "does not have permission to index", }, { permissions2, groupsList2, "test", - "", + authz.None, "does not have permission to FeatureBase", }, { permissions1, groupsList3, "test", - "read", + authz.Read, "", }, { permissions2, groupsList3, "test", - "write", + authz.Write, "", }, { permissions3, groupsList4, "test", - "admin", + authz.Admin, "", }, { permissions4, groupsList3, "test", - "", + authz.None, "no permissions found", }, } @@ -214,8 +214,8 @@ func TestAuth_IsAdmin(t *testing.T) { } groupPermissions := authz.GroupPermissions{ - Permissions: map[string]map[string]string{ - "dca35310-ecda-4f23-86cd-876aee55906b": {"test": "write"}, + Permissions: map[string]map[string]authz.Permission{ + "dca35310-ecda-4f23-86cd-876aee55906b": {"test": authz.Write}, }, Admin: "ac97c9e2-346b-42a2-b6da-18bcb61a32fe", } @@ -259,13 +259,13 @@ func TestAuth_GetAuthorizedIndexList(t *testing.T) { } p := authz.GroupPermissions{ - Permissions: map[string]map[string]string{ + Permissions: map[string]map[string]authz.Permission{ "dca35310-ecda-4f23-86cd-876aee55906b": { - "test1": "read", - "test2": "write", + "test1": authz.Read, + "test2": authz.Write, }, "dca35310-ecda-4f23-86cd-876aee559900": { - "test3": "read", + "test3": authz.Read, }, }, Admin: "ac97c9e2-346b-42a2-b6da-18bcb61a32fe", @@ -273,32 +273,32 @@ func TestAuth_GetAuthorizedIndexList(t *testing.T) { tests := []struct { groups []authn.Group - permission string + permission authz.Permission output []string }{ { group1, - "read", + authz.Read, []string{"test1", "test2"}, }, { group1, - "write", + authz.Write, []string{"test2"}, }, { group3, - "write", + authz.Write, nil, }, { group2, - "read", + authz.Read, []string{"test1", "test2", "test3"}, }, { group2, - "write", + authz.Write, []string{"test1", "test2", "test3"}, }, } diff --git a/http/handler.go b/http/handler.go index 86312dc18..661f04b4e 100644 --- a/http/handler.go +++ b/http/handler.go @@ -568,7 +568,7 @@ func (h *Handler) mwAuth(handler http.HandlerFunc, perm authz.Permission) http.H if perm != authz.Admin { h.querylogger.Infof("User ID: %s, User Name: %s, Endpoint: %s, Index: %s, Query: %s, Err: %v", uinfo.UserID, uinfo.UserName, r.URL.Path, indexName, queryString, err) } - if err != nil || !authz.IsComparable(p, perm.String()) { + if err != nil || !p.Satisfies(perm.String()) { w.Header().Add("Content-Type", "text/plain") w.WriteHeader(http.StatusForbidden) return