Actix (Rust) Reference
PropelAuth's Actix library provides all the building blocks you need to add authentication to your Actix projects.
Installation
In your Cargo.toml
file, add the following line:
propelauth = { version = "0.9.0", features = ["actix4"] }
Initialize
There are two options for initializing the library. You can call PropelAuth::fetch_and_init
which is an async
function that will
fetch the metadata needed to verify access tokens. Or, you can call PropelAuth::init
and pass in the metadata directly. The later is
useful for serverless environments.
let auth = PropelAuth::fetch_and_init(AuthOptions {
auth_url: "REPLACE_ME".to_string(),
api_key: "REPLACE_ME".to_string(),
}).await.expect("Unable to initialize authentication");
Protect API Routes
You'll need to add PropelAuth
as app_data
:
HttpServer::new(move || {
App::new()
.service(whoami)
.service(org_whoami)
.app_data(web::Data::new(auth.clone())) // <-- here
})
You can then take User in as an argument, which will look for an access token in the Authorization
HTTP header:
// User will automatically return a 401 (Unauthorized) if a valid access token wasn't provided
#[get("/whoami")]
async fn whoami(user: User) -> impl Responder {
HttpResponse::Ok().json(user)
}
Verifying the access token doesn't require an external request.
Authorization / Organizations
You can also verify which organizations the user is in, and which roles and permissions they have:
// If the user isn't in the provided organization, a 403 is returned
#[get("/org/{org_name}/whoami")]
async fn whoami(user: User, org_name: web::Path<String>) -> Result<impl Responder, UnauthorizedOrForbiddenError> {
let org = user.validate_org_membership(RequiredOrg::OrgName(&org_name.into_inner()),
UserRequirementsInOrg::IsRole("Admin"))?;
Ok(HttpResponse::Ok()
.body(format!("You are a {} in {}", org.user_role, org.org_name)))
}
User
The User object contains information about the user that made the request.
- Name
user_id
- Type
- string
- Description
The unique id of the user.
- Name
email
- Type
- string
- Description
The email of the user.
- Name
first_name
- Type
- string
- Description
The first name of the user.
- Name
last_name
- Type
- string
- Description
The last name of the user.
- Name
username
- Type
- string
- Description
The username of the user.
- Name
legacy_user_id
- Type
- string
- Description
If the user was migrated using our Migration API, this will be the id of the user in the legacy system.
- Name
impersonator_user_id
- Type
- string
- Description
If the user is being impersonated, this is id of the user that impersonated them.
- Name
login_method
- Type
- object
- Description
The method the user used to log in. Returns the Login Method Property.
- Name
active_org_id
- Type
- string | undefined
- Description
The ID of the Active Org.
- Name
properties
- Type
- HashMap<String, Value>
- Description
A dictionary of custom properties associated with the user.
- Name
org_id_to_org_member_info
- Type
- HashMap<String, OrgMemberInfo>
- Description
A dictionary mapping from organization id to OrgMemberInfo object.
- Name
validate_org_membership(...)
- Type
- function
- Description
A function that validates the user is in the specified organization, and has the specified role and permissions. See Authorization / Organizations for more information.
- Name
get_org(RequiredOrg)
- Type
- fn() => Optional<OrgMemberInfo>
- Description
A function that returns the OrgMemberInfo object for the specified organization.
- Name
get_all_orgs()
- Type
- fn() => OrgMemberInfo[]
- Description
A function that returns a list of OrgMemberInfo objects for all organizations the user is in.
- Name
get_active_org_id
- Type
- fn() => string | undefined
- Description
Returns the ID of the Active Org.
- Name
get_active_org
- Type
- fn() => Optional<OrgMemberInfo>
- Description
Returns the OrgMemberInfo of the Active Org.
- Name
is_impersonated
- Type
- fn() => bool
- Description
Whether the current user is being impersonated by someone else. See User Impersonation for more information.
OrgMemberInfo
The OrgMemberInfo object contains information about the user's membership in an organization.
- Name
org_id
- Type
- string
- Description
The unique id of the organization.
- Name
org_name
- Type
- string
- Description
The name of the organization.
- Name
org_metadata
- Type
- object
- Description
The metadata associated with the organization.
- Name
user_role
- Type
- string
- Description
The role of the user in the organization.
- Name
user_permissions
- Type
- Vec<String>
- Description
A list of permissions the user has in the organization, based on their role.
- Name
url_safe_org_name
- Type
- string
- Description
The URL-safe name of the organization.
- Name
inherited_user_roles_plus_current_role
- Type
- Vec<String>
- Description
The role of the user within this organization plus each inherited role.
- Name
is_role
- Type
- fn(role: string) -> bool
- Description
A function that returns true if the user has the specified role in the organization.
- Name
is_at_least_role
- Type
- fn(role: string) -> bool
- Description
A function that returns true if the user has at least the specified role in the organization.
- Name
has_permission
- Type
- fn(permission: string) -> bool
- Description
A function that returns true if the user has the specified permission in the organization.
- Name
has_all_permissions
- Type
- fn(permissions: Vec<String>) -> bool
- Description
A function that returns true if the user has all of the specified permissions in the organization.
- Name
org_role_structure
- Type
- string
- Description
The role structure set for your project. See multi roles per user for more information.
- Name
additional_roles
- Type
- Vec<String>
- Description
If using multiple roles per user, returns an array of roles that the user belongs to. Excludes the
user_role
.
Calling backend APIs
You can also use the library to call the PropelAuth APIs directly, allowing you to fetch users, create orgs, and a lot more.
#[post("/magic_link")]
async fn make_req(auth: web::Data<PropelAuth>) -> impl Responder {
let magic_link = auth.user().create_magic_link(CreateMagicLinkRequest {
email: "user@customer.com".to_string(),
..Default::default()
}).await.expect("Couldn't create magic link");
HttpResponse::Ok().json(magic_link)
}
See the API Reference for more information.