influxdb/user_resource_mapping.go

102 lines
3.1 KiB
Go

package platform
import (
"context"
"errors"
"fmt"
)
type UserType string
type ResourceType string
// available user resource types.
const (
Owner UserType = "owner"
Member UserType = "member"
DashboardResourceType ResourceType = "dashboard"
BucketResourceType ResourceType = "bucket"
TaskResourceType ResourceType = "task"
OrgResourceType ResourceType = "org"
ViewResourceType ResourceType = "view"
TelegrafResourceType ResourceType = "telegraf"
TokenResourceType ResourceType = "token"
UserResourceType ResourceType = "user"
)
// UserResourceMappingService maps the relationships between users and resources
type UserResourceMappingService interface {
// FindUserResourceMappings returns a list of UserResourceMappings that match filter and the total count of matching mappings.
FindUserResourceMappings(ctx context.Context, filter UserResourceMappingFilter, opt ...FindOptions) ([]*UserResourceMapping, int, error)
// CreateUserResourceMapping creates a user resource mapping
CreateUserResourceMapping(ctx context.Context, m *UserResourceMapping) error
// DeleteUserResourceMapping deletes a user resource mapping
DeleteUserResourceMapping(ctx context.Context, resourceID ID, userID ID) error
}
// UserResourceMapping represents a mapping of a resource to its user
type UserResourceMapping struct {
ResourceID ID `json:"resource_id"`
ResourceType ResourceType `json:"resource_type"`
UserID ID `json:"user_id"`
UserType UserType `json:"user_type"`
}
// Validate reports any validation errors for the mapping.
func (m UserResourceMapping) Validate() error {
if !m.ResourceID.Valid() {
return errors.New("resourceID is required")
}
if !m.UserID.Valid() {
return errors.New("userID is required")
}
if m.UserType != Owner && m.UserType != Member {
return errors.New("a valid user type is required")
}
switch m.ResourceType {
case DashboardResourceType, BucketResourceType, TaskResourceType, OrgResourceType, ViewResourceType, TelegrafResourceType:
default:
return errors.New("a valid resource type is required")
}
return nil
}
// UserResourceMapping represents a set of filters that restrict the returned results.
type UserResourceMappingFilter struct {
ResourceID ID
ResourceType ResourceType
UserID ID
UserType UserType
}
var ownerActions = []action{WriteAction, CreateAction, DeleteAction}
var memberActions = []action{ReadAction}
// ToPermission converts a user resource mapping into a set of permissions.
func (m *UserResourceMapping) ToPermissions() []Permission {
// TODO(desa): we'll have to do something more fine-grained eventually
// but this should be good enough for now.
ps := []Permission{}
r := resource(fmt.Sprintf("%s/%s", m.ResourceType, m.ResourceID))
if m.UserType == Owner {
for _, a := range ownerActions {
p := Permission{
Resource: r,
Action: a,
}
ps = append(ps, p)
}
}
for _, a := range memberActions {
p := Permission{
Resource: r,
Action: a,
}
ps = append(ps, p)
}
return ps
}