mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
The ioutil package is deprecated, with all of its functions having moved into os or io. Do the replacements so we stop having this impending.
141 lines
3.6 KiB
Go
141 lines
3.6 KiB
Go
// Copyright 2017 Pilosa Corp.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package authz
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/molecula/featurebase/v3/authn"
|
|
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
type GroupPermissions struct {
|
|
Permissions map[string]map[string]Permission `yaml:"user-groups"`
|
|
Admin string `yaml:"admin"`
|
|
}
|
|
|
|
type Permission string
|
|
|
|
const (
|
|
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 := io.ReadAll(permsFile)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("reading permissions failed with error: %s", err)
|
|
}
|
|
|
|
err = yaml.UnmarshalStrict(permsData, &p)
|
|
if err != nil {
|
|
return fmt.Errorf("unmarshalling permissions failed with error: %s", err)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (p *GroupPermissions) GetPermissions(user *authn.UserInfo, index string) (permission Permission, errors error) {
|
|
groups := user.Groups
|
|
if admin := p.IsAdmin(groups); admin {
|
|
return Admin, nil
|
|
}
|
|
|
|
allPermissions := map[Permission]bool{
|
|
Write: false,
|
|
Read: false,
|
|
}
|
|
|
|
if len(groups) == 0 {
|
|
return None, fmt.Errorf("user is not part of any groups in identity provider")
|
|
}
|
|
|
|
var groupsDenied []string
|
|
for _, group := range groups {
|
|
if _, ok := p.Permissions[group.GroupID]; ok {
|
|
if perm, ok := p.Permissions[group.GroupID][index]; ok {
|
|
allPermissions[perm] = true
|
|
} else {
|
|
return None, fmt.Errorf("user %s does not have permission to index %s", user.UserID, index)
|
|
}
|
|
} else {
|
|
groupsDenied = append(groupsDenied, group.GroupID)
|
|
}
|
|
}
|
|
|
|
if len(groupsDenied) == len(groups) {
|
|
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
|
|
} else {
|
|
return None, fmt.Errorf("no permissions found")
|
|
}
|
|
}
|
|
|
|
func (p *GroupPermissions) IsAdmin(groups []authn.Group) bool {
|
|
for _, group := range groups {
|
|
if p.Admin == group.GroupID {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
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 p.IsAdmin(groups) {
|
|
for groupId := range p.Permissions {
|
|
for index := range p.Permissions[groupId] {
|
|
indexList = append(indexList, index)
|
|
}
|
|
}
|
|
return indexList
|
|
}
|
|
|
|
for _, group := range groups {
|
|
if _, ok := p.Permissions[group.GroupID]; ok {
|
|
for index, permission := range p.Permissions[group.GroupID] {
|
|
if permission.Satisfies(desiredPermission) {
|
|
indexList = append(indexList, index)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return indexList
|
|
}
|