github.com/influxdata/influxdb/v2@v2.7.6/user_resource_mapping.go (about)

     1  package influxdb
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"errors"
     7  
     8  	"github.com/influxdata/influxdb/v2/kit/platform"
     9  )
    10  
    11  var (
    12  	// ErrInvalidUserType notes that the provided UserType is invalid
    13  	ErrInvalidUserType = errors.New("unknown user type")
    14  	// ErrInvalidMappingType notes that the provided MappingType is invalid
    15  	ErrInvalidMappingType = errors.New("unknown mapping type")
    16  	// ErrUserIDRequired notes that the ID was not provided
    17  	ErrUserIDRequired = errors.New("user id is required")
    18  	// ErrResourceIDRequired notes that the provided ID was not provided
    19  	ErrResourceIDRequired = errors.New("resource id is required")
    20  )
    21  
    22  // UserType can either be owner or member.
    23  type UserType string
    24  
    25  const (
    26  	// Owner can read and write to a resource
    27  	Owner UserType = "owner" // 1
    28  	// Member can read from a resource.
    29  	Member UserType = "member" // 2
    30  )
    31  
    32  // Valid checks if the UserType is a member of the UserType enum
    33  func (ut UserType) Valid() (err error) {
    34  	switch ut {
    35  	case Owner: // 1
    36  	case Member: // 2
    37  	default:
    38  		err = ErrInvalidUserType
    39  	}
    40  
    41  	return err
    42  }
    43  
    44  type MappingType uint8
    45  
    46  const (
    47  	UserMappingType = 0
    48  	OrgMappingType  = 1
    49  )
    50  
    51  func (mt MappingType) Valid() error {
    52  	switch mt {
    53  	case UserMappingType, OrgMappingType:
    54  		return nil
    55  	}
    56  
    57  	return ErrInvalidMappingType
    58  }
    59  
    60  func (mt MappingType) String() string {
    61  	switch mt {
    62  	case UserMappingType:
    63  		return "user"
    64  	case OrgMappingType:
    65  		return "org"
    66  	}
    67  
    68  	return "unknown"
    69  }
    70  
    71  func (mt MappingType) MarshalJSON() ([]byte, error) {
    72  	return json.Marshal(mt.String())
    73  }
    74  
    75  func (mt *MappingType) UnmarshalJSON(b []byte) error {
    76  	var s string
    77  	if err := json.Unmarshal(b, &s); err != nil {
    78  		return err
    79  	}
    80  
    81  	switch s {
    82  	case "user":
    83  		*mt = UserMappingType
    84  		return nil
    85  	case "org":
    86  		*mt = OrgMappingType
    87  		return nil
    88  	}
    89  
    90  	return ErrInvalidMappingType
    91  }
    92  
    93  // UserResourceMappingService maps the relationships between users and resources.
    94  type UserResourceMappingService interface {
    95  	// FindUserResourceMappings returns a list of UserResourceMappings that match filter and the total count of matching mappings.
    96  	FindUserResourceMappings(ctx context.Context, filter UserResourceMappingFilter, opt ...FindOptions) ([]*UserResourceMapping, int, error)
    97  
    98  	// CreateUserResourceMapping creates a user resource mapping.
    99  	CreateUserResourceMapping(ctx context.Context, m *UserResourceMapping) error
   100  
   101  	// DeleteUserResourceMapping deletes a user resource mapping.
   102  	DeleteUserResourceMapping(ctx context.Context, resourceID, userID platform.ID) error
   103  }
   104  
   105  // UserResourceMapping represents a mapping of a resource to its user.
   106  type UserResourceMapping struct {
   107  	UserID       platform.ID  `json:"userID"`
   108  	UserType     UserType     `json:"userType"`
   109  	MappingType  MappingType  `json:"mappingType"`
   110  	ResourceType ResourceType `json:"resourceType"`
   111  	ResourceID   platform.ID  `json:"resourceID"`
   112  }
   113  
   114  // Validate reports any validation errors for the mapping.
   115  func (m UserResourceMapping) Validate() error {
   116  	if !m.ResourceID.Valid() {
   117  		return ErrResourceIDRequired
   118  	}
   119  
   120  	if !m.UserID.Valid() {
   121  		return ErrUserIDRequired
   122  	}
   123  
   124  	if err := m.UserType.Valid(); err != nil {
   125  		return err
   126  	}
   127  
   128  	if err := m.MappingType.Valid(); err != nil {
   129  		return err
   130  	}
   131  
   132  	if err := m.ResourceType.Valid(); err != nil {
   133  		return err
   134  	}
   135  
   136  	return nil
   137  }
   138  
   139  // UserResourceMappingFilter represents a set of filters that restrict the returned results.
   140  type UserResourceMappingFilter struct {
   141  	ResourceID   platform.ID
   142  	ResourceType ResourceType
   143  	UserID       platform.ID
   144  	UserType     UserType
   145  }
   146  
   147  func (m *UserResourceMapping) ownerPerms() ([]Permission, error) {
   148  	if m.ResourceType == OrgsResourceType {
   149  		return OwnerPermissions(m.ResourceID), nil
   150  	}
   151  
   152  	if m.ResourceType == InstanceResourceType {
   153  		return []Permission{
   154  			{Action: ReadAction, Resource: Resource{Type: InstanceResourceType}},
   155  			{Action: WriteAction, Resource: Resource{Type: InstanceResourceType}},
   156  		}, nil
   157  	}
   158  
   159  	ps := []Permission{
   160  		// TODO: Uncomment these once the URM system is no longer being used for find lookups for:
   161  		// 	Telegraf
   162  		// 	DashBoard
   163  		// 	notification rule
   164  		// 	notification endpoint
   165  		// Permission{
   166  		// 	Action: ReadAction,
   167  		// 	Resource: Resource{
   168  		// 		Type: m.ResourceType,
   169  		// 		ID:   &m.ResourceID,
   170  		// 	},
   171  		// },
   172  		// Permission{
   173  		// 	Action: WriteAction,
   174  		// 	Resource: Resource{
   175  		// 		Type: m.ResourceType,
   176  		// 		ID:   &m.ResourceID,
   177  		// 	},
   178  		// },
   179  	}
   180  	return ps, nil
   181  }
   182  
   183  func (m *UserResourceMapping) memberPerms() ([]Permission, error) {
   184  	if m.ResourceType == OrgsResourceType {
   185  		return MemberPermissions(m.ResourceID), nil
   186  	}
   187  
   188  	if m.ResourceType == BucketsResourceType {
   189  		return []Permission{MemberBucketPermission(m.ResourceID)}, nil
   190  	}
   191  
   192  	ps := []Permission{
   193  		// TODO: Uncomment these once the URM system is no longer being used for find lookups for:
   194  		// 	Telegraf
   195  		// 	DashBoard
   196  		// 	notification rule
   197  		// 	notification endpoint
   198  		// Permission{
   199  		// 	Action: ReadAction,
   200  		// 	Resource: Resource{
   201  		// 		Type: m.ResourceType,
   202  		// 		ID:   &m.ResourceID,
   203  		// 	},
   204  		// },
   205  	}
   206  	return ps, nil
   207  }
   208  
   209  // ToPermissions converts a user resource mapping into a set of permissions.
   210  func (m *UserResourceMapping) ToPermissions() ([]Permission, error) {
   211  	switch m.UserType {
   212  	case Owner:
   213  		return m.ownerPerms()
   214  	case Member:
   215  		return m.memberPerms()
   216  	default:
   217  		return nil, ErrInvalidUserType
   218  	}
   219  }