feat: add the concept of an instance owner (#23497)

* feat: Add the instance owner concept

* feat: improve handling of instance resource type

* fix: remove relic of cloud/oss split

* feat: Add an instance id. This gets set during onboarding and can be used to uniquely identify that instance.

* chore: Revert "feat: Add an instance id. This gets set during onboarding and can be used to uniquely identify that instance."

This reverts commit 6a712df61e.

We decided to stick with the "singleton" 1 id for now, as there is not a clear need for unique identifiers.
pull/23597/head
Jeffrey Smith II 2022-08-01 09:42:06 -04:00 committed by GitHub
parent f0072ef230
commit 67ccbae8ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 57 deletions

View File

@ -3,7 +3,6 @@ package influxdb
import (
"errors"
"fmt"
"os"
"path"
"github.com/influxdata/influxdb/v2/kit/platform"
@ -143,6 +142,8 @@ const (
RemotesResourceType = ResourceType("remotes") // 20
// ReplicationsResourceType gives permission to one or more replications.
ReplicationsResourceType = ResourceType("replications") // 21
// InstanceResourceType is a special permission that allows ownership of the entire instance (creating orgs/operator tokens/etc)
InstanceResourceType = ResourceType("instance") // 22
)
// AllResourceTypes is the list of all known resource types.
@ -169,6 +170,7 @@ var AllResourceTypes = []ResourceType{
AnnotationsResourceType, // 19
RemotesResourceType, // 20
ReplicationsResourceType, // 21
InstanceResourceType, // 22
// NOTE: when modifying this list, please update the swagger for components.schemas.Permission resource enum.
}
@ -202,6 +204,7 @@ func (t ResourceType) Valid() (err error) {
case AnnotationsResourceType: // 19
case RemotesResourceType: // 20
case ReplicationsResourceType: // 21
case InstanceResourceType: // 22
default:
err = ErrInvalidResourceType
}
@ -221,17 +224,8 @@ type Permission struct {
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)
}
@ -240,6 +234,10 @@ func (p Permission) matchesV1(perm Permission) bool {
return false
}
if p.Resource.Type == InstanceResourceType {
return true
}
if p.Resource.Type != perm.Resource.Type {
return false
}
@ -278,53 +276,6 @@ func (p Permission) matchesV1(perm Permission) bool {
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)
}
@ -421,6 +372,11 @@ func NewPermissionAtID(id platform.ID, a Action, rt ResourceType, orgID platform
func OperPermissions() []Permission {
ps := []Permission{}
for _, r := range AllResourceTypes {
// For now, we are only allowing instance permissions when logged in through session auth
// That is handled in user resource mapping
if r == InstanceResourceType {
continue
}
for _, a := range actions {
ps = append(ps, Permission{Action: a, Resource: Resource{Type: r}})
}
@ -434,6 +390,11 @@ func OperPermissions() []Permission {
func ReadAllPermissions() []Permission {
ps := make([]Permission, len(AllResourceTypes))
for i, t := range AllResourceTypes {
// For now, we are only allowing instance permissions when logged in through session auth
// That is handled in user resource mapping
if t == InstanceResourceType {
continue
}
ps[i] = Permission{Action: ReadAction, Resource: Resource{Type: t}}
}
return ps
@ -443,6 +404,11 @@ func ReadAllPermissions() []Permission {
func OwnerPermissions(orgID platform.ID) []Permission {
ps := []Permission{}
for _, r := range AllResourceTypes {
// For now, we are only allowing instance permissions when logged in through session auth
// That is handled in user resource mapping
if r == InstanceResourceType {
continue
}
for _, a := range actions {
if r == OrgsResourceType {
ps = append(ps, Permission{Action: a, Resource: Resource{Type: r, ID: &orgID}})
@ -468,6 +434,11 @@ func MePermissions(userID platform.ID) []Permission {
func MemberPermissions(orgID platform.ID) []Permission {
ps := []Permission{}
for _, r := range AllResourceTypes {
// For now, we are only allowing instance permissions when logged in through session auth
// That is handled in user resource mapping
if r == InstanceResourceType {
continue
}
if r == OrgsResourceType {
ps = append(ps, Permission{Action: ReadAction, Resource: Resource{Type: r, ID: &orgID}})
continue

View File

@ -45,6 +45,7 @@ func TestResourceListHandler(t *testing.T) {
string(influxdb.AnnotationsResourceType),
string(influxdb.RemotesResourceType),
string(influxdb.ReplicationsResourceType),
string(influxdb.InstanceResourceType),
}
resp := w.Result()

View File

@ -152,6 +152,16 @@ func (s *OnboardService) onboardUser(ctx context.Context, req *influxdb.Onboardi
return nil, err
}
if err := s.service.CreateUserResourceMapping(ctx, &influxdb.UserResourceMapping{
UserID: user.ID,
UserType: influxdb.Owner,
MappingType: influxdb.UserMappingType,
ResourceType: influxdb.InstanceResourceType,
ResourceID: platform.ID(1), // The instance doesn't have a resourceid
}); err != nil {
return nil, err
}
// create orgs buckets
ub := &influxdb.Bucket{
OrgID: org.ID,

View File

@ -149,6 +149,13 @@ func (m *UserResourceMapping) ownerPerms() ([]Permission, error) {
return OwnerPermissions(m.ResourceID), nil
}
if m.ResourceType == InstanceResourceType {
return []Permission{
{Action: ReadAction, Resource: Resource{Type: InstanceResourceType}},
{Action: WriteAction, Resource: Resource{Type: InstanceResourceType}},
}, nil
}
ps := []Permission{
// TODO: Uncomment these once the URM system is no longer being used for find lookups for:
// Telegraf