website/docs: improve docs for expressions
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
6232333a52
commit
a4c28a28b4
|
@ -26,8 +26,8 @@ class BaseEvaluator:
|
||||||
_filename: str
|
_filename: str
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# update authentik/policies/expression/templates/policy/expression/form.html
|
# update website/docs/expressions/_objects.md
|
||||||
# update website/docs/policies/expression.md
|
# update website/docs/expressions/_functions.md
|
||||||
self._globals = {
|
self._globals = {
|
||||||
"regex_match": BaseEvaluator.expr_filter_regex_match,
|
"regex_match": BaseEvaluator.expr_filter_regex_match,
|
||||||
"regex_replace": BaseEvaluator.expr_filter_regex_replace,
|
"regex_replace": BaseEvaluator.expr_filter_regex_replace,
|
||||||
|
|
|
@ -38,7 +38,8 @@ class PolicyEvaluator(BaseEvaluator):
|
||||||
|
|
||||||
def set_policy_request(self, request: PolicyRequest):
|
def set_policy_request(self, request: PolicyRequest):
|
||||||
"""Update context based on policy request (if http request is given, update that too)"""
|
"""Update context based on policy request (if http request is given, update that too)"""
|
||||||
# update website/docs/policies/expression.md
|
# update website/docs/expressions/_objects.md
|
||||||
|
# update website/docs/expressions/_functions.md
|
||||||
self._context["ak_is_sso_flow"] = request.context.get(PLAN_CONTEXT_SSO, False)
|
self._context["ak_is_sso_flow"] = request.context.get(PLAN_CONTEXT_SSO, False)
|
||||||
if request.http_request:
|
if request.http_request:
|
||||||
self.set_http_request(request.http_request)
|
self.set_http_request(request.http_request)
|
||||||
|
@ -47,7 +48,8 @@ class PolicyEvaluator(BaseEvaluator):
|
||||||
|
|
||||||
def set_http_request(self, request: HttpRequest):
|
def set_http_request(self, request: HttpRequest):
|
||||||
"""Update context based on http request"""
|
"""Update context based on http request"""
|
||||||
# update website/docs/policies/expression.md
|
# update website/docs/expressions/_objects.md
|
||||||
|
# update website/docs/expressions/_functions.md
|
||||||
self._context["ak_client_ip"] = ip_address(
|
self._context["ak_client_ip"] = ip_address(
|
||||||
get_client_ip(request) or "255.255.255.255"
|
get_client_ip(request) or "255.255.255.255"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,22 +1,3 @@
|
||||||
---
|
|
||||||
title: Expressions
|
|
||||||
---
|
|
||||||
|
|
||||||
Expressions allow you to write custom logic using Python code.
|
|
||||||
|
|
||||||
Expressions are used in different places throughout authentik, and can do different things.
|
|
||||||
|
|
||||||
:::info
|
|
||||||
These functions/objects are available wherever expressions are used. For more specific information, see [Expression Policies](../policies/expression.md) and [Property Mappings](../property-mappings/expression.md)
|
|
||||||
:::
|
|
||||||
|
|
||||||
## Global objects
|
|
||||||
|
|
||||||
- `ak_logger`: structlog BoundLogger. ([ref](https://www.structlog.org/en/stable/api.html#structlog.BoundLogger))
|
|
||||||
- `requests`: requests Session object. ([ref](https://requests.readthedocs.io/en/master/user/advanced/))
|
|
||||||
|
|
||||||
## Generally available functions
|
|
||||||
|
|
||||||
### `regex_match(value: Any, regex: str) -> bool`
|
### `regex_match(value: Any, regex: str) -> bool`
|
||||||
|
|
||||||
Check if `value` matches Regular Expression `regex`.
|
Check if `value` matches Regular Expression `regex`.
|
||||||
|
@ -49,7 +30,9 @@ return ak_is_group_member(request.user, name="test_group")
|
||||||
|
|
||||||
### `ak_user_by(**filters) -> Optional[User]`
|
### `ak_user_by(**filters) -> Optional[User]`
|
||||||
|
|
||||||
Fetch a user matching `**filters`. Returns "None" if no user was found.
|
Fetch a user matching `**filters`.
|
||||||
|
|
||||||
|
Returns "None" if no user was found, otherwise [User](/docs/expressions/reference/user-object)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
- `ak_logger`: structlog BoundLogger. See ([structlog documentation](https://www.structlog.org/en/stable/api.html#structlog.BoundLogger))
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```python
|
||||||
|
ak_logger.debug("This is a test message")
|
||||||
|
ak_logger.warning("This will be logged with a warning level")
|
||||||
|
ak_logger.info("Passing structured data", request=request)
|
||||||
|
```
|
||||||
|
|
||||||
|
- `requests`: requests Session object. See ([request documentation](https://requests.readthedocs.io/en/master/user/advanced/))
|
|
@ -15,9 +15,16 @@ The User object has the following attributes:
|
||||||
- `group_attributes` Merged attributes of all groups the user is member of and the user's own attributes.
|
- `group_attributes` Merged attributes of all groups the user is member of and the user's own attributes.
|
||||||
- `ak_groups` This is a queryset of all the user's groups.
|
- `ak_groups` This is a queryset of all the user's groups.
|
||||||
|
|
||||||
You can do additional filtering like `user.ak_groups.filter(name__startswith='test')`, see [here](https://docs.djangoproject.com/en/3.1/ref/models/querysets/#id4)
|
You can do additional filtering like
|
||||||
|
```python
|
||||||
|
user.ak_groups.filter(name__startswith='test')
|
||||||
|
```
|
||||||
|
see [here](https://docs.djangoproject.com/en/3.1/ref/models/querysets/#id4)
|
||||||
|
|
||||||
To get the name of all groups, you can do `[group.name for group in user.ak_groups.all()]`
|
To get the name of all groups, you can do
|
||||||
|
```python
|
||||||
|
[group.name for group in user.ak_groups.all()]
|
||||||
|
```
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,12 @@ title: Flows
|
||||||
|
|
||||||
Flows are a method of describing a sequence of stages. A stage represents a single verification or logic step. They are used to authenticate users, enroll them, and more.
|
Flows are a method of describing a sequence of stages. A stage represents a single verification or logic step. They are used to authenticate users, enroll them, and more.
|
||||||
|
|
||||||
|
For example, a standard login flow would consist of the following stages:
|
||||||
|
|
||||||
|
- Identification, user identifies themselves via a username or email address
|
||||||
|
- Password, the user's password is checked against the hash in the database
|
||||||
|
- Log the user in
|
||||||
|
|
||||||
Upon flow execution, a plan containing all stages is generated. This means that all attached policies are evaluated upon execution. This behaviour can be altered by enabling the **Re-evaluate Policies** option on the binding.
|
Upon flow execution, a plan containing all stages is generated. This means that all attached policies are evaluated upon execution. This behaviour can be altered by enabling the **Re-evaluate Policies** option on the binding.
|
||||||
|
|
||||||
To determine which flow is linked, authentik searches all flows with the required designation and chooses the first instance the current user has access to.
|
To determine which flow is linked, authentik searches all flows with the required designation and chooses the first instance the current user has access to.
|
||||||
|
|
|
@ -2,15 +2,19 @@
|
||||||
title: Expression Policies
|
title: Expression Policies
|
||||||
---
|
---
|
||||||
|
|
||||||
:::note
|
The passing of the policy is determined by the return value of the code. Use
|
||||||
These variables are available in addition to the common variables/functions defined in [**Expressions**](../expressions/index.md)
|
```python
|
||||||
:::
|
return True
|
||||||
|
```
|
||||||
|
to pass a policy and
|
||||||
|
```python
|
||||||
|
return False
|
||||||
|
```
|
||||||
|
to fail it.
|
||||||
|
|
||||||
The passing of the policy is determined by the return value of the code. Use `return True` to pass a policy and `return False` to fail it.
|
## Available Functions
|
||||||
|
|
||||||
### Available Functions
|
### `ak_message(message: str)`
|
||||||
|
|
||||||
#### `ak_message(message: str)`
|
|
||||||
|
|
||||||
Add a message, visible by the end user. This can be used to show the reason why they were denied.
|
Add a message, visible by the end user. This can be used to show the reason why they were denied.
|
||||||
|
|
||||||
|
@ -21,16 +25,24 @@ ak_message("Access denied")
|
||||||
return False
|
return False
|
||||||
```
|
```
|
||||||
|
|
||||||
### Context variables
|
import Functions from '../expressions/_functions.md'
|
||||||
|
|
||||||
|
<Functions />
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
import Objects from '../expressions/_objects.md'
|
||||||
|
|
||||||
|
<Objects />
|
||||||
|
|
||||||
- `request`: A PolicyRequest object, which has the following properties:
|
- `request`: A PolicyRequest object, which has the following properties:
|
||||||
- `request.user`: ([ref](../expressions/reference/user-object.md)) The current user, against which the policy is applied.
|
- `request.user`: The current user, against which the policy is applied. See [User](../expressions/reference/user-object.md)
|
||||||
- `request.http_request`: ([ref](https://docs.djangoproject.com/en/3.0/ref/request-response/#httprequest-objects)) The Django HTTP Request.
|
- `request.http_request`: The Django HTTP Request. See ([Django documentation](https://docs.djangoproject.com/en/3.0/ref/request-response/#httprequest-objects))
|
||||||
- `request.obj`: A Django Model instance. This is only set if the policy is ran against an object.
|
- `request.obj`: A Django Model instance. This is only set if the policy is ran against an object.
|
||||||
- `request.context`: A dictionary with dynamic data. This depends on the origin of the execution.
|
- `request.context`: A dictionary with dynamic data. This depends on the origin of the execution.
|
||||||
- `geoip`: ([ref](https://geoip2.readthedocs.io/en/latest/#geoip2.models.City)) GeoIP object, which is added when GeoIP is enabled.
|
- `geoip`: GeoIP object, which is added when GeoIP is enabled. See [GeoIP](https://geoip2.readthedocs.io/en/latest/#geoip2.models.City)
|
||||||
- `ak_is_sso_flow`: Boolean which is true if request was initiated by authenticating through an external provider.
|
- `ak_is_sso_flow`: Boolean which is true if request was initiated by authenticating through an external provider.
|
||||||
- `ak_client_ip`: ([ref](https://docs.python.org/3/library/ipaddress.html#ipaddress.ip_address)) Client's IP Address or 255.255.255.255 if no IP Address could be extracted. Can be [compared](../expressions/index.md#comparing-ip-addresses), for example
|
- `ak_client_ip`: Client's IP Address or 255.255.255.255 if no IP Address could be extracted. Can be [compared](../expressions/index.md#comparing-ip-addresses), for example
|
||||||
|
|
||||||
```python
|
```python
|
||||||
return ak_client_ip in ip_network('10.0.0.0/24')
|
return ak_client_ip in ip_network('10.0.0.0/24')
|
||||||
|
@ -38,10 +50,12 @@ return False
|
||||||
return ak_client_ip.is_private
|
return ak_client_ip.is_private
|
||||||
```
|
```
|
||||||
|
|
||||||
|
See also [Python documetnation](https://docs.python.org/3/library/ipaddress.html#ipaddress.ip_address)
|
||||||
|
|
||||||
Additionally, when the policy is executed from a flow, every variable from the flow's current context is accessible under the `context` object.
|
Additionally, when the policy is executed from a flow, every variable from the flow's current context is accessible under the `context` object.
|
||||||
|
|
||||||
This includes the following:
|
This includes the following:
|
||||||
|
|
||||||
- `prompt_data`: Data which has been saved from a prompt stage or an external source.
|
- `prompt_data`: Data which has been saved from a prompt stage or an external source.
|
||||||
- `application`: The application the user is in the process of authorizing.
|
- `application`: The application the user is in the process of authorizing.
|
||||||
- `pending_user`: The currently pending user
|
- `pending_user`: The currently pending user, see [User](/docs/expressions/reference/user-object)
|
|
@ -1,15 +1,22 @@
|
||||||
---
|
---
|
||||||
title: Property Mapping Expressions
|
title: Expressions
|
||||||
---
|
---
|
||||||
|
|
||||||
The property mapping should return a value that is expected by the Provider/Source. Supported types are documented in the individual Provider/Source. Returning `None` is always accepted and would simply skip the mapping for which `None` was returned.
|
The property mapping should return a value that is expected by the Provider/Source. Supported types are documented in the individual Provider/Source. Returning `None` is always accepted and would simply skip the mapping for which `None` was returned.
|
||||||
|
|
||||||
:::note
|
|
||||||
These variables are available in addition to the common variables/functions defined in [**Expressions**](../expressions/index.md)
|
|
||||||
:::
|
|
||||||
|
|
||||||
### Context Variables
|
## Available Functions
|
||||||
|
|
||||||
- `user`: The current user. This may be `None` if there is no contextual user. ([ref](../expressions/reference/user-object.md))
|
import Functions from '../expressions/_functions.md'
|
||||||
- `request`: The current request. This may be `None` if there is no contextual request. ([ref](https://docs.djangoproject.com/en/3.0/ref/request-response/#httprequest-objects))
|
|
||||||
|
<Functions />
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
import Objects from '../expressions/_objects.md'
|
||||||
|
|
||||||
|
<Objects />
|
||||||
|
|
||||||
|
- `user`: The current user. This may be `None` if there is no contextual user. See ([User](../expressions/reference/user-object.md))
|
||||||
|
- `request`: The current request. This may be `None` if there is no contextual request. See ([Django documentation](https://docs.djangoproject.com/en/3.0/ref/request-response/#httprequest-objects))
|
||||||
- Other arbitrary arguments given by the provider, this is documented on the Provider/Source.
|
- Other arbitrary arguments given by the provider, this is documented on the Provider/Source.
|
|
@ -10,6 +10,18 @@ title: Next
|
||||||
|
|
||||||
Currently, only Duo push notifications are supported. Because no additional input is required, Duo also works with the LDAP Outpost.
|
Currently, only Duo push notifications are supported. Because no additional input is required, Duo also works with the LDAP Outpost.
|
||||||
|
|
||||||
|
- Multi-tenancy
|
||||||
|
|
||||||
|
This version adds soft multi-tenancy. This means you can configure different branding settings and different default flows per domain.
|
||||||
|
|
||||||
|
This also changes how a default flow is determined. Previously, for defaults flow, authentik would pick the first flow that
|
||||||
|
|
||||||
|
- matches the required designation
|
||||||
|
- comes first sorted by slug
|
||||||
|
- is allowed by policies
|
||||||
|
|
||||||
|
Now, authentik first checks if the current tenant has a default flow configured for the selected designation. If not, it behaves the same as before, meaning that if you want to select a default flow based on policy, you can just leave the tenant default empty.
|
||||||
|
|
||||||
## Minor changes
|
## Minor changes
|
||||||
|
|
||||||
- You can now specify which sources should be shown on an Identification stage.
|
- You can now specify which sources should be shown on an Identification stage.
|
||||||
|
|
|
@ -41,6 +41,40 @@ module.exports = {
|
||||||
"outposts/manual-deploy-kubernetes",
|
"outposts/manual-deploy-kubernetes",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: "category",
|
||||||
|
label: "Integrations",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
type: "category",
|
||||||
|
label: "as Source",
|
||||||
|
items: ["integrations/sources/active-directory/index"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "category",
|
||||||
|
label: "as Provider",
|
||||||
|
items: [
|
||||||
|
"integrations/services/apache-guacamole/index",
|
||||||
|
"integrations/services/aws/index",
|
||||||
|
"integrations/services/awx-tower/index",
|
||||||
|
"integrations/services/gitlab/index",
|
||||||
|
"integrations/services/grafana/index",
|
||||||
|
"integrations/services/harbor/index",
|
||||||
|
"integrations/services/home-assistant/index",
|
||||||
|
"integrations/services/minio/index",
|
||||||
|
"integrations/services/nextcloud/index",
|
||||||
|
"integrations/services/rancher/index",
|
||||||
|
"integrations/services/sentry/index",
|
||||||
|
"integrations/services/sonarr/index",
|
||||||
|
"integrations/services/tautulli/index",
|
||||||
|
"integrations/services/ubuntu-landscape/index",
|
||||||
|
"integrations/services/veeam-enterprise-manager/index",
|
||||||
|
"integrations/services/vmware-vcenter/index",
|
||||||
|
"integrations/services/wiki-js/index",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: "category",
|
type: "category",
|
||||||
label: "Flows",
|
label: "Flows",
|
||||||
|
@ -83,7 +117,6 @@ module.exports = {
|
||||||
type: "category",
|
type: "category",
|
||||||
label: "Expressions",
|
label: "Expressions",
|
||||||
items: [
|
items: [
|
||||||
"expressions/index",
|
|
||||||
{
|
{
|
||||||
type: "category",
|
type: "category",
|
||||||
label: "Reference",
|
label: "Reference",
|
||||||
|
@ -100,40 +133,6 @@ module.exports = {
|
||||||
"events/transports"
|
"events/transports"
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
type: "category",
|
|
||||||
label: "Integrations",
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
type: "category",
|
|
||||||
label: "as Source",
|
|
||||||
items: ["integrations/sources/active-directory/index"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "category",
|
|
||||||
label: "as Provider",
|
|
||||||
items: [
|
|
||||||
"integrations/services/apache-guacamole/index",
|
|
||||||
"integrations/services/aws/index",
|
|
||||||
"integrations/services/awx-tower/index",
|
|
||||||
"integrations/services/gitlab/index",
|
|
||||||
"integrations/services/grafana/index",
|
|
||||||
"integrations/services/harbor/index",
|
|
||||||
"integrations/services/home-assistant/index",
|
|
||||||
"integrations/services/minio/index",
|
|
||||||
"integrations/services/nextcloud/index",
|
|
||||||
"integrations/services/rancher/index",
|
|
||||||
"integrations/services/sentry/index",
|
|
||||||
"integrations/services/sonarr/index",
|
|
||||||
"integrations/services/tautulli/index",
|
|
||||||
"integrations/services/ubuntu-landscape/index",
|
|
||||||
"integrations/services/veeam-enterprise-manager/index",
|
|
||||||
"integrations/services/vmware-vcenter/index",
|
|
||||||
"integrations/services/wiki-js/index",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
type: "category",
|
type: "category",
|
||||||
label: "Maintenance",
|
label: "Maintenance",
|
||||||
|
|
Reference in New Issue