diff --git a/internal/permissions/errors.go b/internal/permissions/errors.go index bb51d49..877b74d 100644 --- a/internal/permissions/errors.go +++ b/internal/permissions/errors.go @@ -3,8 +3,9 @@ package permissions import "errors" var ( - ErrRoleNotFound = errors.New("role not found") - ErrAssignmentFailed = errors.New("assignment failed") - ErrUnassignmentFailed = errors.New("unassignment failed") - ErrUnexpectedRoleDeleteFailed = errors.New("unknown role delete error") + ErrRoleNotFound = errors.New("role not found") + ErrAssignmentFailed = errors.New("assignment failed") + ErrUnassignmentFailed = errors.New("unassignment failed") + ErrUnexpectedRoleDeleteFailed = errors.New("unknown role delete error") + ErrUnexpectedRelationshipDeleteFailed = errors.New("unknown relationship delete error") ) diff --git a/internal/permissions/relationships.go b/internal/permissions/relationships.go index 5381c9b..7da8e25 100644 --- a/internal/permissions/relationships.go +++ b/internal/permissions/relationships.go @@ -21,6 +21,39 @@ type ResourceRelationship struct { SubjectID gidx.PrefixedID } +type ResourceRelationshipRequest struct { + Relation string `json:"relation"` + SubjectID string `json:"subject_id"` +} + +type ResourceRelationshipDeleteResponse struct { + Success bool `json:"success"` +} + +func (c *Client) DeleteResourceRelationship(ctx context.Context, resourceID gidx.PrefixedID, relation string, relatedResourceID gidx.PrefixedID) error { + path := fmt.Sprintf("/api/v1/resources/%s/relationships", resourceID.String()) + + body, err := encodeJSON(ResourceRelationshipRequest{ + Relation: relation, + SubjectID: relatedResourceID.String(), + }) + if err != nil { + return err + } + + var response ResourceRelationshipDeleteResponse + + if _, err := c.DoRequest(ctx, http.MethodDelete, path, body, &response); err != nil { + return err + } + + if !response.Success { + return ErrUnexpectedRelationshipDeleteFailed + } + + return nil +} + func (c *Client) ListResourceRelationships(ctx context.Context, resourceID gidx.PrefixedID, relatedResourceType string) ([]ResourceRelationship, error) { query := url.Values{ "resourceType": []string{relatedResourceType}, diff --git a/internal/service/process_relationships.go b/internal/service/process_relationships.go index a46dfef..8b8e1d4 100644 --- a/internal/service/process_relationships.go +++ b/internal/service/process_relationships.go @@ -102,16 +102,6 @@ func (s *service) processRelationships(ctx context.Context, eventType string, re }) } - for _, relatedResourceID := range deleteParentRelationships { - processEvents = append(processEvents, events.ChangeMessage{ - SubjectID: relationships.Resource.PrefixedID(), - EventType: string(events.DeleteChangeType), - AdditionalSubjectIDs: []gidx.PrefixedID{ - relatedResourceID, - }, - }) - } - for _, relation := range createSubjectRelationships { processEvents = append(processEvents, events.ChangeMessage{ SubjectID: relation.Resource.PrefixedID(), @@ -122,14 +112,23 @@ func (s *service) processRelationships(ctx context.Context, eventType string, re }) } + for _, relatedResourceID := range deleteParentRelationships { + err = s.perms.DeleteResourceRelationship(ctx, relationships.Resource.PrefixedID(), string(RelateParent), relatedResourceID) + if err != nil { + rlogger.Errorw("error deleting parent relationship", + "parent.resource.id", relatedResourceID.String(), + ) + } + } + for _, relation := range deleteSubjectRelationships { - processEvents = append(processEvents, events.ChangeMessage{ - SubjectID: relation.Resource.PrefixedID(), - EventType: string(events.DeleteChangeType), - AdditionalSubjectIDs: []gidx.PrefixedID{ - relationships.Resource.PrefixedID(), - }, - }) + err = s.perms.DeleteResourceRelationship(ctx, relation.Resource.PrefixedID(), string(relation.Relation), relationships.Resource.PrefixedID()) + if err != nil { + rlogger.Errorw("error deleting relationship", + "relation", relation.Relation, + "subject.id", relation.Resource.PrefixedID().String(), + ) + } } for _, event := range processEvents {