pub trait Policy<M>: Send + Sync {
type User: Authenticatable;
// Provided methods
fn before(&self, _user: &Self::User, _ability: &str) -> Option<bool> { ... }
fn view_any(&self, _user: &Self::User) -> AuthResponse { ... }
fn view(&self, _user: &Self::User, _model: &M) -> AuthResponse { ... }
fn create(&self, _user: &Self::User) -> AuthResponse { ... }
fn update(&self, _user: &Self::User, _model: &M) -> AuthResponse { ... }
fn delete(&self, _user: &Self::User, _model: &M) -> AuthResponse { ... }
fn restore(&self, _user: &Self::User, _model: &M) -> AuthResponse { ... }
fn force_delete(&self, _user: &Self::User, _model: &M) -> AuthResponse { ... }
fn check(
&self,
user: &Self::User,
ability: &str,
model: Option<&M>,
) -> AuthResponse { ... }
}Expand description
Trait for authorization policies.
Policies organize authorization logic around a particular model. Each method corresponds to a specific ability (view, create, update, delete, etc.).
§Example
ⓘ
use ferro_rs::authorization::{Policy, AuthResponse};
use crate::models::{User, Post};
pub struct PostPolicy;
impl Policy<Post> for PostPolicy {
type User = User;
fn before(&self, user: &Self::User, _ability: &str) -> Option<bool> {
// Admins can do everything
if user.is_admin {
return Some(true);
}
None // Continue to specific check
}
fn view(&self, _user: &Self::User, _model: &Post) -> AuthResponse {
AuthResponse::allow() // Anyone can view posts
}
fn update(&self, user: &Self::User, post: &Post) -> AuthResponse {
if user.id == post.user_id {
AuthResponse::allow()
} else {
AuthResponse::deny("You do not own this post.")
}
}
fn delete(&self, user: &Self::User, post: &Post) -> AuthResponse {
self.update(user, post) // Same as update
}
}Required Associated Types§
Sourcetype User: Authenticatable
type User: Authenticatable
The user type for this policy.
Provided Methods§
Sourcefn before(&self, _user: &Self::User, _ability: &str) -> Option<bool>
fn before(&self, _user: &Self::User, _ability: &str) -> Option<bool>
Run before any other authorization checks.
Return Some(true) to allow, Some(false) to deny,
or None to continue to the specific ability check.
This is useful for implementing admin bypass.
Sourcefn view_any(&self, _user: &Self::User) -> AuthResponse
fn view_any(&self, _user: &Self::User) -> AuthResponse
Determine whether the user can view any models.
Sourcefn view(&self, _user: &Self::User, _model: &M) -> AuthResponse
fn view(&self, _user: &Self::User, _model: &M) -> AuthResponse
Determine whether the user can view the model.
Sourcefn create(&self, _user: &Self::User) -> AuthResponse
fn create(&self, _user: &Self::User) -> AuthResponse
Determine whether the user can create models.
Sourcefn update(&self, _user: &Self::User, _model: &M) -> AuthResponse
fn update(&self, _user: &Self::User, _model: &M) -> AuthResponse
Determine whether the user can update the model.
Sourcefn delete(&self, _user: &Self::User, _model: &M) -> AuthResponse
fn delete(&self, _user: &Self::User, _model: &M) -> AuthResponse
Determine whether the user can delete the model.
Sourcefn restore(&self, _user: &Self::User, _model: &M) -> AuthResponse
fn restore(&self, _user: &Self::User, _model: &M) -> AuthResponse
Determine whether the user can restore the model.
Sourcefn force_delete(&self, _user: &Self::User, _model: &M) -> AuthResponse
fn force_delete(&self, _user: &Self::User, _model: &M) -> AuthResponse
Determine whether the user can permanently delete the model.