mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
create a Permissions type
makes it nice to say p.Satisfies(otherPerm)
This commit is contained in:
parent
d95d4dac9d
commit
17679eb924
3 changed files with 63 additions and 81 deletions
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue