Django Rest Framework Library Reference
Installation
$ pip install propelauth-django-rest-framework
Initialize
init_auth performs a one-time initialization of the library. It will verify
your api_key
is correct and fetch the metadata needed to verify access tokens
in
IsUserAuthenticated, AllowAny, and IsUserInOrg.
from propelauth_django_rest_framework import init_auth
auth = init_auth("YOUR_AUTH_URL", "YOUR_API_KEY")
Protect API routes
IsUserAuthenticated
A permission that will verify the request was made by a valid user. Specifically, it will:
- Check that a valid access token was provided. If not, the request is rejected
with a
401
status code. - Set request.propelauth_user with the user’s information.
from propelauth_django_rest_framework import init_auth
auth = init_auth("YOUR_AUTH_URL", "YOUR_API_KEY")
@api_view(['GET'])
@permission_classes([auth.IsUserAuthenticated])
def whoami(request):
return HttpResponse(request.propelauth_user.user_id)
or you can use it in class-based views:
class WhoAmIView(APIView):
permission_classes = [auth.IsUserAuthenticated]
def get(self, request):
return HttpResponse(request.propelauth_user.user_id)
AllowAny
Similar to IsUserAuthenticated,
except if an access token is missing or invalid, the request is allowed to
continue, but request.propelauth_user
will be None
.
class OptionalUserView(APIView):
permission_classes = [auth.AllowAny]
def get(self, request):
if request.propelauth_user is None:
return HttpResponse("none")
return HttpResponse(request.propelauth_user.user_id)
request.propelauth_user
A per-request value that contains user information for the user making the request. It’s set by one of IsUserAuthenticated, AllowAny, or any organization checking like IsUserInOrg.
The id of the user
A dictionary of org ids to metadata about the org. Includes all orgs that the user is in
The original ID of the user, if the user was migrated from an external source
If someone on your team is impersonating another user, this will be set to the employee’s ID. By default, user impersonation is turned off and this will be None
The values of org_id_to_org_member_info
are OrgMemberInfo
’s, with the
following fields/functions:
The id of the org
The name of the org
The user’s role within the organization. See Roles and Permissions for more details.
Returns True if the user’s role within the organization matches the role
passed in
Returns True if the user’s role within the organization is at least the role
passed in. If the hierarchy of roles is Owner => Admin => Member, specifying “Admin” will return True for Admins and Owners, but False for Members.
Return True if the user has a specific permission. The users’ permissions are derived from their role within this organization.
Return True if the user has all the specified permissions. The users’ permissions are derived from their role within this organization.
IsUserInOrg
A function that returns a Django permission that will verify the request was made by a valid user that belongs to a specific organization.
A function that takes in the request and outputs the org_id to require the user to be a member of. If none is specified, it will check for a path param org_id by checking request.GET.get('org_id', '')
.
@api_view(['GET'])
@permission_classes([auth.IsUserInOrg()])
def org_membership(request):
message = f"You are in {request.propelauth_org.org_name}"
return HttpResponse(message)
Specifically, it will:
- Check that a valid access token was provided. If not, the request is rejected
with a
401
status code. - Set request.propelauth_user (scoped to the current request) with the user’s information.
- Find an id for an organization within the request. By default, it will check for a path parameter org_id.
- Check that the user is a member of that organization. If not, the request is
rejected with a
403
status code. - Set request.propelauth_org (scoped to the current request) with the organization’s information for this user.
request.propelauth_org
A per-request value that contains org information for the user making the request.
The id of the org
The name of the org
The user’s role within the organization. See Roles and Permissions for more details.
Returns True if the user’s role within the organization matches the role
passed in
Returns True if the user’s role within the organization is at least the role
passed in. If the hierarchy of roles is Owner => Admin => Member, specifying “Admin” will return True for Admins and Owners, but False for Members.
Return True if the user has a specific permission. The users’ permissions are derived from their role within this organization.
Return True if the user has all the specified permissions. The users’ permissions are derived from their role within this organization.
Roles and Permissions
A user has a Role within an organization. By default, the available roles are Owner, Admin, or Member, but these can be configured. These roles are also hierarchical, so Owner > Admin > Member.
Roles allow you to control what different users can do within your product. If
you want to check a user’s role, you can use auth.IsUserInOrgWithRole
or
auth.IsUserInOrgWithMinimumRole
.
## Assuming a Role structure of Owner => Admin => Member
@api_view(['GET'])
@permission_classes([auth.IsUserInOrgWithRole("Admin")])
def admin_only(request):
message = f"You are an Admin of {request.propelauth_org.org_name}"
return HttpResponse(message)
@api_view(['GET'])
@permission_classes([auth.IsUserInOrgWithMinimumRole("Admin")])
def admin_or_owner(request):
message = f"You are an Admin or Owner of {request.propelauth_org.org_name}"
return HttpResponse(message)
Permissions are arbitrary strings associated with a role. For example, can_view_billing, ProductA::CanCreate, and ReadOnly are all valid permissions. The PropelAuth dashboard allows you to set up these permissions.
You can use auth.IsUserInOrgWithPermission or auth.IsUserInOrgWithAllPermissions to check for a given permission.
@api_view(['GET'])
@permission_classes([auth.IsUserInOrgWithPermission("can_view_billing")])
def billing_req(request):
pass
All of these functions, just like IsUserInOrg, will also take in req_to_org_id, and will set both request.propelauth_user and request.propelauth_org on a valid request.
Fetching functions
Fetch user metadata by id
# auth object comes from init_base_auth
auth.fetch_user_metadata_by_user_id(user_id, include_orgs=False)
Parameters
The id of the user
Whether to return an org_id_to_org_info object
Successful response:
{
"user_id": "e9d3520f-836e-403c-82c2-09843517e1ce",
"email": "user@example.com",
"email_confirmed": true,
"has_password": true,
"username": "example",
"first_name": "first",
"last_name": "last",
"picture_url": "https://...",
// True if the user's account is locked for security purposes.
"locked": false,
"enabled": true,
"mfa_enabled": false,
"created_at": 1645131680,
"last_active_at": 1650654711,
// Only returned if include_orgs = true
"org_id_to_org_info": {
"2ef0e1fc-234f-4dc0-a50c-35adb1bbb7e4": {
"org_id": "2ef0e1fc-234f-4dc0-a50c-35adb1bbb7e4",
"org_name": "ExampleOrganization",
"user_role": "Owner"
}
},
// Only returned if user was migrated from an external system
"legacy_user_id": "507f191e810c19729de860ea"
}
Fetch user metadata by email
# auth object comes from init_base_auth
auth.fetch_user_metadata_by_email(email, include_orgs=False)
The email of the user
Whether to return an org_id_to_org_info object
Successful response is the same as fetch_user_metadata_by_user_id, expect it takes an email as an argument.
Fetch user metadata by username
# auth object comes from init_base_auth
auth.fetch_user_metadata_by_username(email, include_orgs=False)
The username of the user
Whether to return an org_id_to_org_info object
Successful response is the same as fetch_user_metadata_by_user_id, expect it takes a username as an argument.
Batch fetch users by ids
# auth object comes from init_base_auth
user_id_to_metadata = auth.fetch_batch_user_metadata_by_user_ids([
"1be238f3-5908-4c51-b3bf-e53dd763047e",
"beb00acf-6e48-435d-8388-3758607ec01b",
"941c99e5-3530-4475-bd0f-bbc5d06603c3"
], include_orgs=False)
List of user_ids
Whether to return an org_id_to_org_info object
Any IDs that don’t have a match are not returned. Duplicate users are only returned once.
user_id_to_metadata
will store a dictionary response mapped to the ‘user_ids’ you pass in, as shown below:
{
"1be238f3-5908-4c51-b3bf-e53dd763047e": {
"user_id": "e9d3520f-836e-403c-82c2-09843517e1ce",
"email": "user@example.com",
"email_confirmed": true,
"has_password": true,
"username": "example",
"first_name": "first",
"last_name": "last",
"picture_url": "https://...",
// True if the user's account is locked for security purposes.
"locked": false,
"enabled": true,
"mfa_enabled": false,
"created_at": 1645131680,
"last_active_at": 1650654711,
// Only returned if include_orgs = true
"org_id_to_org_info": {
"2ef0e1fc-234f-4dc0-a50c-35adb1bbb7e4": {
"org_id": "2ef0e1fc-234f-4dc0-a50c-35adb1bbb7e4",
"org_name": "ExampleOrganization",
"user_role": "Owner",
}
},
// Only returned if user was migrated from an external system
"legacy_user_id": "507f191e810c19729de860ea"
},
"beb00acf-6e48-435d-8388-3758607ec01b": {
//...
}
}
Batch fetch users by emails
# auth object comes from init_base_auth
auth.fetch_batch_user_metadata_by_emails(["a@example.com", "b@example.com"], include_orgs=True)
List of user emails
Whether to return an org_id_to_org_info object
Successful response is the same as Batch fetch users by ids, but the keys are matching email addresses.
Batch fetch users by usernames
# auth object comes from init_base_auth
auth.fetch_batch_user_metadata_by_usernames(["usera", "userb", "userc"], include_orgs=True)
List of usernames
Whether to return an org_id_to_org_info object
Successful response is the same as Batch fetch users by ids, but the keys are matching usernames.
Search for users
# auth object comes from init_base_auth
auth.fetch_users_by_query(page_size=10, page_number=0, order_by=UserQueryOrderBy.CREATED_AT_ASC,
email_or_username=None, include_orgs=False)
The number of results to return at a time. Must be between 1 and 100, default 10.
Used to page over results
How to order the results. Must be one of: CREATED_AT_ASC, CREATED_AT_DESC, LAST_ACTIVE_AT_ASC, LAST_ACTIVE_AT_DESC, EMAIL, USERNAME
Searches for partial matches within email addresses or usernames. port would match a user with email address support@propelauth.com.
Whether to return an org_id_to_org_info object
Successful response:
{
"total_users": 103,
"current_page": 0,
"page_size": 10,
"has_more_results": true,
"users": [{
// See (1) for example users
}, {
// There will be 10 users in this response
}]
}
Fetch users in organization
# auth object comes from init_base_auth
auth.fetch_users_in_org(org_id, page_size=10, page_number=0, include_orgs=False)
The organization to fetch users for
The number of results to return at a time. Must be between 1 and 100, default 10.
Used to page over results
Whether to return an org_id_to_org_info object
Successful response:
{
"total_users": 43,
"current_page": 0,
"page_size": 10,
"has_more_results": true,
"users": [{
// See (1) for example users
}, {
// There will be 10 users in this response, all in the specified organization
}]
}
Fetch an organization
# auth object comes from init_base_auth
org = auth.fetch_org(org_id)
The organization to fetch users for
Successful response:
{
"org_id": "d488996d-8ccc-4101-b5f2-131f5f09ddb6"
"name": "OneOfYourCustomers"
}
Fetch all organizations
# auth object comes from init_base_auth
auth.fetch_org_by_query(page_size=10, page_number=0, order_by=OrgQueryOrderBy.CREATED_AT_ASC)
The number of results to return at a time. Must be between 1 and 100, default 10.
Used to page over results
How to order the results. Must be one of: CREATED_AT_ASC, CREATED_AT_DESC, LAST_ACTIVE_AT_ASC, LAST_ACTIVE_AT_DESC, EMAIL, USERNAME
Successful response:
{
"total_orgs": 21,
"current_page": 0,
"page_size": 10,
"has_more_results": true,
"orgs": [{
"org_id": "d488996d-8ccc-4101-b5f2-131f5f09ddb6",
"name": "OneOfYourCustomers"
}, {
// There will be 10 orgs in this response
}]
}
User Management
Create User
# auth object comes from init_base_auth
auth.create_user(email, email_confirmed=False, send_email_to_confirm_email_address=True,
ask_user_to_update_password_on_login=False,
password=None, username=None, first_name=None, last_name=None)
The user’s email address
Whether the email address should start off as already confirmed. If false, the user is required to confirm the email address before they sign in.
Whether we should send an email immediately to confirm the user’s email address. If false, the user will get a confirmation email when they first sign in.
Whether we should require the user to set or update their password on initial login. Default false
Optional password. If unset, the user can set it themselves via their account page
Optional username. Can only be used if username is enabled in your user schema
Optional first name. Can only be used if name is enabled in your user schema
Optional last name. Can only be used if name is enabled in your user schema
Successful response:
{
"user_id": "b5f667fb-e51a-49c6-a396-711e62948689"
}
Update User Email
# auth object comes from init_base_auth
# Returns true if it was successful, false if the user was not found
auth.update_user_email(user_id, new_email, require_email_confirmation)
The id of the user
New email address for this user
Whether the new email address requires confirmation. If true, an email will be sent to the new email address to confirm. If false, the users email address will be updated and confirmed immediately.
Update User Metadata
# auth object comes from init_base_auth
# Returns true if it was successful, false if the user was not found
auth.update_user_metadata(user_id, username=None, first_name=None, last_name=None, metadata=None)
The id of the user
Optional username. Can only be used if username is enabled in your user schema
Optional first name. Can only be used if name is enabled in your user schema
Optional last name. Can only be used if name is enabled in your user schema
Optional custom metadata dictionary.
Update User Password
# auth object comes from init_base_auth
# Returns true if it was successful, false if the user was not found
auth.update_user_password(user_id, password, ask_user_to_update_password_on_login=False)
The id of the user
The id of the user
(Optional) Whether we should require the user to set or update their password the next time they visit your product. Default false
Delete user
# auth object comes from init_base_auth
# Returns true if it was successful, false if the user was not found
auth.delete_user(user_id)
The id of the user
Disable user
If successful, the user is logged out and unable to log back in.
# auth object comes from init_base_auth
# Returns true if it was successful, false if the user was not found
auth.disable_user(user_id)
The id of the user
Enable user
If successful, the user is able to log back in again.
# auth object comes from init_base_auth
# Returns true if it was successful, false if the user was not found
auth.enable_user(user_id)
The id of the user
Migrate User from External Source
A similar function to Create User, but for cases where you already have a user stored in an external system. You can, for example, pass in a password hash for an existing user, and they will be able to login with their same password. It is also possible to provide an existing identifier, and we will store and return it along with our future identifiers, allowing you to link them.
# auth object comes from init_base_auth
auth.migrate_user_from_external_source(email, email_confirmed,
existing_user_id=None, existing_password_hash=None,
existing_mfa_base32_encoded_secret=None,
ask_user_to_update_password_on_login=False,
enabled=None, first_name=None, last_name=None, username=None)
The user’s email address
Whether the email address should start off as already confirmed. If false, the user is required to confirm the email address before they sign in.
(Optional) The user’s ID in the existing system. This ID will be stored on the user as a legacy_user_id
and it is present everywhere user_id’s are (e.g. fetching user metadata or validating a user’s token).
(Optional) The user’s hashed password. We support both bcrypt and argon2 password hashes.
(Optional) The user’s MFA secret, base32 encoded. If specified the user will have MFA enabled by default.
(Optional) Whether we should require the user to set or update their password on initial login. Default false
(Optional) Whether or not the user can login
Optional username. Can only be used if username is enabled in your user schema
Optional first name. Can only be used if name is enabled in your user schema
Optional last name. Can only be used if name is enabled in your user schema
Successful response:
{
"user_id": "b5f667fb-e51a-49c6-a396-711e62948689"
}
Create magic link
Creates a magic link that a user can use to log in. Use this API if you’d prefer to send the magic link to the customer yourself, otherwise, we have Create User which will email them directly.
# auth object comes from init_base_auth
auth.create_magic_link(email, redirect_to_url=None, expires_in_hours=None, create_new_user_if_one_doesnt_exist=None)
Argument | Description |
---|---|
The user’s email address | |
redirect_to_url | (Optional) Where to redirect the user after they login. If unspecified, will use the login redirect path specified in your dashboard. |
expires_in_hours | (Optional) How many hours should the link be valid for? |
create_new_user_if_one_doesnt_exist | (Optional) If true, this will create a new user if one matching the provided email address doesn’t exist. If false, the request will fail if no user with that email exists. Default is true. |
The user’s email address
(Optional) Where to redirect the user after they login. If unspecified, will use the login redirect path specified in your dashboard.
(Optional) How many hours should the link be valid for?
(Optional) If true, this will create a new user if one matching the provided email address doesn’t exist. If false, the request will fail if no user with that email exists. Default is true.
Successful response:
{
"url": "https://auth.yourdomain.com/..."
}
Create Access Token
Our frontend libraries allow you to get access tokens that can be sent to the backend. The backend is then responsible for verifying these tokens.
For testing purposes, you may want to create access tokens separately from the frontend and set a custom expiration time. With this API, you can create access tokens for users programmatically and set a custom expiration.
# auth object comes from init_base_auth
auth.create_access_token(user_id, duration_in_minutes)
The id of the user
How long the token is valid for, in minutes.
Successful response:
{
"access_token": "..."
}
Org Management
Create Organization
# auth object comes from init_base_auth
auth.create_org(name)
The organization’s name
Successful response:
{
"org_id": "d488996d-8ccc-4101-b5f2-131f5f09ddb6"
}
Add user to organization
# auth object comes from init_base_auth
auth.add_user_to_org(user_id, org_id, role)
The id of the user
The org’s ID
The role of the user in that organization, e.g. Admin
Successful response:
{}
Allow organization to set up SAML connection
# auth object comes from init_base_auth
auth.allow_org_to_setup_saml_connection(org_id)
The org’s ID
Returns True if successful, meaning the organization can now set up SAML connections.
Disallow organization to set up SAML connection
# auth object comes from init_base_auth
auth.disallow_org_to_setup_saml_connection(org_id)
The org’s ID
Returns True if successful, meaning the organization can no longer set up SAML connections.
Update Organization Metadata
# auth object comes from init_base_auth
# Returns true if it was successful, false if the organization was not found
auth.update_org_metadata(org_id, name=None, can_setup_saml=None, metadata=None)
Optional organization name. Updates the name of the organization.
Optional boolean. If enabled this organization has access to setup SAML connections via our hosted UI’s.
Optional custom metadata dictionary.