From 44fd32567b5fdb01262ef8f44f5b9f2f2acf51b5 Mon Sep 17 00:00:00 2001 From: Mike Mason Date: Tue, 18 Jul 2023 19:48:52 +0000 Subject: [PATCH] update permissions relationships calls to use from/to --- internal/permissions/client.go | 3 +- internal/permissions/relationships.go | 70 +++++++++++------------ internal/service/organizations.go | 2 +- internal/service/process_relationships.go | 16 ++++-- internal/service/relationships.go | 2 +- 5 files changed, 49 insertions(+), 44 deletions(-) diff --git a/internal/permissions/client.go b/internal/permissions/client.go index d2eff88..e449d1b 100644 --- a/internal/permissions/client.go +++ b/internal/permissions/client.go @@ -34,7 +34,8 @@ type Client interface { DeleteResourceRelationship(ctx context.Context, resourceID gidx.PrefixedID, relation string, relatedResourceID gidx.PrefixedID) error DeleteRole(ctx context.Context, roleID gidx.PrefixedID) error FindResourceRoleByActions(ctx context.Context, resourceID gidx.PrefixedID, actions []string) (ResourceRole, error) - ListResourceRelationships(ctx context.Context, resourceID gidx.PrefixedID, relatedResourceType string) ([]ResourceRelationship, error) + ListResourceRelationshipsFrom(ctx context.Context, resourceID gidx.PrefixedID) ([]ResourceRelationship, error) + ListResourceRelationshipsTo(ctx context.Context, resourceID gidx.PrefixedID) ([]ResourceRelationship, error) ListResourceRoles(ctx context.Context, resourceID gidx.PrefixedID) (ResourceRoles, error) ListRoleAssignments(ctx context.Context, roleID gidx.PrefixedID) ([]gidx.PrefixedID, error) RoleHasAssignment(ctx context.Context, roleID gidx.PrefixedID, memberID gidx.PrefixedID) (bool, error) diff --git a/internal/permissions/relationships.go b/internal/permissions/relationships.go index 5d79a1d..fe7d744 100644 --- a/internal/permissions/relationships.go +++ b/internal/permissions/relationships.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "net/http" - "net/url" "go.infratographer.com/x/gidx" ) @@ -58,53 +57,54 @@ func (c *client) DeleteResourceRelationship(ctx context.Context, resourceID gidx return nil } -// ListResourceRelationships returns resources related to the given id. -// If relatedResourceType is not provied, relations to subjects are returned. -// If relatedResourceType is provided, relations to the given resource are returned which match the given type. -func (c *client) ListResourceRelationships(ctx context.Context, resourceID gidx.PrefixedID, relatedResourceType string) ([]ResourceRelationship, error) { - query := url.Values{ - "resourceType": []string{relatedResourceType}, - } - - url := url.URL{ - Path: fmt.Sprintf("/api/v1/resources/%s/relationships", resourceID.String()), - RawQuery: query.Encode(), - } - +// ListResourceRelationshipsFrom returns resources related to the given id. +func (c *client) ListResourceRelationshipsFrom(ctx context.Context, resourceID gidx.PrefixedID) ([]ResourceRelationship, error) { var response struct { Data []resourceRelationship `json:"data"` } - if _, err := c.DoRequest(ctx, http.MethodGet, url.String(), nil, &response); err != nil { // nolint:bodyclose // closed by Do on json decode. + if _, err := c.DoRequest(ctx, http.MethodGet, fmt.Sprintf("/api/v1/relationships/from/%s", resourceID.String()), nil, &response); err != nil { // nolint:bodyclose // closed by Do on json decode. return nil, err } data := make([]ResourceRelationship, len(response.Data)) for i, entry := range response.Data { - var ( - resID, subID gidx.PrefixedID - err error - ) - - if entry.ResourceID != "" { - resID, err = gidx.Parse(entry.ResourceID) - if err != nil { - return nil, err - } - } - - if entry.SubjectID != "" { - subID, err = gidx.Parse(entry.SubjectID) - if err != nil { - return nil, err - } + subID, err := gidx.Parse(entry.SubjectID) + if err != nil { + return nil, err } data[i] = ResourceRelationship{ - ResourceID: resID, - Relation: entry.Relation, - SubjectID: subID, + Relation: entry.Relation, + SubjectID: subID, + } + } + + return data, nil +} + +// ListResourceRelationshipsTo returns resources related to the given id. +func (c *client) ListResourceRelationshipsTo(ctx context.Context, resourceID gidx.PrefixedID) ([]ResourceRelationship, error) { + var response struct { + Data []resourceRelationship `json:"data"` + } + + if _, err := c.DoRequest(ctx, http.MethodGet, fmt.Sprintf("/api/v1/relationships/to/%s", resourceID.String()), nil, &response); err != nil { // nolint:bodyclose // closed by Do on json decode. + return nil, err + } + + data := make([]ResourceRelationship, len(response.Data)) + + for i, entry := range response.Data { + resID, err := gidx.Parse(entry.ResourceID) + if err != nil { + return nil, err + } + + data[i] = ResourceRelationship{ + ResourceID: resID, + Relation: entry.Relation, } } diff --git a/internal/service/organizations.go b/internal/service/organizations.go index b396af4..d91136e 100644 --- a/internal/service/organizations.go +++ b/internal/service/organizations.go @@ -19,7 +19,7 @@ func (s *service) buildOrganizationRelationships(org *models.OrganizationDetails Relation: RelateParent, Resource: s.rootResource, }, - SubjectType: TypeProject, + SubjectRelation: RelateParent, } for _, member := range org.Memberships { diff --git a/internal/service/process_relationships.go b/internal/service/process_relationships.go index 6e13a52..e0a7ec2 100644 --- a/internal/service/process_relationships.go +++ b/internal/service/process_relationships.go @@ -17,10 +17,10 @@ func (s *service) processRelationships(ctx context.Context, eventType string, re wantParentRelationship, wantSubjectRelationships := s.mapRelationWants(relationships) - liveParentRelationships, liveSubjectRelationships, err := s.getRelationshipMap(ctx, relationships.Resource, relationships.SubjectType) + liveParentRelationships, liveSubjectRelationships, err := s.getRelationshipMap(ctx, relationships.Resource, relationships.SubjectRelation) if err != nil { rlogger.Errorw("failed to get relationship map", - "relationships.subject_type", relationships.SubjectType, + "relationships.subject_relation", relationships.SubjectRelation, "error", err, ) @@ -177,16 +177,16 @@ func (s *service) mapRelationWants(relationships Relationships) (*Relation, map[ // getRelationshipMap fetches the provided resources relationships, as the source resource and the destination subject. // Returned are two maps, the first maps Subject IDs -> Relationship // The second map, maps Resource IDs -> relationship -func (s *service) getRelationshipMap(ctx context.Context, resource IDPrefixableResource, relatedObjectType ObjectType) (map[gidx.PrefixedID]RelationshipType, map[gidx.PrefixedID]RelationshipType, error) { - liveResource, err := s.perms.ListResourceRelationships(ctx, resource.PrefixedID(), "") +func (s *service) getRelationshipMap(ctx context.Context, resource IDPrefixableResource, relation RelationshipType) (map[gidx.PrefixedID]RelationshipType, map[gidx.PrefixedID]RelationshipType, error) { + liveResource, err := s.perms.ListResourceRelationshipsFrom(ctx, resource.PrefixedID()) if err != nil { return nil, nil, err } var liveSubject []permissions.ResourceRelationship - if relatedObjectType != "" { - liveSubject, err = s.perms.ListResourceRelationships(ctx, resource.PrefixedID(), relatedObjectType.Prefix()) + if relation != "" { + liveSubject, err = s.perms.ListResourceRelationshipsTo(ctx, resource.PrefixedID()) if err != nil { return nil, nil, err } @@ -205,6 +205,10 @@ func (s *service) getRelationshipMap(ctx context.Context, resource IDPrefixableR subject := make(map[gidx.PrefixedID]RelationshipType, len(liveSubject)) for _, relationship := range liveSubject { + if relationship.Relation != string(relation) { + continue + } + subject[relationship.ResourceID] = RelationshipType(relationship.Relation) } diff --git a/internal/service/relationships.go b/internal/service/relationships.go index b06ee31..bb665b6 100644 --- a/internal/service/relationships.go +++ b/internal/service/relationships.go @@ -24,7 +24,7 @@ type IDPrefixableResource interface { type Relationships struct { Resource IDPrefixableResource Parent Relation - SubjectType ObjectType + SubjectRelation RelationshipType SubjectRelationships []Relation Memberships []ResourceMemberships }