create a Permissions type

makes it nice to say p.Satisfies(otherPerm)
This commit is contained in:
reesporte 2021-12-29 13:38:11 -06:00
parent d95d4dac9d
commit 17679eb924
3 changed files with 63 additions and 81 deletions

View file

@ -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"
}

View file

@ -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"},
},
}

View file

@ -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