TupleModelManager

Struct TupleModelManager 

Source
pub struct TupleModelManager<T, S>
where T: GrpcService<Body>, T::Error: Into<StdError>, T::ResponseBody: Body<Data = Bytes> + Send + 'static, <T::ResponseBody as Body>::Error: Into<StdError> + Send,
{ /* private fields */ }
Expand description

Manages AuthorizationModels in OpenFGA.

Authorization models in OpenFGA don’t receive a unique name. Instead, they receive a random id on creation. If we don’t store this ID, we can’t find the model again and use its ID.

This ModelManager stores the mapping of AuthorizationModelVersion to the ID of the model in OpenFGA directly inside OpenFGA. This way can query OpenFGA to determine if a model with a certain version has already exists.

When running TupleModelManager::migrate(), the manager only applies models and their migrations if they don’t already exist in OpenFGA.

To store the mapping of model versions to OpenFGA IDs, the following needs to part of your Authorization Model:

type auth_model_id
type model_version
  relations
    define openfga_id: [auth_model_id]
    define exists: [auth_model_id:*]

Implementations§

Source§

impl<T, S> TupleModelManager<T, S>
where T: GrpcService<Body> + Clone, T::Error: Into<StdError>, T::ResponseBody: Body<Data = Bytes> + Send + 'static, <T::ResponseBody as Body>::Error: Into<StdError> + Send, S: Clone,

Source

pub fn new( client: OpenFgaServiceClient<T>, store_name: &str, model_prefix: &str, ) -> Self

Create a new TupleModelManager with the given client and model name. The model prefix must not change after the first model has been added or the model manager will not be able to find the model again. Use different model prefixes if models for different purposes are stored in the same OpenFGA store.

Source

pub fn add_model<FutPre, FutPost>( self, model: AuthorizationModel, version: AuthorizationModelVersion, pre_migration_fn: Option<impl Fn(OpenFgaServiceClient<T>, Option<String>, Option<String>, S) -> FutPre + Send + 'static>, post_migration_fn: Option<impl Fn(OpenFgaServiceClient<T>, Option<String>, Option<String>, S) -> FutPost + Send + 'static>, ) -> Self
where FutPre: Future<Output = Result<(), StdError>> + Send + 'static, FutPost: Future<Output = Result<(), StdError>> + Send + 'static,

Add a new model to the manager. If a model with the same version has already been added, the new model will replace the old one.

Ensure that migration functions are written in an idempotent way. If a migration fails, it might be retried.

Source

pub async fn migrate(&mut self, state: S) -> Result<()>

Run migrations.

This will:

  1. Get all existing models in the OpenFGA store.
  2. Determine which migrations need to be performed: All migrations with a version higher than the highest existing model.
  3. In order of the version of the model, perform the migrations:
    1. Run the pre-migration hook if it exists.
    2. Write the model to OpenFGA.
    3. Run the post-migration hook if it exists.
  4. Mark the model as applied in OpenFGA.
§Errors
  • If OpenFGA cannot be reached or a request fails.
  • If any of the migration hooks fail.
Source

pub async fn get_authorization_model_id( &mut self, version: AuthorizationModelVersion, ) -> Result<Option<String>>

Get the OpenFGA Authorization model ID for the specified model version. Ensure that migrations have been run before calling this method.

§Errors
  • If the store with the given name does not exist.
  • If a call to OpenFGA fails.
Source

pub async fn get_existing_versions( &mut self, ) -> Result<Vec<AuthorizationModelVersion>>

Get versions of all existing models in OpenFGA. Returns an empty vector if the store does not exist.

§Errors
  • If the call to determine existing stores fails.
  • If a tuple read call fails.

Trait Implementations§

Source§

impl<T, S: Clone> Clone for TupleModelManager<T, S>
where T: GrpcService<Body> + Clone, T::Error: Into<StdError>, T::ResponseBody: Body<Data = Bytes> + Send + 'static, <T::ResponseBody as Body>::Error: Into<StdError> + Send,

Source§

fn clone(&self) -> TupleModelManager<T, S>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T, S: Debug> Debug for TupleModelManager<T, S>
where T: GrpcService<Body> + Debug, T::Error: Into<StdError>, T::ResponseBody: Body<Data = Bytes> + Send + 'static, <T::ResponseBody as Body>::Error: Into<StdError> + Send,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T, S> !Freeze for TupleModelManager<T, S>

§

impl<T, S> !RefUnwindSafe for TupleModelManager<T, S>

§

impl<T, S> !Send for TupleModelManager<T, S>

§

impl<T, S> !Sync for TupleModelManager<T, S>

§

impl<T, S> Unpin for TupleModelManager<T, S>
where <<T as GrpcService<Body>>::ResponseBody as Body>::Error: Sized, <T as GrpcService<Body>>::Error: Sized, T: Unpin,

§

impl<T, S> !UnwindSafe for TupleModelManager<T, S>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more