Compare commits
	
		
			1 Commits
		
	
	
		
			dependabot
			...
			blueprints
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 906c63c16f | 
							
								
								
									
										5
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							@ -29,6 +29,7 @@
 | 
			
		||||
        "!Enumerate sequence",
 | 
			
		||||
        "!Env scalar",
 | 
			
		||||
        "!Find sequence",
 | 
			
		||||
        "!FindObject sequence",
 | 
			
		||||
        "!Format sequence",
 | 
			
		||||
        "!If sequence",
 | 
			
		||||
        "!Index scalar",
 | 
			
		||||
@ -51,7 +52,9 @@
 | 
			
		||||
            "ignoreCase": false
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
    "go.testFlags": ["-count=1"],
 | 
			
		||||
    "go.testFlags": [
 | 
			
		||||
        "-count=1"
 | 
			
		||||
    ],
 | 
			
		||||
    "github-actions.workflows.pinned.workflows": [
 | 
			
		||||
        ".github/workflows/ci-main.yml"
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
@ -150,6 +150,7 @@ entries:
 | 
			
		||||
              at_index_sequence_default: !AtIndex [!Context sequence, 100, "non existent"]
 | 
			
		||||
              at_index_mapping: !AtIndex [!Context mapping, "key2"]
 | 
			
		||||
              at_index_mapping_default: !AtIndex [!Context mapping, "invalid", "non existent"]
 | 
			
		||||
              find_object: !AtIndex [!FindObject [authentik_providers_oauth2.scopemapping, [scope_name, openid]], managed]
 | 
			
		||||
      identifiers:
 | 
			
		||||
          name: test
 | 
			
		||||
      conditions:
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@ from os import environ
 | 
			
		||||
 | 
			
		||||
from django.test import TransactionTestCase
 | 
			
		||||
 | 
			
		||||
from authentik.blueprints.tests import apply_blueprint
 | 
			
		||||
from authentik.blueprints.v1.exporter import FlowExporter
 | 
			
		||||
from authentik.blueprints.v1.importer import Importer, transaction_rollback
 | 
			
		||||
from authentik.core.models import Group
 | 
			
		||||
@ -126,6 +127,7 @@ class TestBlueprintsV1(TransactionTestCase):
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(Prompt.objects.filter(field_key="username").count(), count_before)
 | 
			
		||||
 | 
			
		||||
    @apply_blueprint("system/providers-oauth2.yaml")
 | 
			
		||||
    def test_import_yaml_tags(self):
 | 
			
		||||
        """Test some yaml tags"""
 | 
			
		||||
        ExpressionPolicy.objects.filter(name="foo-bar-baz-qux").delete()
 | 
			
		||||
@ -136,9 +138,11 @@ class TestBlueprintsV1(TransactionTestCase):
 | 
			
		||||
        self.assertTrue(importer.apply())
 | 
			
		||||
        policy = ExpressionPolicy.objects.filter(name="foo-bar-baz-qux").first()
 | 
			
		||||
        self.assertTrue(policy)
 | 
			
		||||
        self.assertTrue(
 | 
			
		||||
            Group.objects.filter(
 | 
			
		||||
                attributes={
 | 
			
		||||
        group = Group.objects.filter(name="test").first()
 | 
			
		||||
        self.assertIsNotNone(group)
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            group.attributes,
 | 
			
		||||
            {
 | 
			
		||||
                "policy_pk1": str(policy.pk) + "-suffix",
 | 
			
		||||
                "policy_pk2": str(policy.pk) + "-suffix",
 | 
			
		||||
                "boolAnd": True,
 | 
			
		||||
@ -219,8 +223,8 @@ class TestBlueprintsV1(TransactionTestCase):
 | 
			
		||||
                "at_index_sequence_default": "non existent",
 | 
			
		||||
                "at_index_mapping": 2,
 | 
			
		||||
                "at_index_mapping_default": "non existent",
 | 
			
		||||
                }
 | 
			
		||||
            ).exists()
 | 
			
		||||
                "find_object": "goauthentik.io/providers/oauth2/scope-openid",
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
        self.assertTrue(
 | 
			
		||||
            OAuthSource.objects.filter(
 | 
			
		||||
 | 
			
		||||
@ -311,7 +311,7 @@ class Format(YAMLTag):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Find(YAMLTag):
 | 
			
		||||
    """Find any object"""
 | 
			
		||||
    """Find any object primary key"""
 | 
			
		||||
 | 
			
		||||
    model_name: str | YAMLTag
 | 
			
		||||
    conditions: list[list]
 | 
			
		||||
@ -326,7 +326,7 @@ class Find(YAMLTag):
 | 
			
		||||
                values.append(loader.construct_object(node_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):
 | 
			
		||||
            model_name = self.model_name.resolve(entry, blueprint)
 | 
			
		||||
        else:
 | 
			
		||||
@ -348,12 +348,29 @@ class Find(YAMLTag):
 | 
			
		||||
            else:
 | 
			
		||||
                query_value = cond[1]
 | 
			
		||||
            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:
 | 
			
		||||
            return instance.pk
 | 
			
		||||
        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):
 | 
			
		||||
    """Convert all values to a single boolean"""
 | 
			
		||||
 | 
			
		||||
@ -649,6 +666,7 @@ class BlueprintLoader(SafeLoader):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.add_constructor("!KeyOf", KeyOf)
 | 
			
		||||
        self.add_constructor("!Find", Find)
 | 
			
		||||
        self.add_constructor("!FindObject", FindObject)
 | 
			
		||||
        self.add_constructor("!Context", Context)
 | 
			
		||||
        self.add_constructor("!Format", Format)
 | 
			
		||||
        self.add_constructor("!Condition", Condition)
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,7 @@ For VS Code, for example, add these entries to your `settings.json`:
 | 
			
		||||
        "!Enumerate sequence",
 | 
			
		||||
        "!Env scalar",
 | 
			
		||||
        "!Find sequence",
 | 
			
		||||
        "!FindObject sequence",
 | 
			
		||||
        "!Format sequence",
 | 
			
		||||
        "!If sequence",
 | 
			
		||||
        "!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.
 | 
			
		||||
 | 
			
		||||
#### `!Context`
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user