update permissions relationships calls to use from/to

This commit is contained in:
Mike Mason
2023-07-18 19:48:52 +00:00
parent 321e872b46
commit 44fd32567b
5 changed files with 49 additions and 44 deletions

View File

@@ -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)

View File

@@ -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,
}
}

View File

@@ -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 {

View File

@@ -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)
}

View File

@@ -24,7 +24,7 @@ type IDPrefixableResource interface {
type Relationships struct {
Resource IDPrefixableResource
Parent Relation
SubjectType ObjectType
SubjectRelation RelationshipType
SubjectRelationships []Relation
Memberships []ResourceMemberships
}