blueprints: add Env tag

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2022-12-24 20:41:51 +01:00
parent fe1e2aa8af
commit 94b9ebb0bb
No known key found for this signature in database
5 changed files with 52 additions and 1 deletions

View File

@ -24,8 +24,11 @@
"!Find sequence",
"!KeyOf scalar",
"!Context scalar",
"!Context sequence",
"!Format sequence",
"!Condition sequence"
"!Condition sequence",
"!Env sequence",
"!Env scalar"
],
"typescript.preferences.importModuleSpecifier": "non-relative",
"typescript.preferences.importModuleSpecifierEnding": "index",

View File

@ -4,6 +4,16 @@ context:
policy_property: name
policy_property_value: foo-bar-baz-qux
entries:
- model: authentik_sources_oauth.oauthsource
identifiers:
slug: test
attrs:
name: test
provider_type: github
consumer_key: !Env foo
consumer_secret: !Env [bar, baz]
authentication_flow: !Find [authentik_flows.Flow, [slug, default-source-authentication]]
enrollment_flow: !Find [authentik_flows.Flow, [slug, default-source-enrollment]]
- attrs:
expression: return True
identifiers:

View File

@ -1,4 +1,6 @@
"""Test blueprints v1"""
from os import environ
from django.test import TransactionTestCase
from authentik.blueprints.tests import load_yaml_fixture
@ -9,6 +11,7 @@ from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
from authentik.lib.generators import generate_id
from authentik.policies.expression.models import ExpressionPolicy
from authentik.policies.models import PolicyBinding
from authentik.sources.oauth.models import OAuthSource
from authentik.stages.prompt.models import FieldTypes, Prompt, PromptStage
from authentik.stages.user_login.models import UserLoginStage
@ -132,6 +135,7 @@ class TestBlueprintsV1(TransactionTestCase):
"""Test some yaml tags"""
ExpressionPolicy.objects.filter(name="foo-bar-baz-qux").delete()
Group.objects.filter(name="test").delete()
environ["foo"] = generate_id()
importer = Importer(load_yaml_fixture("fixtures/tags.yaml"), {"bar": "baz"})
self.assertTrue(importer.validate()[0])
self.assertTrue(importer.apply())
@ -152,6 +156,12 @@ class TestBlueprintsV1(TransactionTestCase):
}
)
)
self.assertTrue(
OAuthSource.objects.filter(
slug="test",
consumer_key=environ["foo"],
)
)
def test_export_validate_import_policies(self):
"""Test export and validate it"""

View File

@ -4,6 +4,7 @@ from dataclasses import asdict, dataclass, field, is_dataclass
from enum import Enum
from functools import reduce
from operator import ixor
from os import getenv
from typing import Any, Literal, Optional
from uuid import UUID
@ -160,6 +161,26 @@ class KeyOf(YAMLTag):
)
class Env(YAMLTag):
"""Lookup environment variable with optional default"""
key: str
default: Optional[Any]
# pylint: disable=unused-argument
def __init__(self, loader: "BlueprintLoader", node: ScalarNode | SequenceNode) -> None:
super().__init__()
self.default = None
if isinstance(node, ScalarNode):
self.key = node.value
if isinstance(node, SequenceNode):
self.key = node.value[0].value
self.default = node.value[1].value
def resolve(self, entry: BlueprintEntry, blueprint: Blueprint) -> Any:
return getenv(self.key, self.default)
class Context(YAMLTag):
"""Lookup key from instance context"""
@ -332,6 +353,7 @@ class BlueprintLoader(SafeLoader):
self.add_constructor("!Context", Context)
self.add_constructor("!Format", Format)
self.add_constructor("!Condition", Condition)
self.add_constructor("!Env", Env)
class EntryInvalidError(SentryIgnoredException):

View File

@ -8,6 +8,12 @@ Resolves to the primary key of the model instance defined by id _my-policy-id_.
If no matching entry can be found, an error is raised and the blueprint is invalid.
#### `!Env`
Example: `password: !Env my_env_var`
Returns the value of the given environment variable. Can be used as a scalar with `!Env my_env_var, default` to return a default value.
#### `!Find`
Examples: