Open qwackididuck opened 1 month ago
I think it need to be ! Today, ther's no way to compare 2 biscuits or just read any facts...
Any update on this subject ?
The solution suggested by @Benoit12345 is exactly what I thought.
Do you agree ?
could you tell me more about the use case here? The generateWorld
was meant only for tests. if you want to access data in the token, that's supposed to be done through the authorizer API, with methods like Query
.
A better solution to access the entire list would be the snapshot API that we will introduce soon to this library (already specified and implemented in other libraries): https://github.com/biscuit-auth/biscuit/blob/c87cbb5d778964d6574df3e9e6579567cad12fff/schema.proto#L186-L207
If the goal is to compare tokens there may be other means. What do you want to achieve?
Thanks @Geal, One of the use case (the main one for us) is for our own tests where we have to check a generated token (ie. same as expected one). For the moment, we use a "very dirty way" by comparing the String() result (which generate sometimes different output and failed our tests with no reason... but that's another subject). We thought to use the authorizer API but using it means that we have, for each generated biscuit, for each use cases, for each facts/rules, to validate every possible values to be sure that the fact/rule is present and validate the right way. That's much more a validation of the authorizer part than a validation of the biscuit itself. Today, for the Go client (it doesn't seem to be the case for other clients), the API is really limited to creation/authorization. It's quite hard to just consult the biscuit content.
Thank you @Geal for your answer
To add more information to @Benoit12345 comment about our use cases :
We have different kinds of biscuit. Each kind allowing access to different kind of resources.
Since they are different, they have different authorizers, that are dynamically loaded depending on the type
.
The type
of the biscuit is stored inside of it.
So we can not use the Query
API on the authorizer to get the type
, since we need the type
to get the authorizer :disappointed:
In my understanding, the Query
API is available on an authorizer, after an Authorize()
call.
In my tests :
Query before authorizing
b, err := biscuit.Unmarshal(token)
if err != nil {
panic("unmarhsal failed: " + err.Error())
}
fmt.Println(b.String())
authorizer, err := b.Authorizer(pub)
if err != nil {
panic("authorizer creation failed: " + err.Error())
}
authorizerRules, err := parser.FromStringRule(`
my::type($t) <- type($t)
`)
if err != nil {
panic("authorizer contents can not be parsed: " + err.Error())
}
authorizer.AddRule(authorizerRules)
fs, _ := authorizer.Query(authorizerRules) // fs = [] here
Query after authorizing
b, err := biscuit.Unmarshal(token)
if err != nil {
panic("unmarhsal failed: " + err.Error())
}
fmt.Println(b.String())
authorizer, err := b.Authorizer(pub)
if err != nil {
panic("authorizer creation failed: " + err.Error())
}
policy, err := parser.FromStringPolicy("allow if type(\"A\")")
if err != nil {
panic("unparsable policy: " + err.Error())
}
authorizer.AddPolicy(policy)
if err := authorizer.Authorize(); err != nil {
panic("failed authorizing: " + err.Error())
}
authorizerRules, err := parser.FromStringRule(`
my::type($t) <- type($t)
`)
if err != nil {
panic("authorizer contents can not be parsed: " + err.Error())
}
authorizer.AddRule(authorizerRules)
fs, _ := authorizer.Query(authorizerRules) // fs contains the my::type fact
As said in my first message, we have to work with this legacy approach...
With an imaginary example :
We have 2 kinds of biscuit : Type A with the following authorizer
check if res::user($r), user($u), $u == $r
Type B with the following authorizer
check if res::amount($a), max($m), $a <= $m
We generate a biscuit for token A
type("A")
user("foo")
The biscuit is used by the client to access a resource, so to get the authorizer, we must retrieve the fact type
from the given biscuit.
So how can we do it in your opinion ?
Thank you very much :)
Hello @Geal ,
Do you have any advice on our issue ?
We need to keep the same behaviour, allowed in Java, but it does not seem possible in Golang without the requested evolution..
Or maybe you have a better idea ?
Thank you !
Hello,
Does anyone have an opinion ?
Hi,
We're in charge of taking over a component that generates and consumes biscuits. The component is developed in Java and we want to rewrite it in Go.
I wanted to retrieve a fact from a unmarshalled biscuit.
Example in Java of retrieving the facts (here, the first one)
And the biscuit
In Go, we have no function that allows us to get the facts of a biscuit...
I suppose it could be done by performing
Query
on theWorld
structure, and theBiscuit
structure has agenerateWorld
method that can create this neededWorld
, but it is private and only used by the tests...Is this a bug ? Shouldn't it be available for consumption ?
If not, how can I retrieve the facts of an unmarshalled biscuit properly ? (no regex and other ugly stuff like that)
Thank you very much