mirror of
https://github.com/goauthentik/authentik
synced 2026-04-26 01:25:02 +02:00
* Reorganize policy documentation * website/docs: address policy docs review feedback * post-rebase * website/docs: Reorganize policy documentation -- Revisions (#21601) * apply suggestions --------- Co-authored-by: Teffen Ellis <592134+GirlBossRush@users.noreply.github.com>
269 lines
8.9 KiB
Plaintext
269 lines
8.9 KiB
Plaintext
### `regex_match(value: Any, regex: str) -> bool`
|
|
|
|
Check if `value` matches Regular Expression `regex`.
|
|
|
|
Example:
|
|
|
|
```python
|
|
return regex_match(request.user.username, '.*admin.*')
|
|
```
|
|
|
|
### `regex_replace(value: Any, regex: str, repl: str) -> str`
|
|
|
|
Replace anything matching `regex` within `value` with `repl` and return it.
|
|
|
|
Example:
|
|
|
|
```python
|
|
user_email_local = regex_replace(request.user.email, '(.+)@.+', '')
|
|
```
|
|
|
|
### `list_flatten(value: list[Any] | Any) -> Optional[Any]`
|
|
|
|
Flatten a list by either returning its first element, None if the list is empty, or the passed in object if it's not a list.
|
|
|
|
Example:
|
|
|
|
```python
|
|
user = list_flatten(["foo"])
|
|
# user = "foo"
|
|
```
|
|
|
|
### `ak_call_policy(name: str, **kwargs) -> PolicyResult`
|
|
|
|
Call another policy with the name _name_. The current request is passed to the policy. Keyword arguments
|
|
can be used to modify the request's context.
|
|
|
|
Example:
|
|
|
|
```python
|
|
result = ak_call_policy("test-policy")
|
|
# result is a PolicyResult object, so you can access `.passing` and `.messages`.
|
|
# Starting with authentik 2023.4, you can also access `.raw_result`, which is the raw value returned from the called policy
|
|
# `result.passing` will always be a boolean if the policy is passing or not.
|
|
return result.passing
|
|
|
|
result = ak_call_policy("test-policy-2", foo="bar")
|
|
# Inside the `test-policy-2` you can then use `request.context["foo"]`
|
|
return result.passing
|
|
```
|
|
|
|
### `ak_is_group_member(user: User, **group_filters) -> bool`
|
|
|
|
Check if `user` is member of a group matching `**group_filters`.
|
|
|
|
Example:
|
|
|
|
```python
|
|
return ak_is_group_member(request.user, name="test_group")
|
|
```
|
|
|
|
### `ak_user_by(**filters) -> Optional[User]`
|
|
|
|
Fetch a user matching `**filters`.
|
|
|
|
Returns `None` if no user was found; otherwise, returns the [User](../../users-sources/user/index.mdx) object.
|
|
|
|
Example:
|
|
|
|
```python
|
|
# Find user by username
|
|
other_user = ak_user_by(username="other_user")
|
|
|
|
# Find user by custom attribute
|
|
other_user = ak_user_by(attributes__<custom_attribute_name>="<value>")
|
|
```
|
|
|
|
### `ak_user_has_authenticator(user: User, device_type: Optional[str] = None) -> bool`
|
|
|
|
Check if a user has any authenticator devices. Only fully validated devices are counted.
|
|
|
|
Optionally, you can filter by a specific device type. The following options are valid:
|
|
|
|
- `totp`
|
|
- `duo`
|
|
- `static`
|
|
- `webauthn`
|
|
|
|
Example:
|
|
|
|
```python
|
|
return ak_user_has_authenticator(request.user)
|
|
```
|
|
|
|
### `ak_create_event(action: str, **kwargs) -> None`
|
|
|
|
Create a new event with the action set to `action`. Any additional keyword parameters will be saved in the event context. Additionally, `context` will be set to the context in which this function is called.
|
|
|
|
Before saving, any data structures which are not representable in JSON are flattened, and credentials are removed.
|
|
|
|
The event is saved automatically.
|
|
|
|
Example:
|
|
|
|
```python
|
|
ak_create_event("my_custom_event", foo=request.user)
|
|
```
|
|
|
|
### `ak_create_jwt(user: User, provider: OAuth2Provider | str, scopes: list[str], validity = "seconds=60") -> str | None`:ak-version[2025.2]
|
|
|
|
:::info Requires HTTP Request
|
|
This function will only work when there is an HTTP request in the current context.
|
|
:::
|
|
|
|
Create a new JWT signed by the given `provider` for `user`.
|
|
|
|
The `provider` parameter can either be an instance of `OAuth2Provider` or the name of a provider instance as a string. Scopes are an array of all scopes that the JWT should have.
|
|
|
|
The JWT is valid for 60 seconds by default, and this can be customized using the `validity` parameter. The syntax of the parameter is `hours=1,minutes=2,seconds=3`. The following keys are allowed:
|
|
|
|
- Microseconds
|
|
- Milliseconds
|
|
- Seconds
|
|
- Minutes
|
|
- Hours
|
|
- Days
|
|
- Weeks
|
|
|
|
All values accept floating-point values.
|
|
|
|
Example:
|
|
|
|
```python
|
|
jwt = ak_create_jwt(request.user, "my-oauth2-provider-name", ["openid", "profile", "email"])
|
|
```
|
|
|
|
### `ak_create_jwt_raw(provider: OAuth2Provider | str, validity = "seconds=60", **kwargs) -> str | None`:ak-version[2025.12]
|
|
|
|
Similar to [`ak_create_jwt`](#ak_create_jwtuser-user-provider-oauth2provider--str-scopes-liststr-validity--seconds60---str--none), however this function does _not_ require an HTTP request and allows for setting custom claims via `**kwargs`.
|
|
|
|
The `provider` parameter can either be an instance of `OAuth2Provider` or the name of a provider instance as a string. Scopes are an array of all scopes that the JWT should have.
|
|
|
|
The JWT is valid for 60 seconds by default, and this can be customized using the `validity` parameter. The syntax of the parameter is `hours=1,minutes=2,seconds=3`. The following keys are allowed:
|
|
|
|
- Microseconds
|
|
- Milliseconds
|
|
- Seconds
|
|
- Minutes
|
|
- Hours
|
|
- Days
|
|
- Weeks
|
|
|
|
All values accept floating-point values.
|
|
|
|
Example:
|
|
|
|
```python
|
|
jwt = ak_create_jwt_raw("my-oauth2-provider-name", my_claim="my_value")
|
|
```
|
|
|
|
### `ak_send_email(address: str | list[str], subject: str, body: str = None, stage: EmailStage = None, template: str = None, context: dict = None, cc: str | list[str] = None, bcc: str | list[str] = None) -> bool`:ak-version[2025.10]
|
|
|
|
Send an email using authentik's email system.
|
|
|
|
The `address` parameter specifies the recipient email address(es). It can be:
|
|
|
|
- A single email address as a string: `"user@example.com"`
|
|
- A list of email addresses: `["user1@example.com", "user2@example.com"]`
|
|
|
|
:::info
|
|
When using multiple recipients in the `address` or `cc` fields, all email addresses will be visible to all recipients. Use `bcc` to send to multiple recipients without revealing addresses to each other.
|
|
:::
|
|
|
|
The `subject` parameter sets the email subject line.
|
|
|
|
You must provide either `body` (for plain text/HTML content) or `template` (for template rendering), but not both.
|
|
|
|
The `stage` parameter can be an `EmailStage` instance for custom email settings. If `None`, global email settings are used.
|
|
|
|
The `template` parameter specifies a template name to render. When using templates, you can pass additional context variables via the `context` parameter.
|
|
|
|
The `cc` parameter specifies email address(es) to carbon copy. Same format as `address`.
|
|
|
|
The `bcc` parameter specifies email address(es) to blind carbon copy. Same format as `address`. Recipients in `bcc` will not be visible to other recipients.
|
|
|
|
If the email is queued successfully, the function returns `True`; otherwise, it returns `False`.
|
|
|
|
Examples:
|
|
|
|
```python
|
|
# Send email with plain body to single recipient
|
|
ak_send_email("user@example.com", "Welcome!", body="Welcome to our platform!")
|
|
|
|
# Send email to multiple recipients
|
|
ak_send_email(
|
|
["user1@example.com", "user2@example.com", "admin@example.com"],
|
|
"System Maintenance",
|
|
body="Scheduled maintenance will occur tonight."
|
|
)
|
|
|
|
# Send email using a template
|
|
ak_send_email("user@example.com", "Password Reset", template="email/password_reset.html")
|
|
|
|
# Send email with custom context for template to multiple recipients
|
|
ak_send_email(
|
|
["user@example.com", "admin@example.com"],
|
|
"Account Update",
|
|
template="email/event_notification.html",
|
|
context={
|
|
"title": "Profile Updated",
|
|
"body": "Your account profile has been successfully updated.",
|
|
"key_value": {"Updated Field": "Email Address", "Date": "2025-01-01"}
|
|
}
|
|
)
|
|
|
|
# Send email with custom email stage
|
|
ak_send_email("admin@example.com", "Report", body="Daily report", stage=my_custom_stage)
|
|
|
|
# Send email with CC
|
|
ak_send_email(
|
|
"user@example.com",
|
|
"Important Update",
|
|
body="Please review this update.",
|
|
cc="manager@example.com"
|
|
)
|
|
|
|
# Send email with multiple CC and BCC recipients
|
|
ak_send_email(
|
|
"user@example.com",
|
|
"Confidential Report",
|
|
body="Attached is the quarterly report.",
|
|
cc=["manager@example.com", "lead@example.com"],
|
|
bcc=["audit@example.com", "compliance@example.com"]
|
|
)
|
|
```
|
|
|
|
## Comparing IP Addresses
|
|
|
|
To compare IP addresses or check if an IP address is within a given subnet, you can use the functions `ip_address('192.0.2.1')` and `ip_network('192.0.2.0/24')`. With these objects you can do [arithmetic operations](https://docs.python.org/3/library/ipaddress.html#operators).
|
|
|
|
You can also check if an IP Address is within a subnet by writing the following:
|
|
|
|
```python
|
|
ip_address('192.0.2.1') in ip_network('192.0.2.0/24')
|
|
# evaluates to True
|
|
```
|
|
|
|
## DNS resolution and reverse DNS lookups
|
|
|
|
To resolve a hostname to a list of IP addresses, use the functions `resolve_dns(hostname)` and `resolve_dns(hostname, ip_version)`.
|
|
|
|
```python
|
|
resolve_dns("google.com") # returns a list of all IPv4 and IPv6 addresses
|
|
resolve_dns("google.com", 4) # returns a list of only IPv4 addresses
|
|
resolve_dns("google.com", 6) # returns a list of only IPv6 addresses
|
|
```
|
|
|
|
You can also perform reverse DNS lookups.
|
|
|
|
:::note
|
|
Reverse DNS lookups may not return the expected host if the IP address is part of a shared hosting environment.
|
|
See: https://stackoverflow.com/a/19867936
|
|
:::
|
|
|
|
To perform a reverse DNS lookup use `reverse_dns("192.0.2.0")`. If no DNS records are found the original IP address is returned.
|
|
|
|
:::info
|
|
DNS resolving results are cached in memory. The last 32 unique queries are cached for up to 3 minutes.
|
|
:::
|