Replies: 8 comments
-
Howdy! I'm already familiar with your repo and using it at work - have even raised a couple of issues under my work account (thanks for addressing those btw) 😀 In terms of goals, the first one was to solve the problem of having to refer to the schema itself for definition/relation/permission names and referencing these directly or manually creating constants for them. So at present the source generator just generates these constants for you: namespace SpiceWeaver
{
public static class Schema
{
public static class Definitions
{
public static class User
{
public const string Name = "user";
}
public static class Document
{
public const string Name = "document";
public static class Relations
{
public const string Viewer = "viewer";
public const string Editor = "editor";
}
public static class Permissions
{
public const string View = "view";
public const string Edit = "edit";
}
}
}
}
} Ideally, it would evolve into a strongly-typed client that wraps a lower-level client like yours, so consumers would not need to work directly with If you think this is something that could live under the SpiceDb.net project, I'd be more than happy to contribute. One thing to note is that originally I was writing a schema parser myself, but it was using Pidgin which is not compatible with .NET Standard (and therefore Source Generators), so I scrapped that and am now using spice2json instead, which uses the SpiceDB DSL parser to output json. This does mean there is a dependency on this external binary at present, however. I'm unsure if the Source Generator route is 100% necessary versus something like a simple cli tool that spits out |
Beta Was this translation helpful? Give feedback.
-
Ah that's how your named looked familiar. I didn't put the two together. Since the recent major refactor you can now supply a ChannelBase directly if so desired for the grpc channel. Try out 1.5.1 if you haven't yet. Relationships can also include caveats now when you create them. I also reorganized a lot of code to clean things up a bit and started work on a documentation project. If we could unite the two I think that would be great and since you are using it for work it could give you an opportunity to shape the library as well. Honestly it feels like a bit of a lonely island working on the client because it's tough to tell how much SpiceDb is even adopted by the .net community. TBH I saw your comment on the spice2json library so it appears it isn't just limited to .net. I made the .net client out of necessity originally though because I wanted to use it from c# first of all, there wasn't a lot to choose from client-wise, and I wanted to create a wrapper for possibly more than SpiceDb (which is why some of the types don't match exactly in the client) but I've since mostly steered exclusively towards SpiceDb. I do want to be able to provide better quality of life c# code for developers though who want to work with the database though which means if I can create a useful layer on top of the grpc client that could be useful. One of the aspects I found off-putting with libraries like the Java client is how much code it takes to just check a permission. For your project, what if you still used spice2json but eliminated the executable dependency (sort of) by just requiring that schemas be run through spice2json first and named with .zedj (or similar) before adding to the project? Then have the source generator just transform that specific file? That way you can just check in the transformed schema directly into your source. It requires an extra step but the ability to use it doesn't require much setup work (especially on remote build servers). Here is an ANTLR grammar I made. It is missing types for caveats but is a start. The grammar can be used as a basis to build other grammars. Right now I think the spice2json route is the best approach rather than trying to parse it directly.
Let me know your thoughts. |
Beta Was this translation helpful? Give feedback.
-
Does Spice2Json pick up on caveats as well? A caveat has a name and context, but the context keys (user_ip and allowed_range) are also well-defined. ex.
For simplicity sake you could create a class called Caveats that contains all the caveats. If the caveats themselves were classes that inherited SpiceDb.net Caveat that would make working with them pretty simple.
That would be something like: public class Caveats {
public class HasValidIp : Caveat
{
public HasValidIp () { this.Name = "has_valid_ip"; }
public IpAddress? UserIp {
get {
return this.Context.ContainsKey("user_ip") ? this.Context["user_ip"].ToIpAddress() : null
}
set {
this.Context["user_ip"] = value;
}
}
public string AllowedRange {
get {
return this.Context.ContainsKey("allowed_range") ? this.Context["allowed_range"] : null;
}
set {
this.Context["allowed_range"] = value;
}
}
}
} Note that allowed_range would be supplied when creating the relationship caveat and user_ip could be supplied during permission checks. |
Beta Was this translation helpful? Give feedback.
-
I've already taken this into account with an option on the additional file, was just missing documentation to explain
There's also a tree-sitter grammar written by the co-founder of AuthZed but I found tree-sitter hard to work with. |
Beta Was this translation helpful? Give feedback.
-
An issue was just raised in the SpiceDB repo about having an official .NET client: authzed/spicedb#1877 Be interesting to see what the response to this is. |
Beta Was this translation helpful? Give feedback.
-
TBH it's pretty easy to just generate a c# client off the protobuf definitions but I could definitely see how it's easier to have faith in a company if the client is supported by that company. You just have to deal with all the custom google grpc data structures. I wouldn't have bothered making what I did if there was something official. |
Beta Was this translation helpful? Give feedback.
-
I'm playing around with the source generator and it's working well. I created a new Relationship object as follows: using Arch = Archimedes.Schema.Definitions;
new Relationship($"{Arch.Document.Name}:abc123", Arch.Document.Relations.Viewer, $"{Arch.User.Name}:efg456"); Using the definition with an id is extremely common.. maybe add an additional "WithId" method to each definition as a helper? Something generated like this: public static class User
{
public const string Name = "user";
public static string WithId (string id) => $"user:{id}";
} Then code to use it is: using Arch = Archimedes.Schema.Definitions;
new Relationship(Arch.Document.WithId("abc123"), Arch.Platform.Relations.Viewer, Arch.User.WithId("efg456")); Thoughts? |
Beta Was this translation helpful? Give feedback.
-
I like it, if you throw that in a new issue I can take a look tomorrow - should be pretty trivial |
Beta Was this translation helpful? Give feedback.
-
Greetings! I'm working on a C# client for SpiceDb and I sorely would love to automate the process of making relationships and permissions strongly-typed and happened upon your repo. Hand-writing everything requires constant referencing of the schema and I'd rather not do that if possible.
My repo is at https://github.com/JalexSocial/SpiceDb
I was wondering what your project goals were if you would be willing to share.
Beta Was this translation helpful? Give feedback.
All reactions