influxdb/authz.go

245 lines
5.9 KiB
Go

package platform
import (
"errors"
"fmt"
)
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")
// ErrInvalidResource notes that the provided resource is invalid
ErrInvalidResource = errors.New("unknown resource 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 {
// Allowed returns true is the associated permission is allowed by the authorizer
Allowed(p Permission) bool
// ID returns an identifier used for auditing.
Identifier() ID
// GetUserID returns the user id.
GetUserID() ID
// Kind metadata for auditing.
Kind() string
}
// PermissionAllowed
func PermissionAllowed(p Permission, ps []Permission) bool {
pID := ID(0)
if p.ID != nil {
pID = *p.ID
if !pID.Valid() {
return false
}
}
for _, perm := range ps {
permID := ID(0)
if perm.ID != nil {
permID = *perm.ID
if !permID.Valid() {
return false
}
}
if perm.Action == p.Action && perm.Resource == p.Resource && permID == pID {
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
}
// Resource is an enum defining all resources that have a permission model in platform
type Resource string
const (
// AuthorizationsResource gives permissions to one or more authorizations.
AuthorizationsResource = Resource("authorizations") // 0
// BucketsResource gives permissions to one or more buckets.
BucketsResource = Resource("buckets") // 1
// DashboardsResource gives permissions to one or more dashboards.
DashboardsResource = Resource("dashboards") // 2
// OrgsResource gives permissions to one or more orgs.
OrgsResource = Resource("orgs") // 3
// SourcesResource gives permissions to one or more sources.
SourcesResource = Resource("sources") // 4
// TasksResource gives permissions to one or more tasks.
TasksResource = Resource("tasks") // 5
// TelegrafsResource type gives permissions to a one or more telegrafs.
TelegrafsResource = Resource("telegrafs") // 6
// UsersResource gives permissions to one or more users.
UsersResource = Resource("users") // 7
)
// AllResources is the list of all known resource types.
var AllResources = []Resource{
AuthorizationsResource, // 0
BucketsResource, // 1
DashboardsResource, // 2
OrgsResource, // 3
SourcesResource, // 4
TasksResource, // 5
TelegrafsResource, // 6
UsersResource, // 7
}
// OrgResources is the list of all known resource types that belong to an organization.
var OrgResources = []Resource{
BucketsResource, // 1
DashboardsResource, // 2
SourcesResource, // 4
TasksResource, // 5
TelegrafsResource, // 6
UsersResource, // 7
}
// Valid checks if the resource is a member of the Resource enum.
func (r Resource) Valid() (err error) {
switch r {
case AuthorizationsResource: // 0
case BucketsResource: // 1
case DashboardsResource: // 2
case OrgsResource: // 3
case TasksResource: // 4
case TelegrafsResource: // 5
case SourcesResource: // 6
case UsersResource: //7
default:
err = ErrInvalidResource
}
return err
}
// Permission defines an action and a resource.
type Permission struct {
Action Action `json:"action"`
Resource Resource `json:"resource"`
ID *ID `json:"id,omitempty"`
}
func (p Permission) String() string {
str := fmt.Sprintf("%s:%s", p.Action, p.Resource)
if p.ID != nil {
str += fmt.Sprintf(":%s", (*p.ID).String())
}
return str
}
// Valid checks if there the resource and action provided is known.
func (p *Permission) Valid() error {
if err := p.Resource.Valid(); err != nil {
return &Error{
Code: EInvalid,
Err: err,
Msg: "invalid resource type for permission",
}
}
if err := p.Action.Valid(); err != nil {
return &Error{
Code: EInvalid,
Err: err,
Msg: "invalid action type for permission",
}
}
if p.ID != nil && !(*p.ID).Valid() {
return &Error{
Code: EInvalid,
Err: ErrInvalidID,
Msg: "invalid id for permission",
}
}
return nil
}
// NewPermission returns a permission with provided arguments.
func NewPermission(a Action, r Resource) (*Permission, error) {
p := &Permission{
Action: a,
Resource: r,
}
return p, p.Valid()
}
// NewPermissionAtID creates a permission with the provided arguments.
func NewPermissionAtID(id ID, a Action, r Resource) (*Permission, error) {
p := &Permission{
Action: a,
Resource: r,
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 AllResources {
for _, a := range actions {
ps = append(ps, Permission{Action: a, Resource: r})
}
}
return ps
}
// OrgAdminPermissions are the default permissions for org admins.
func OrgAdminPermissions(orgID ID) []Permission {
ps := []Permission{}
for _, r := range OrgResources {
for _, a := range actions {
ps = append(ps, Permission{ID: &orgID, Action: a, Resource: r})
}
}
return ps
}
// OrgMemberPermissions are the default permissions for org members.
func OrgMemberPermissions(orgID ID) []Permission {
ps := []Permission{}
for _, r := range OrgResources {
ps = append(ps, Permission{ID: &orgID, Action: ReadAction, Resource: r})
}
return ps
}