Skip to content

Commit

Permalink
Merge pull request #20 from EducationPerfect/fix-subjectfilter-relation
Browse files Browse the repository at this point in the history
fix: Corrected subject filter semantics
  • Loading branch information
tanczosm authored May 20, 2024
2 parents 29dc872 + ba5b27f commit 20831fd
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 39 deletions.
59 changes: 29 additions & 30 deletions SpiceDb/Api/SpiceDbPermissions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ public async Task<PermissionResponse> CheckPermissionAsync(string resourceType,
}

public async IAsyncEnumerable<SpiceDb.Models.ReadRelationshipsResponse> ReadRelationshipsAsync(string resourceType, string optionalResourceId = "",
string optionalRelation = "", string optionalSubjectType = "", string optionalSubjectId = "", string optionalSubjectRelation = "",
string optionalRelation = "", string optionalSubjectType = "", string optionalSubjectId = "", string? optionalSubjectRelation = null,
ZedToken? zedToken = null,
CacheFreshness cacheFreshness = CacheFreshness.AnyFreshness)
{
Expand All @@ -305,18 +305,9 @@ public async Task<PermissionResponse> CheckPermissionAsync(string resourceType,
ReadRelationshipsRequest req = new ReadRelationshipsRequest()
{
Consistency = new Consistency { MinimizeLatency = true, AtExactSnapshot = zedToken },
RelationshipFilter = new Authzed.Api.V1.RelationshipFilter
{
ResourceType = resourceType,
OptionalRelation = optionalRelation,
OptionalResourceId = optionalResourceId
}
RelationshipFilter = CreateRelationshipFilter(resourceType, optionalResourceId, optionalRelation, optionalSubjectType, optionalSubjectId, optionalSubjectRelation)
};
if (!String.IsNullOrEmpty(optionalSubjectType))
{
req.RelationshipFilter.OptionalSubjectFilter = new SubjectFilter() { SubjectType = optionalSubjectType, OptionalSubjectId = optionalSubjectId };
req.RelationshipFilter.OptionalSubjectFilter.OptionalRelation = new SubjectFilter.Types.RelationFilter() { Relation = optionalSubjectRelation };
}

if (cacheFreshness == CacheFreshness.AtLeastAsFreshAs)
{
req.Consistency.AtLeastAsFresh = zedToken;
Expand Down Expand Up @@ -364,29 +355,13 @@ public bool UpdateRelationships(ref RepeatedField<RelationshipUpdate> updateColl
}
}

public async Task<ZedToken?> DeleteRelationshipsAsync(string resourceType, string optionalResourceId = "", string optionalRelation = "", string optionalSubjectType = "", string optionalSubjectId = "", string optionalSubjectRelation = "", RepeatedField<Precondition>? optionalPreconditions = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
public async Task<ZedToken?> DeleteRelationshipsAsync(string resourceType, string optionalResourceId = "", string optionalRelation = "", string optionalSubjectType ="", string optionalSubjectId = "", string? optionalSubjectRelation = null, RepeatedField<Precondition>? optionalPreconditions = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
var req = new DeleteRelationshipsRequest
{
OptionalPreconditions = { optionalPreconditions },
RelationshipFilter = new Authzed.Api.V1.RelationshipFilter
{
ResourceType = resourceType,
OptionalRelation = optionalRelation,
OptionalResourceId = optionalResourceId
}
RelationshipFilter = CreateRelationshipFilter(resourceType, optionalResourceId, optionalRelation, optionalSubjectType, optionalSubjectId, optionalSubjectRelation)
};
if (!String.IsNullOrEmpty(optionalSubjectType))
{
req.RelationshipFilter.OptionalSubjectFilter = new SubjectFilter() { SubjectType = optionalSubjectType, OptionalSubjectId = optionalSubjectId };
if (!String.IsNullOrEmpty(optionalSubjectRelation))
{
req.RelationshipFilter.OptionalSubjectFilter.OptionalRelation = new SubjectFilter.Types.RelationFilter()
{
Relation = optionalSubjectRelation
};
}
}

var response = await _acl!.DeleteRelationshipsAsync(req, deadline: deadline, cancellationToken: cancellationToken);

Expand Down Expand Up @@ -461,4 +436,28 @@ public async Task<ZedToken> UpdateRelationshipsAsync(string resourceType, string
Context = caveat.Context?.ToStruct(),
};
}

private static Authzed.Api.V1.RelationshipFilter CreateRelationshipFilter(string resourceType, string optionalResourceId, string optionalRelation, string optionalSubjectType, string optionalSubjectId, string? optionalSubjectRelation)
{
var filter = new Authzed.Api.V1.RelationshipFilter
{
ResourceType = resourceType,
OptionalRelation = optionalRelation,
OptionalResourceId = optionalResourceId
};

if (!String.IsNullOrEmpty(optionalSubjectType))
{
filter.OptionalSubjectFilter = new Authzed.Api.V1.SubjectFilter { SubjectType = optionalSubjectType, OptionalSubjectId = optionalSubjectId };
if (optionalSubjectRelation is not null)
{
filter.OptionalSubjectFilter.OptionalRelation = new Authzed.Api.V1.SubjectFilter.Types.RelationFilter()
{
Relation = optionalSubjectRelation
};
}
}

return filter;
}
}
7 changes: 3 additions & 4 deletions SpiceDb/ISpiceDbClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public interface ISpiceDbClient
/// <param name="zedToken"></param>
/// <param name="cacheFreshness"></param>
/// <returns></returns>
IAsyncEnumerable<SpiceDb.Models.ReadRelationshipsResponse> ReadRelationshipsAsync(Models.RelationshipFilter resource, Models.RelationshipFilter? subject = null,
IAsyncEnumerable<SpiceDb.Models.ReadRelationshipsResponse> ReadRelationshipsAsync(Models.RelationshipFilter resource, Models.SubjectFilter? subject = null,
bool excludePrefix = false,
ZedToken? zedToken = null,
CacheFreshness cacheFreshness = CacheFreshness.AnyFreshness);
Expand All @@ -39,8 +39,8 @@ public interface ISpiceDbClient
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns></returns>
Task<ZedToken?> DeleteRelationshipsAsync(SpiceDb.Models.RelationshipFilter resourceFilter, Models.RelationshipFilter? optionalSubjectFilter = null, List<SpiceDb.Models.Precondition>? optionalPreconditions = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));

Task<ZedToken?> DeleteRelationshipsAsync(SpiceDb.Models.RelationshipFilter resourceFilter, Models.SubjectFilter? optionalSubjectFilter = null, List<SpiceDb.Models.Precondition>? optionalPreconditions = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// CheckPermission determines for a given resource whether a subject computes to having a permission or is a direct member of
/// a particular relation. Contains support for context as well where context objects can be string, bool, double, int, uint, or long.
Expand Down Expand Up @@ -91,7 +91,6 @@ public interface ISpiceDbClient
/// <returns></returns>
Task<ZedToken> DeleteRelationshipAsync(SpiceDb.Models.Relationship relation);


/// <summary>
/// Removes an existing relationship (if it exists)
/// </summary>
Expand Down
8 changes: 8 additions & 0 deletions SpiceDb/Models/SubjectFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace SpiceDb.Models;

public class SubjectFilter
{
public required string Type { get; set; }
public string? OptionalRelation { get; set; }
public string OptionalId { get; set; } = string.Empty;
}
10 changes: 5 additions & 5 deletions SpiceDb/SpiceDbClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ private ChannelBase CreateDefaultAuthenticatedChannel(string address, string? to
/// <param name="cacheFreshness">Specifies the acceptable freshness of the data to be read from the cache.</param>
/// <returns>An async enumerable of <see cref="ReadRelationshipsResponse"/> objects matching the specified filters.</returns>
public async IAsyncEnumerable<ReadRelationshipsResponse> ReadRelationshipsAsync(RelationshipFilter resource,
RelationshipFilter? subject = null,
SubjectFilter? subject = null,
bool excludePrefix = false,
ZedToken? zedToken = null,
CacheFreshness cacheFreshness = CacheFreshness.AnyFreshness)
Expand All @@ -108,7 +108,7 @@ public async IAsyncEnumerable<ReadRelationshipsResponse> ReadRelationshipsAsync(
resource.OptionalId,
resource.OptionalRelation,
EnsurePrefix(subject?.Type) ?? string.Empty, subject?.OptionalId ?? string.Empty,
subject?.OptionalRelation ?? string.Empty, zedToken.ToAuthzedToken(), cacheFreshness))
subject?.OptionalRelation, zedToken.ToAuthzedToken(), cacheFreshness))
{
if (excludePrefix)
{
Expand Down Expand Up @@ -203,7 +203,7 @@ public async IAsyncEnumerable<ReadRelationshipsResponse> ReadRelationshipsAsync(

return response?.WrittenAt.ToSpiceDbToken();
}

/// <summary>
/// DeleteRelationships atomically bulk deletes all relationships matching the provided filter. If no relationships
/// match, none will be deleted and the operation will succeed. An optional set of preconditions can be provided
Expand All @@ -216,7 +216,7 @@ public async IAsyncEnumerable<ReadRelationshipsResponse> ReadRelationshipsAsync(
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns></returns>
public async Task<ZedToken?> DeleteRelationshipsAsync(RelationshipFilter resourceFilter,
RelationshipFilter? optionalSubjectFilter = null, List<Precondition>? optionalPreconditions = null,
SubjectFilter? optionalSubjectFilter = null, List<Precondition>? optionalPreconditions = null,
DateTime? deadline = null, CancellationToken cancellationToken = default)
{
RepeatedField<Authzed.Api.V1.Precondition> preconditionCollection = new();
Expand Down Expand Up @@ -254,7 +254,7 @@ public async IAsyncEnumerable<ReadRelationshipsResponse> ReadRelationshipsAsync(
resourceFilter.OptionalId, resourceFilter.OptionalRelation,
EnsurePrefix(optionalSubjectFilter?.Type) ?? string.Empty,
optionalSubjectFilter?.OptionalId ?? string.Empty,
optionalSubjectFilter?.OptionalRelation ?? string.Empty, preconditionCollection, deadline,
optionalSubjectFilter?.OptionalRelation, preconditionCollection, deadline,
cancellationToken))
.ToSpiceDbToken();
}
Expand Down

0 comments on commit 20831fd

Please sign in to comment.