An Authorizer value wraps a datalog::World value, which contains facts and rules used for datalog evaluation. The Authorizer struct also contains an (optional) Vec<Block> representing a token (it is optional because an Authorizer can be created without a token. It also contains a BlockBuilder which contains facts, rules and checks added to the authorizer, as well as a Vec<Policy> containing policies added to the authorizer.
After calling authorize(), the World value contains facts from the token blocks, facts from the authorizer block builder and facts generated by rules.
The issue is that the World value does not always contain facts and rules from the authorizer builder:
when adding a token to an authorizer, all facts and rules are loaded in the World
when adding a fact or rule to an authorizer, it is added to the BlockBuilder but not the world
when calling authorize(), facts and rules from the BlockBuilder are copied to the world, and datalog generation is run
when calling query on Authorizer, datalog generation is automatically run on the current state of World (authorizer facts are not taken into account unless authorize() has been called first)
So, depending on whether authorize() and query() have been called, the authorizer world can be in various states:
no authorizer facts or rules, no generated facts at all
no authorizer facts or rules, but facts generated from the token contents
authorizer facts or rules, and facts generated from both the token contents and the authorizer
authorizer snapshots take a faithful copy of the inner World value, but only for facts. So taking a snapshot from an authorizer and then re-creating an authorizer from the snapshot will result in an authorizer with no authorizer rules in the datalog world
this makes relying on World contents tricky.
impl Display for Authorizer only uses World for facts and rules currently -> this needs to be fixed (#195)
Authorizer.query() only uses World, by design
Open questions:
what should query() return? would it be possible to avoid running datalog generation in query if we can ensure it's done elsewhere?
would it be possible to keep the World value in sync with the BlockBuilder. what would be the cost?
does it make sense to continue adding facts and rules to an Authorizer after having called authorize()?
after thinking things through and experimenting, here's what I think:
the datalog world should always be up-to-date wrt facts and rules from the token and authorizer blocks (this might be a bit tricky to do because of the optional scope annotation for the whole authorizer block)
datalog generation should be available as an explicit method
datalog generation should stay explicit since it is a costly operation
An
Authorizer
value wraps adatalog::World
value, which contains facts and rules used for datalog evaluation. TheAuthorizer
struct also contains an (optional)Vec<Block>
representing a token (it is optional because anAuthorizer
can be created without a token. It also contains aBlockBuilder
which contains facts, rules and checks added to the authorizer, as well as aVec<Policy>
containing policies added to the authorizer.After calling
authorize()
, theWorld
value contains facts from the token blocks, facts from the authorizer block builder and facts generated by rules.The issue is that the
World
value does not always contain facts and rules from the authorizer builder:World
BlockBuilder
but not the worldauthorize()
, facts and rules from theBlockBuilder
are copied to the world, and datalog generation is runquery
onAuthorizer
, datalog generation is automatically run on the current state ofWorld
(authorizer facts are not taken into account unlessauthorize()
has been called first)So, depending on whether
authorize()
andquery()
have been called, the authorizer world can be in various states:World
value, but only for facts. So taking a snapshot from an authorizer and then re-creating an authorizer from the snapshot will result in an authorizer with no authorizer rules in the datalog worldthis makes relying on
World
contents tricky.impl Display for Authorizer
only usesWorld
for facts and rules currently -> this needs to be fixed (#195)Authorizer.query()
only usesWorld
, by designOpen questions:
query()
return? would it be possible to avoid running datalog generation in query if we can ensure it's done elsewhere?World
value in sync with theBlockBuilder
. what would be the cost?Authorizer
after having calledauthorize()
?This affects #192 and #193