2019-01-08 00:37:16 +00:00
|
|
|
package influxdb
|
2018-09-28 17:02:34 +00:00
|
|
|
|
2018-11-20 23:20:51 +00:00
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
2019-01-15 16:09:58 +00:00
|
|
|
"path/filepath"
|
2018-11-20 23:20:51 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
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")
|
2019-01-15 16:09:58 +00:00
|
|
|
// ErrInvalidResourceType notes that the provided resource is invalid
|
|
|
|
ErrInvalidResourceType = errors.New("unknown resource type for permission")
|
2018-12-28 23:02:19 +00:00
|
|
|
// ErrInvalidAction notes that the provided action is invalid
|
|
|
|
ErrInvalidAction = errors.New("unknown action for permission")
|
2018-11-20 23:20:51 +00:00
|
|
|
)
|
2018-09-28 17:02:34 +00:00
|
|
|
|
|
|
|
// Authorizer will authorize a permission.
|
|
|
|
type Authorizer interface {
|
2018-09-28 18:33:35 +00:00
|
|
|
// Allowed returns true is the associated permission is allowed by the authorizer
|
2018-09-28 17:02:34 +00:00
|
|
|
Allowed(p Permission) bool
|
2018-09-28 18:33:35 +00:00
|
|
|
|
|
|
|
// ID returns an identifier used for auditing.
|
|
|
|
Identifier() ID
|
|
|
|
|
2018-10-24 15:13:30 +00:00
|
|
|
// GetUserID returns the user id.
|
|
|
|
GetUserID() ID
|
|
|
|
|
2018-09-28 18:33:35 +00:00
|
|
|
// Kind metadata for auditing.
|
|
|
|
Kind() string
|
2018-09-28 17:02:34 +00:00
|
|
|
}
|
|
|
|
|
2019-01-10 21:21:59 +00:00
|
|
|
// PermissionAllowed determines if a permission is allowed.
|
2019-01-15 16:09:58 +00:00
|
|
|
func PermissionAllowed(perm Permission, ps []Permission) bool {
|
|
|
|
for _, p := range ps {
|
|
|
|
if p.Matches(perm) {
|
|
|
|
return true
|
2018-09-28 17:02:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2018-12-28 23:02:19 +00:00
|
|
|
// Action is an enum defining all possible resource operations
|
|
|
|
type Action string
|
2018-09-28 17:02:34 +00:00
|
|
|
|
|
|
|
const (
|
|
|
|
// ReadAction is the action for reading.
|
2018-12-28 23:02:19 +00:00
|
|
|
ReadAction Action = "read" // 1
|
2018-09-28 17:02:34 +00:00
|
|
|
// WriteAction is the action for writing.
|
2018-12-28 23:02:19 +00:00
|
|
|
WriteAction Action = "write" // 2
|
2018-09-28 17:02:34 +00:00
|
|
|
)
|
|
|
|
|
2018-12-28 23:02:19 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2019-01-15 16:09:58 +00:00
|
|
|
// 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 *ID `json:"id,omitempty"`
|
|
|
|
OrgID *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)
|
|
|
|
}
|
2018-09-28 17:02:34 +00:00
|
|
|
|
|
|
|
const (
|
2019-01-15 16:09:58 +00:00
|
|
|
// 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
|
2019-02-14 20:32:54 +00:00
|
|
|
// VariablesResourceType gives permission to one or more variables.
|
|
|
|
VariablesResourceType = ResourceType("variables") // 8
|
2019-01-17 18:56:29 +00:00
|
|
|
// ScraperResourceType gives permission to one or more scrapers.
|
|
|
|
ScraperResourceType = ResourceType("scrapers") // 9
|
2019-01-22 00:22:39 +00:00
|
|
|
// SecretsResourceType gives permission to one or more secrets.
|
2019-01-21 16:58:13 +00:00
|
|
|
SecretsResourceType = ResourceType("secrets") // 10
|
2019-01-22 13:39:56 +00:00
|
|
|
// LabelsResourceType gives permission to one or more labels.
|
|
|
|
LabelsResourceType = ResourceType("labels") // 11
|
2019-02-05 21:52:15 +00:00
|
|
|
// ViewsResourceType gives permission to one or more views.
|
2019-07-23 22:35:19 +00:00
|
|
|
ViewsResourceType = ResourceType("views") // 12
|
|
|
|
// DocumentsResourceType gives permission to one or more documents.
|
2019-03-04 17:41:24 +00:00
|
|
|
DocumentsResourceType = ResourceType("documents") // 13
|
2019-07-23 22:35:19 +00:00
|
|
|
// NotificationRuleResourceType gives permission to one or more notificationRules.
|
|
|
|
NotificationRuleResourceType = ResourceType("notificationRules") // 14
|
|
|
|
// NotificationEndpointResourceType gives permission to one or more notificationEndpoints.
|
|
|
|
NotificationEndpointResourceType = ResourceType("notificationEndpoints") // 15
|
2019-07-19 09:42:01 +00:00
|
|
|
// ChecksResourceType gives permission to one or more Checks.
|
|
|
|
ChecksResourceType = ResourceType("checks") // 16
|
2018-09-28 17:02:34 +00:00
|
|
|
)
|
|
|
|
|
2019-01-15 16:09:58 +00:00
|
|
|
// AllResourceTypes is the list of all known resource types.
|
|
|
|
var AllResourceTypes = []ResourceType{
|
2019-07-23 22:35:19 +00:00
|
|
|
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
|
2019-07-19 09:42:01 +00:00
|
|
|
ChecksResourceType, // 16
|
2019-03-18 23:38:30 +00:00
|
|
|
// NOTE: when modifying this list, please update the swagger for components.schemas.Permission resource enum.
|
2018-09-28 17:02:34 +00:00
|
|
|
}
|
|
|
|
|
2019-01-15 16:09:58 +00:00
|
|
|
// OrgResourceTypes is the list of all known resource types that belong to an organization.
|
|
|
|
var OrgResourceTypes = []ResourceType{
|
2019-07-23 22:35:19 +00:00
|
|
|
BucketsResourceType, // 1
|
|
|
|
DashboardsResourceType, // 2
|
|
|
|
SourcesResourceType, // 4
|
|
|
|
TasksResourceType, // 5
|
|
|
|
TelegrafsResourceType, // 6
|
|
|
|
UsersResourceType, // 7
|
|
|
|
VariablesResourceType, // 8
|
|
|
|
SecretsResourceType, // 10
|
|
|
|
DocumentsResourceType, // 13
|
|
|
|
NotificationRuleResourceType, // 14
|
|
|
|
NotificationEndpointResourceType, // 15
|
2019-07-19 09:42:01 +00:00
|
|
|
ChecksResourceType, // 16
|
2019-01-09 15:35:21 +00:00
|
|
|
}
|
|
|
|
|
2019-01-18 23:27:28 +00:00
|
|
|
// Valid checks if the resource type is a member of the ResourceType enum.
|
2018-12-28 23:02:19 +00:00
|
|
|
func (r Resource) Valid() (err error) {
|
2019-01-15 16:09:58 +00:00
|
|
|
return r.Type.Valid()
|
|
|
|
}
|
|
|
|
|
2019-01-18 23:27:28 +00:00
|
|
|
// Valid checks if the resource type is a member of the ResourceType enum.
|
2019-01-15 16:09:58 +00:00
|
|
|
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
|
2019-01-17 13:21:03 +00:00
|
|
|
case UsersResourceType: // 7
|
2019-02-14 20:32:54 +00:00
|
|
|
case VariablesResourceType: // 8
|
2019-01-17 18:56:29 +00:00
|
|
|
case ScraperResourceType: // 9
|
2019-01-21 16:58:13 +00:00
|
|
|
case SecretsResourceType: // 10
|
2019-01-22 13:39:56 +00:00
|
|
|
case LabelsResourceType: // 11
|
2019-02-05 21:52:15 +00:00
|
|
|
case ViewsResourceType: // 12
|
2019-03-04 17:41:24 +00:00
|
|
|
case DocumentsResourceType: // 13
|
2019-07-23 22:35:19 +00:00
|
|
|
case NotificationRuleResourceType: // 14
|
|
|
|
case NotificationEndpointResourceType: // 15
|
2019-07-19 09:42:01 +00:00
|
|
|
case ChecksResourceType: // 16
|
2018-12-28 23:02:19 +00:00
|
|
|
default:
|
2019-01-15 16:09:58 +00:00
|
|
|
err = ErrInvalidResourceType
|
2018-12-28 23:02:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
2018-09-28 17:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Permission defines an action and a resource.
|
|
|
|
type Permission struct {
|
2018-12-28 23:02:19 +00:00
|
|
|
Action Action `json:"action"`
|
|
|
|
Resource Resource `json:"resource"`
|
2018-09-28 17:02:34 +00:00
|
|
|
}
|
|
|
|
|
2019-01-15 16:09:58 +00:00
|
|
|
// Matches returns whether or not one permission matches the other.
|
|
|
|
func (p Permission) Matches(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 && 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
|
|
|
|
}
|
|
|
|
}
|
2018-12-28 23:02:19 +00:00
|
|
|
}
|
|
|
|
|
2019-01-15 16:09:58 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p Permission) String() string {
|
|
|
|
return fmt.Sprintf("%s:%s", p.Action, p.Resource)
|
2018-09-28 17:02:34 +00:00
|
|
|
}
|
|
|
|
|
2019-01-09 15:35:21 +00:00
|
|
|
// Valid checks if there the resource and action provided is known.
|
2018-12-28 23:02:19 +00:00
|
|
|
func (p *Permission) Valid() error {
|
|
|
|
if err := p.Resource.Valid(); err != nil {
|
|
|
|
return &Error{
|
|
|
|
Code: EInvalid,
|
|
|
|
Err: err,
|
|
|
|
Msg: "invalid resource type for permission",
|
|
|
|
}
|
2018-09-28 17:02:34 +00:00
|
|
|
}
|
2018-12-28 23:02:19 +00:00
|
|
|
|
|
|
|
if err := p.Action.Valid(); err != nil {
|
|
|
|
return &Error{
|
|
|
|
Code: EInvalid,
|
|
|
|
Err: err,
|
|
|
|
Msg: "invalid action type for permission",
|
|
|
|
}
|
2018-09-28 17:02:34 +00:00
|
|
|
}
|
|
|
|
|
2019-12-18 07:05:28 +00:00
|
|
|
if p.Resource.OrgID != nil && !p.Resource.OrgID.Valid() {
|
2019-01-10 21:21:59 +00:00
|
|
|
return &Error{
|
|
|
|
Code: EInvalid,
|
|
|
|
Err: ErrInvalidID,
|
|
|
|
Msg: "invalid org id for permission",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-18 07:05:28 +00:00
|
|
|
if p.Resource.ID != nil && !p.Resource.ID.Valid() {
|
2018-12-28 23:02:19 +00:00
|
|
|
return &Error{
|
|
|
|
Code: EInvalid,
|
|
|
|
Err: ErrInvalidID,
|
|
|
|
Msg: "invalid id for permission",
|
|
|
|
}
|
2018-09-28 17:02:34 +00:00
|
|
|
}
|
2018-12-28 23:02:19 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-01-09 15:35:21 +00:00
|
|
|
// NewPermission returns a permission with provided arguments.
|
2019-01-15 16:09:58 +00:00
|
|
|
func NewPermission(a Action, rt ResourceType, orgID ID) (*Permission, error) {
|
2018-12-28 23:02:19 +00:00
|
|
|
p := &Permission{
|
2019-01-15 16:09:58 +00:00
|
|
|
Action: a,
|
|
|
|
Resource: Resource{
|
|
|
|
Type: rt,
|
|
|
|
OrgID: &orgID,
|
|
|
|
},
|
2018-12-28 23:02:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return p, p.Valid()
|
2018-09-28 17:02:34 +00:00
|
|
|
}
|
|
|
|
|
2019-01-15 16:09:58 +00:00
|
|
|
// 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()
|
|
|
|
}
|
|
|
|
|
2019-01-09 15:35:21 +00:00
|
|
|
// NewPermissionAtID creates a permission with the provided arguments.
|
2019-01-15 16:09:58 +00:00
|
|
|
func NewPermissionAtID(id ID, a Action, rt ResourceType, orgID ID) (*Permission, error) {
|
2018-12-28 23:02:19 +00:00
|
|
|
p := &Permission{
|
2019-01-15 16:09:58 +00:00
|
|
|
Action: a,
|
|
|
|
Resource: Resource{
|
|
|
|
Type: rt,
|
|
|
|
OrgID: &orgID,
|
|
|
|
ID: &id,
|
|
|
|
},
|
2018-09-28 17:02:34 +00:00
|
|
|
}
|
2018-12-28 23:02:19 +00:00
|
|
|
|
|
|
|
return p, p.Valid()
|
|
|
|
}
|
|
|
|
|
2019-01-09 15:35:21 +00:00
|
|
|
// OperPermissions are the default permissions for those who setup the application.
|
2019-01-18 23:27:28 +00:00
|
|
|
func OperPermissions() []Permission {
|
2018-12-28 23:02:19 +00:00
|
|
|
ps := []Permission{}
|
2019-01-15 16:09:58 +00:00
|
|
|
for _, r := range AllResourceTypes {
|
|
|
|
for _, a := range actions {
|
|
|
|
ps = append(ps, Permission{Action: a, Resource: Resource{Type: r}})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ps
|
|
|
|
}
|
|
|
|
|
2020-01-21 22:22:45 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2019-01-15 16:09:58 +00:00
|
|
|
// OwnerPermissions are the default permissions for those who own a resource.
|
|
|
|
func OwnerPermissions(orgID ID) []Permission {
|
|
|
|
ps := []Permission{}
|
|
|
|
for _, r := range AllResourceTypes {
|
2018-12-28 23:02:19 +00:00
|
|
|
for _, a := range actions {
|
2019-01-16 20:26:40 +00:00
|
|
|
if r == OrgsResourceType {
|
|
|
|
ps = append(ps, Permission{Action: a, Resource: Resource{Type: r, ID: &orgID}})
|
|
|
|
continue
|
|
|
|
}
|
2019-01-15 16:09:58 +00:00
|
|
|
ps = append(ps, Permission{Action: a, Resource: Resource{Type: r, OrgID: &orgID}})
|
2018-12-28 23:02:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return ps
|
2018-09-28 17:02:34 +00:00
|
|
|
}
|
2019-01-09 15:35:21 +00:00
|
|
|
|
2019-01-17 17:36:00 +00:00
|
|
|
// MePermissions is the permission to read/write myself.
|
|
|
|
func MePermissions(userID ID) []Permission {
|
|
|
|
ps := []Permission{}
|
|
|
|
for _, a := range actions {
|
|
|
|
ps = append(ps, Permission{Action: a, Resource: Resource{Type: UsersResourceType, ID: &userID}})
|
|
|
|
}
|
|
|
|
|
|
|
|
return ps
|
|
|
|
}
|
|
|
|
|
2019-01-15 16:09:58 +00:00
|
|
|
// MemberPermissions are the default permissions for those who can see a resource.
|
2019-01-10 21:21:59 +00:00
|
|
|
func MemberPermissions(orgID ID) []Permission {
|
2019-01-09 15:35:21 +00:00
|
|
|
ps := []Permission{}
|
2019-01-15 16:09:58 +00:00
|
|
|
for _, r := range AllResourceTypes {
|
2019-01-16 20:26:40 +00:00
|
|
|
if r == OrgsResourceType {
|
|
|
|
ps = append(ps, Permission{Action: ReadAction, Resource: Resource{Type: r, ID: &orgID}})
|
|
|
|
continue
|
|
|
|
}
|
2019-01-15 16:09:58 +00:00
|
|
|
ps = append(ps, Permission{Action: ReadAction, Resource: Resource{Type: r, OrgID: &orgID}})
|
2019-01-09 15:35:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ps
|
|
|
|
}
|