1 Star 0 Fork 0

PeterTu_2019/influxdb

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
authz.go 14.26 KB
一键复制 编辑 原始数据 按行查看 历史
package influxdb
import (
"errors"
"fmt"
"os"
"path/filepath"
"github.com/influxdata/influxdb/v2/kit/platform"
errors2 "github.com/influxdata/influxdb/v2/kit/platform/errors"
)
var (
// ErrAuthorizerNotSupported notes that the provided authorizer is not supported for the action you are trying to perform.
ErrAuthorizerNotSupported = errors.New("your authorizer is not supported, please use *platform.Authorization as authorizer")
// ErrInvalidResourceType notes that the provided resource is invalid
ErrInvalidResourceType = errors.New("unknown resource type for permission")
// ErrInvalidAction notes that the provided action is invalid
ErrInvalidAction = errors.New("unknown action for permission")
)
// Authorizer will authorize a permission.
type Authorizer interface {
// PermissionSet returns the PermissionSet associated with the authorizer
PermissionSet() (PermissionSet, error)
// ID returns an identifier used for auditing.
Identifier() platform.ID
// GetUserID returns the user id.
GetUserID() platform.ID
// Kind metadata for auditing.
Kind() string
}
// PermissionAllowed determines if a permission is allowed.
func PermissionAllowed(perm Permission, ps []Permission) bool {
for _, p := range ps {
if p.Matches(perm) {
return true
}
}
return false
}
// Action is an enum defining all possible resource operations
type Action string
const (
// ReadAction is the action for reading.
ReadAction Action = "read" // 1
// WriteAction is the action for writing.
WriteAction Action = "write" // 2
)
var actions = []Action{
ReadAction, // 1
WriteAction, // 2
}
// Valid checks if the action is a member of the Action enum
func (a Action) Valid() (err error) {
switch a {
case ReadAction: // 1
case WriteAction: // 2
default:
err = ErrInvalidAction
}
return err
}
// ResourceType is an enum defining all resource types that have a permission model in platform
type ResourceType string
// Resource is an authorizable resource.
type Resource struct {
Type ResourceType `json:"type"`
ID *platform.ID `json:"id,omitempty"`
OrgID *platform.ID `json:"orgID,omitempty"`
}
// String stringifies a resource
func (r Resource) String() string {
if r.OrgID != nil && r.ID != nil {
return filepath.Join(string(OrgsResourceType), r.OrgID.String(), string(r.Type), r.ID.String())
}
if r.OrgID != nil {
return filepath.Join(string(OrgsResourceType), r.OrgID.String(), string(r.Type))
}
if r.ID != nil {
return filepath.Join(string(r.Type), r.ID.String())
}
return string(r.Type)
}
const (
// AuthorizationsResourceType gives permissions to one or more authorizations.
AuthorizationsResourceType = ResourceType("authorizations") // 0
// BucketsResourceType gives permissions to one or more buckets.
BucketsResourceType = ResourceType("buckets") // 1
// DashboardsResourceType gives permissions to one or more dashboards.
DashboardsResourceType = ResourceType("dashboards") // 2
// OrgsResourceType gives permissions to one or more orgs.
OrgsResourceType = ResourceType("orgs") // 3
// SourcesResourceType gives permissions to one or more sources.
SourcesResourceType = ResourceType("sources") // 4
// TasksResourceType gives permissions to one or more tasks.
TasksResourceType = ResourceType("tasks") // 5
// TelegrafsResourceType type gives permissions to a one or more telegrafs.
TelegrafsResourceType = ResourceType("telegrafs") // 6
// UsersResourceType gives permissions to one or more users.
UsersResourceType = ResourceType("users") // 7
// VariablesResourceType gives permission to one or more variables.
VariablesResourceType = ResourceType("variables") // 8
// ScraperResourceType gives permission to one or more scrapers.
ScraperResourceType = ResourceType("scrapers") // 9
// SecretsResourceType gives permission to one or more secrets.
SecretsResourceType = ResourceType("secrets") // 10
// LabelsResourceType gives permission to one or more labels.
LabelsResourceType = ResourceType("labels") // 11
// ViewsResourceType gives permission to one or more views.
ViewsResourceType = ResourceType("views") // 12
// DocumentsResourceType gives permission to one or more documents.
DocumentsResourceType = ResourceType("documents") // 13
// NotificationRuleResourceType gives permission to one or more notificationRules.
NotificationRuleResourceType = ResourceType("notificationRules") // 14
// NotificationEndpointResourceType gives permission to one or more notificationEndpoints.
NotificationEndpointResourceType = ResourceType("notificationEndpoints") // 15
// ChecksResourceType gives permission to one or more Checks.
ChecksResourceType = ResourceType("checks") // 16
// DBRPType gives permission to one or more DBRPs.
DBRPResourceType = ResourceType("dbrp") // 17
// NotebooksResourceType gives permission to one or more notebooks.
NotebooksResourceType = ResourceType("notebooks") // 18
// AnnotationsResourceType gives permission to one or more annotations.
AnnotationsResourceType = ResourceType("annotations") // 19
)
// AllResourceTypes is the list of all known resource types.
var AllResourceTypes = []ResourceType{
AuthorizationsResourceType, // 0
BucketsResourceType, // 1
DashboardsResourceType, // 2
OrgsResourceType, // 3
SourcesResourceType, // 4
TasksResourceType, // 5
TelegrafsResourceType, // 6
UsersResourceType, // 7
VariablesResourceType, // 8
ScraperResourceType, // 9
SecretsResourceType, // 10
LabelsResourceType, // 11
ViewsResourceType, // 12
DocumentsResourceType, // 13
NotificationRuleResourceType, // 14
NotificationEndpointResourceType, // 15
ChecksResourceType, // 16
DBRPResourceType, // 17
NotebooksResourceType, // 18
AnnotationsResourceType, // 19
// NOTE: when modifying this list, please update the swagger for components.schemas.Permission resource enum.
}
// OrgResourceTypes is the list of all known resource types that belong to an organization.
var OrgResourceTypes = []ResourceType{
BucketsResourceType, // 1
DashboardsResourceType, // 2
SourcesResourceType, // 4
TasksResourceType, // 5
TelegrafsResourceType, // 6
UsersResourceType, // 7
VariablesResourceType, // 8
SecretsResourceType, // 10
DocumentsResourceType, // 13
NotificationRuleResourceType, // 14
NotificationEndpointResourceType, // 15
ChecksResourceType, // 16
DBRPResourceType, // 17
NotebooksResourceType, // 18
AnnotationsResourceType, // 19
}
// Valid checks if the resource type is a member of the ResourceType enum.
func (r Resource) Valid() (err error) {
return r.Type.Valid()
}
// Valid checks if the resource type is a member of the ResourceType enum.
func (t ResourceType) Valid() (err error) {
switch t {
case AuthorizationsResourceType: // 0
case BucketsResourceType: // 1
case DashboardsResourceType: // 2
case OrgsResourceType: // 3
case TasksResourceType: // 4
case TelegrafsResourceType: // 5
case SourcesResourceType: // 6
case UsersResourceType: // 7
case VariablesResourceType: // 8
case ScraperResourceType: // 9
case SecretsResourceType: // 10
case LabelsResourceType: // 11
case ViewsResourceType: // 12
case DocumentsResourceType: // 13
case NotificationRuleResourceType: // 14
case NotificationEndpointResourceType: // 15
case ChecksResourceType: // 16
case DBRPResourceType: // 17
case NotebooksResourceType: // 18
case AnnotationsResourceType: // 19
default:
err = ErrInvalidResourceType
}
return err
}
type PermissionSet []Permission
func (ps PermissionSet) Allowed(p Permission) bool {
return PermissionAllowed(p, ps)
}
// Permission defines an action and a resource.
type Permission struct {
Action Action `json:"action"`
Resource Resource `json:"resource"`
}
var newMatchBehavior bool
func init() {
_, newMatchBehavior = os.LookupEnv("MATCHER_BEHAVIOR")
}
// Matches returns whether or not one permission matches the other.
func (p Permission) Matches(perm Permission) bool {
if newMatchBehavior {
return p.matchesV2(perm)
}
return p.matchesV1(perm)
}
func (p Permission) matchesV1(perm Permission) bool {
if p.Action != perm.Action {
return false
}
if p.Resource.Type != perm.Resource.Type {
return false
}
if p.Resource.OrgID == nil && p.Resource.ID == nil {
return true
}
if p.Resource.OrgID != nil && perm.Resource.OrgID != nil && p.Resource.ID != nil && perm.Resource.ID != nil {
if *p.Resource.OrgID != *perm.Resource.OrgID && *p.Resource.ID == *perm.Resource.ID {
fmt.Printf("v1: old match used: p.Resource.OrgID=%s perm.Resource.OrgID=%s p.Resource.ID=%s",
*p.Resource.OrgID, *perm.Resource.OrgID, *p.Resource.ID)
}
}
if p.Resource.OrgID != nil && p.Resource.ID == nil {
pOrgID := *p.Resource.OrgID
if perm.Resource.OrgID != nil {
permOrgID := *perm.Resource.OrgID
if pOrgID == permOrgID {
return true
}
}
}
if p.Resource.ID != nil {
pID := *p.Resource.ID
if perm.Resource.ID != nil {
permID := *perm.Resource.ID
if pID == permID {
return true
}
}
}
return false
}
func (p Permission) matchesV2(perm Permission) bool {
if p.Action != perm.Action {
return false
}
if p.Resource.Type != perm.Resource.Type {
return false
}
if p.Resource.OrgID == nil && p.Resource.ID == nil {
return true
}
if p.Resource.OrgID != nil && perm.Resource.OrgID != nil && p.Resource.ID != nil && perm.Resource.ID != nil {
if *p.Resource.OrgID != *perm.Resource.OrgID && *p.Resource.ID == *perm.Resource.ID {
fmt.Printf("v2: old match used: p.Resource.OrgID=%s perm.Resource.OrgID=%s p.Resource.ID=%s",
*p.Resource.OrgID, *perm.Resource.OrgID, *p.Resource.ID)
}
}
if p.Resource.OrgID != nil {
if perm.Resource.OrgID != nil {
if *p.Resource.OrgID == *perm.Resource.OrgID {
if p.Resource.ID == nil {
return true
}
if perm.Resource.ID != nil {
return *p.Resource.ID == *perm.Resource.ID
}
}
return false
}
}
if p.Resource.ID != nil {
pID := *p.Resource.ID
if perm.Resource.ID != nil {
permID := *perm.Resource.ID
if pID == permID {
return true
}
}
}
return false
}
func (p Permission) String() string {
return fmt.Sprintf("%s:%s", p.Action, p.Resource)
}
// Valid checks if there the resource and action provided is known.
func (p *Permission) Valid() error {
if err := p.Resource.Valid(); err != nil {
return &errors2.Error{
Code: errors2.EInvalid,
Err: err,
Msg: "invalid resource type for permission",
}
}
if err := p.Action.Valid(); err != nil {
return &errors2.Error{
Code: errors2.EInvalid,
Err: err,
Msg: "invalid action type for permission",
}
}
if p.Resource.OrgID != nil && !p.Resource.OrgID.Valid() {
return &errors2.Error{
Code: errors2.EInvalid,
Err: platform.ErrInvalidID,
Msg: "invalid org id for permission",
}
}
if p.Resource.ID != nil && !p.Resource.ID.Valid() {
return &errors2.Error{
Code: errors2.EInvalid,
Err: platform.ErrInvalidID,
Msg: "invalid id for permission",
}
}
return nil
}
// NewPermission returns a permission with provided arguments.
func NewPermission(a Action, rt ResourceType, orgID platform.ID) (*Permission, error) {
p := &Permission{
Action: a,
Resource: Resource{
Type: rt,
OrgID: &orgID,
},
}
return p, p.Valid()
}
// NewResourcePermission returns a permission with provided arguments.
func NewResourcePermission(a Action, rt ResourceType, rid platform.ID) (*Permission, error) {
p := &Permission{
Action: a,
Resource: Resource{
Type: rt,
ID: &rid,
},
}
return p, p.Valid()
}
// NewGlobalPermission constructs a global permission capable of accessing any resource of type rt.
func NewGlobalPermission(a Action, rt ResourceType) (*Permission, error) {
p := &Permission{
Action: a,
Resource: Resource{
Type: rt,
},
}
return p, p.Valid()
}
// NewPermissionAtID creates a permission with the provided arguments.
func NewPermissionAtID(id platform.ID, a Action, rt ResourceType, orgID platform.ID) (*Permission, error) {
p := &Permission{
Action: a,
Resource: Resource{
Type: rt,
OrgID: &orgID,
ID: &id,
},
}
return p, p.Valid()
}
// OperPermissions are the default permissions for those who setup the application.
func OperPermissions() []Permission {
ps := []Permission{}
for _, r := range AllResourceTypes {
for _, a := range actions {
ps = append(ps, Permission{Action: a, Resource: Resource{Type: r}})
}
}
return ps
}
// ReadAllPermissions represents permission to read all data and metadata.
// Like OperPermissions, but allows read-only users.
func ReadAllPermissions() []Permission {
ps := make([]Permission, len(AllResourceTypes))
for i, t := range AllResourceTypes {
ps[i] = Permission{Action: ReadAction, Resource: Resource{Type: t}}
}
return ps
}
// OwnerPermissions are the default permissions for those who own a resource.
func OwnerPermissions(orgID platform.ID) []Permission {
ps := []Permission{}
for _, r := range AllResourceTypes {
for _, a := range actions {
if r == OrgsResourceType {
ps = append(ps, Permission{Action: a, Resource: Resource{Type: r, ID: &orgID}})
continue
}
ps = append(ps, Permission{Action: a, Resource: Resource{Type: r, OrgID: &orgID}})
}
}
return ps
}
// MePermissions is the permission to read/write myself.
func MePermissions(userID platform.ID) []Permission {
ps := []Permission{}
for _, a := range actions {
ps = append(ps, Permission{Action: a, Resource: Resource{Type: UsersResourceType, ID: &userID}})
}
return ps
}
// MemberPermissions are the default permissions for those who can see a resource.
func MemberPermissions(orgID platform.ID) []Permission {
ps := []Permission{}
for _, r := range AllResourceTypes {
if r == OrgsResourceType {
ps = append(ps, Permission{Action: ReadAction, Resource: Resource{Type: r, ID: &orgID}})
continue
}
ps = append(ps, Permission{Action: ReadAction, Resource: Resource{Type: r, OrgID: &orgID}})
}
return ps
}
// MemberPermissions are the default permissions for those who can see a resource.
func MemberBucketPermission(bucketID platform.ID) Permission {
return Permission{Action: ReadAction, Resource: Resource{Type: BucketsResourceType, ID: &bucketID}}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/petertu_2019/influxdb.git
git@gitee.com:petertu_2019/influxdb.git
petertu_2019
influxdb
influxdb
master

搜索帮助