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 DeleteResourceRelationship(ctx context.Context, resourceID gidx.PrefixedID, relation string, relatedResourceID gidx.PrefixedID) error
DeleteRole(ctx context.Context, roleID gidx.PrefixedID) error DeleteRole(ctx context.Context, roleID gidx.PrefixedID) error
FindResourceRoleByActions(ctx context.Context, resourceID gidx.PrefixedID, actions []string) (ResourceRole, 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) ListResourceRoles(ctx context.Context, resourceID gidx.PrefixedID) (ResourceRoles, error)
ListRoleAssignments(ctx context.Context, roleID gidx.PrefixedID) ([]gidx.PrefixedID, error) ListRoleAssignments(ctx context.Context, roleID gidx.PrefixedID) ([]gidx.PrefixedID, error)
RoleHasAssignment(ctx context.Context, roleID gidx.PrefixedID, memberID gidx.PrefixedID) (bool, error) RoleHasAssignment(ctx context.Context, roleID gidx.PrefixedID, memberID gidx.PrefixedID) (bool, error)

View File

@@ -4,7 +4,6 @@ import (
"context" "context"
"fmt" "fmt"
"net/http" "net/http"
"net/url"
"go.infratographer.com/x/gidx" "go.infratographer.com/x/gidx"
) )
@@ -58,53 +57,54 @@ func (c *client) DeleteResourceRelationship(ctx context.Context, resourceID gidx
return nil return nil
} }
// ListResourceRelationships returns resources related to the given id. // ListResourceRelationshipsFrom returns resources related to the given id.
// If relatedResourceType is not provied, relations to subjects are returned. func (c *client) ListResourceRelationshipsFrom(ctx context.Context, resourceID gidx.PrefixedID) ([]ResourceRelationship, error) {
// 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(),
}
var response struct { var response struct {
Data []resourceRelationship `json:"data"` 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 return nil, err
} }
data := make([]ResourceRelationship, len(response.Data)) data := make([]ResourceRelationship, len(response.Data))
for i, entry := range response.Data { for i, entry := range response.Data {
var ( subID, err := gidx.Parse(entry.SubjectID)
resID, subID gidx.PrefixedID if err != nil {
err error return nil, err
)
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
}
} }
data[i] = ResourceRelationship{ data[i] = ResourceRelationship{
ResourceID: resID, Relation: entry.Relation,
Relation: entry.Relation, SubjectID: subID,
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, Relation: RelateParent,
Resource: s.rootResource, Resource: s.rootResource,
}, },
SubjectType: TypeProject, SubjectRelation: RelateParent,
} }
for _, member := range org.Memberships { 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) 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 { if err != nil {
rlogger.Errorw("failed to get relationship map", rlogger.Errorw("failed to get relationship map",
"relationships.subject_type", relationships.SubjectType, "relationships.subject_relation", relationships.SubjectRelation,
"error", err, "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. // getRelationshipMap fetches the provided resources relationships, as the source resource and the destination subject.
// Returned are two maps, the first maps Subject IDs -> Relationship // Returned are two maps, the first maps Subject IDs -> Relationship
// The second map, maps Resource 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) { func (s *service) getRelationshipMap(ctx context.Context, resource IDPrefixableResource, relation RelationshipType) (map[gidx.PrefixedID]RelationshipType, map[gidx.PrefixedID]RelationshipType, error) {
liveResource, err := s.perms.ListResourceRelationships(ctx, resource.PrefixedID(), "") liveResource, err := s.perms.ListResourceRelationshipsFrom(ctx, resource.PrefixedID())
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
var liveSubject []permissions.ResourceRelationship var liveSubject []permissions.ResourceRelationship
if relatedObjectType != "" { if relation != "" {
liveSubject, err = s.perms.ListResourceRelationships(ctx, resource.PrefixedID(), relatedObjectType.Prefix()) liveSubject, err = s.perms.ListResourceRelationshipsTo(ctx, resource.PrefixedID())
if err != nil { if err != nil {
return nil, nil, err 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)) subject := make(map[gidx.PrefixedID]RelationshipType, len(liveSubject))
for _, relationship := range liveSubject { for _, relationship := range liveSubject {
if relationship.Relation != string(relation) {
continue
}
subject[relationship.ResourceID] = RelationshipType(relationship.Relation) subject[relationship.ResourceID] = RelationshipType(relationship.Relation)
} }

View File

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