Compare commits
1 Commits
version/20
...
blueprints
Author | SHA1 | Date | |
---|---|---|---|
906c63c16f |
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@ -29,6 +29,7 @@
|
|||||||
"!Enumerate sequence",
|
"!Enumerate sequence",
|
||||||
"!Env scalar",
|
"!Env scalar",
|
||||||
"!Find sequence",
|
"!Find sequence",
|
||||||
|
"!FindObject sequence",
|
||||||
"!Format sequence",
|
"!Format sequence",
|
||||||
"!If sequence",
|
"!If sequence",
|
||||||
"!Index scalar",
|
"!Index scalar",
|
||||||
@ -51,7 +52,9 @@
|
|||||||
"ignoreCase": false
|
"ignoreCase": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"go.testFlags": ["-count=1"],
|
"go.testFlags": [
|
||||||
|
"-count=1"
|
||||||
|
],
|
||||||
"github-actions.workflows.pinned.workflows": [
|
"github-actions.workflows.pinned.workflows": [
|
||||||
".github/workflows/ci-main.yml"
|
".github/workflows/ci-main.yml"
|
||||||
]
|
]
|
||||||
|
@ -150,6 +150,7 @@ entries:
|
|||||||
at_index_sequence_default: !AtIndex [!Context sequence, 100, "non existent"]
|
at_index_sequence_default: !AtIndex [!Context sequence, 100, "non existent"]
|
||||||
at_index_mapping: !AtIndex [!Context mapping, "key2"]
|
at_index_mapping: !AtIndex [!Context mapping, "key2"]
|
||||||
at_index_mapping_default: !AtIndex [!Context mapping, "invalid", "non existent"]
|
at_index_mapping_default: !AtIndex [!Context mapping, "invalid", "non existent"]
|
||||||
|
find_object: !AtIndex [!FindObject [authentik_providers_oauth2.scopemapping, [scope_name, openid]], managed]
|
||||||
identifiers:
|
identifiers:
|
||||||
name: test
|
name: test
|
||||||
conditions:
|
conditions:
|
||||||
|
@ -4,6 +4,7 @@ from os import environ
|
|||||||
|
|
||||||
from django.test import TransactionTestCase
|
from django.test import TransactionTestCase
|
||||||
|
|
||||||
|
from authentik.blueprints.tests import apply_blueprint
|
||||||
from authentik.blueprints.v1.exporter import FlowExporter
|
from authentik.blueprints.v1.exporter import FlowExporter
|
||||||
from authentik.blueprints.v1.importer import Importer, transaction_rollback
|
from authentik.blueprints.v1.importer import Importer, transaction_rollback
|
||||||
from authentik.core.models import Group
|
from authentik.core.models import Group
|
||||||
@ -126,6 +127,7 @@ class TestBlueprintsV1(TransactionTestCase):
|
|||||||
|
|
||||||
self.assertEqual(Prompt.objects.filter(field_key="username").count(), count_before)
|
self.assertEqual(Prompt.objects.filter(field_key="username").count(), count_before)
|
||||||
|
|
||||||
|
@apply_blueprint("system/providers-oauth2.yaml")
|
||||||
def test_import_yaml_tags(self):
|
def test_import_yaml_tags(self):
|
||||||
"""Test some yaml tags"""
|
"""Test some yaml tags"""
|
||||||
ExpressionPolicy.objects.filter(name="foo-bar-baz-qux").delete()
|
ExpressionPolicy.objects.filter(name="foo-bar-baz-qux").delete()
|
||||||
@ -136,9 +138,11 @@ class TestBlueprintsV1(TransactionTestCase):
|
|||||||
self.assertTrue(importer.apply())
|
self.assertTrue(importer.apply())
|
||||||
policy = ExpressionPolicy.objects.filter(name="foo-bar-baz-qux").first()
|
policy = ExpressionPolicy.objects.filter(name="foo-bar-baz-qux").first()
|
||||||
self.assertTrue(policy)
|
self.assertTrue(policy)
|
||||||
self.assertTrue(
|
group = Group.objects.filter(name="test").first()
|
||||||
Group.objects.filter(
|
self.assertIsNotNone(group)
|
||||||
attributes={
|
self.assertEqual(
|
||||||
|
group.attributes,
|
||||||
|
{
|
||||||
"policy_pk1": str(policy.pk) + "-suffix",
|
"policy_pk1": str(policy.pk) + "-suffix",
|
||||||
"policy_pk2": str(policy.pk) + "-suffix",
|
"policy_pk2": str(policy.pk) + "-suffix",
|
||||||
"boolAnd": True,
|
"boolAnd": True,
|
||||||
@ -219,8 +223,8 @@ class TestBlueprintsV1(TransactionTestCase):
|
|||||||
"at_index_sequence_default": "non existent",
|
"at_index_sequence_default": "non existent",
|
||||||
"at_index_mapping": 2,
|
"at_index_mapping": 2,
|
||||||
"at_index_mapping_default": "non existent",
|
"at_index_mapping_default": "non existent",
|
||||||
}
|
"find_object": "goauthentik.io/providers/oauth2/scope-openid",
|
||||||
).exists()
|
},
|
||||||
)
|
)
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
OAuthSource.objects.filter(
|
OAuthSource.objects.filter(
|
||||||
|
@ -311,7 +311,7 @@ class Format(YAMLTag):
|
|||||||
|
|
||||||
|
|
||||||
class Find(YAMLTag):
|
class Find(YAMLTag):
|
||||||
"""Find any object"""
|
"""Find any object primary key"""
|
||||||
|
|
||||||
model_name: str | YAMLTag
|
model_name: str | YAMLTag
|
||||||
conditions: list[list]
|
conditions: list[list]
|
||||||
@ -326,7 +326,7 @@ class Find(YAMLTag):
|
|||||||
values.append(loader.construct_object(node_values))
|
values.append(loader.construct_object(node_values))
|
||||||
self.conditions.append(values)
|
self.conditions.append(values)
|
||||||
|
|
||||||
def resolve(self, entry: BlueprintEntry, blueprint: Blueprint) -> Any:
|
def _get_instance(self, entry: BlueprintEntry, blueprint: Blueprint) -> Any:
|
||||||
if isinstance(self.model_name, YAMLTag):
|
if isinstance(self.model_name, YAMLTag):
|
||||||
model_name = self.model_name.resolve(entry, blueprint)
|
model_name = self.model_name.resolve(entry, blueprint)
|
||||||
else:
|
else:
|
||||||
@ -348,12 +348,29 @@ class Find(YAMLTag):
|
|||||||
else:
|
else:
|
||||||
query_value = cond[1]
|
query_value = cond[1]
|
||||||
query &= Q(**{query_key: query_value})
|
query &= Q(**{query_key: query_value})
|
||||||
instance = model_class.objects.filter(query).first()
|
return model_class.objects.filter(query).first()
|
||||||
|
|
||||||
|
def resolve(self, entry: BlueprintEntry, blueprint: Blueprint) -> Any:
|
||||||
|
instance = self._get_instance(entry, blueprint)
|
||||||
if instance:
|
if instance:
|
||||||
return instance.pk
|
return instance.pk
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class FindObject(Find):
|
||||||
|
"""Find any object"""
|
||||||
|
|
||||||
|
def resolve(self, entry: BlueprintEntry, blueprint: Blueprint) -> Any:
|
||||||
|
instance = self._get_instance(entry, blueprint)
|
||||||
|
if not instance:
|
||||||
|
return None
|
||||||
|
if not isinstance(instance, SerializerModel):
|
||||||
|
raise EntryInvalidError.from_entry(
|
||||||
|
f"Model {self.model_name} is not resolvable through FindObject", entry
|
||||||
|
)
|
||||||
|
return instance.serializer(instance=instance).data
|
||||||
|
|
||||||
|
|
||||||
class Condition(YAMLTag):
|
class Condition(YAMLTag):
|
||||||
"""Convert all values to a single boolean"""
|
"""Convert all values to a single boolean"""
|
||||||
|
|
||||||
@ -649,6 +666,7 @@ class BlueprintLoader(SafeLoader):
|
|||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.add_constructor("!KeyOf", KeyOf)
|
self.add_constructor("!KeyOf", KeyOf)
|
||||||
self.add_constructor("!Find", Find)
|
self.add_constructor("!Find", Find)
|
||||||
|
self.add_constructor("!FindObject", FindObject)
|
||||||
self.add_constructor("!Context", Context)
|
self.add_constructor("!Context", Context)
|
||||||
self.add_constructor("!Format", Format)
|
self.add_constructor("!Format", Format)
|
||||||
self.add_constructor("!Condition", Condition)
|
self.add_constructor("!Condition", Condition)
|
||||||
|
@ -12,6 +12,7 @@ For VS Code, for example, add these entries to your `settings.json`:
|
|||||||
"!Enumerate sequence",
|
"!Enumerate sequence",
|
||||||
"!Env scalar",
|
"!Env scalar",
|
||||||
"!Find sequence",
|
"!Find sequence",
|
||||||
|
"!FindObject sequence",
|
||||||
"!Format sequence",
|
"!Format sequence",
|
||||||
"!If sequence",
|
"!If sequence",
|
||||||
"!Index scalar",
|
"!Index scalar",
|
||||||
@ -60,7 +61,22 @@ configure_flow:
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
Looks up any model and resolves to the the matches' primary key.
|
Looks up any model and resolves to the matches' primary key.
|
||||||
|
First argument is the model to be queried, remaining arguments are expected to be pairs of key=value pairs to query for.
|
||||||
|
|
||||||
|
#### `!FindObject` <span class="badge badge--version">authentik 2025.2+</span>
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
flow_designation:
|
||||||
|
!AtIndex [
|
||||||
|
!FindObject [authentik_flows.flow, [slug, default-password-change]],
|
||||||
|
designation,
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Looks up any model and resolves to the matches' serialized data.
|
||||||
First argument is the model to be queried, remaining arguments are expected to be pairs of key=value pairs to query for.
|
First argument is the model to be queried, remaining arguments are expected to be pairs of key=value pairs to query for.
|
||||||
|
|
||||||
#### `!Context`
|
#### `!Context`
|
||||||
|
Reference in New Issue
Block a user