blueprints: don't use example label, add more tags and tests for tags

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2022-08-07 19:27:03 +02:00
parent 201bea6d30
commit 872c18dddc
12 changed files with 62 additions and 17 deletions

View file

@ -82,8 +82,7 @@ COPY ./pyproject.toml /
COPY ./xml /xml COPY ./xml /xml
COPY ./tests /tests COPY ./tests /tests
COPY ./manage.py / COPY ./manage.py /
COPY ./blueprints/default /blueprints/default COPY ./blueprints /blueprints
COPY ./blueprints/system /blueprints/system
COPY ./lifecycle/ /lifecycle COPY ./lifecycle/ /lifecycle
COPY --from=builder /work/authentik /authentik-proxy COPY --from=builder /work/authentik /authentik-proxy
COPY --from=web-builder /work/web/dist/ /web/dist/ COPY --from=web-builder /work/web/dist/ /web/dist/

View file

@ -19,10 +19,12 @@ def check_blueprint_v1_file(BlueprintInstance: type["BlueprintInstance"], path:
"""Check if blueprint should be imported""" """Check if blueprint should be imported"""
from authentik.blueprints.models import BlueprintInstanceStatus from authentik.blueprints.models import BlueprintInstanceStatus
from authentik.blueprints.v1.common import BlueprintLoader, BlueprintMetadata from authentik.blueprints.v1.common import BlueprintLoader, BlueprintMetadata
from authentik.blueprints.v1.labels import LABEL_AUTHENTIK_EXAMPLE from authentik.blueprints.v1.labels import LABEL_AUTHENTIK_INSTANTIATE
with open(path, "r", encoding="utf-8") as blueprint_file: with open(path, "r", encoding="utf-8") as blueprint_file:
raw_blueprint = load(blueprint_file.read(), BlueprintLoader) raw_blueprint = load(blueprint_file.read(), BlueprintLoader)
if not raw_blueprint:
return
metadata = raw_blueprint.get("metadata", None) metadata = raw_blueprint.get("metadata", None)
version = raw_blueprint.get("version", 1) version = raw_blueprint.get("version", 1)
if version != 1: if version != 1:
@ -33,7 +35,7 @@ def check_blueprint_v1_file(BlueprintInstance: type["BlueprintInstance"], path:
meta = None meta = None
if metadata: if metadata:
meta = from_dict(BlueprintMetadata, metadata) meta = from_dict(BlueprintMetadata, metadata)
if meta.labels.get(LABEL_AUTHENTIK_EXAMPLE, "").lower() == "true": if meta.labels.get(LABEL_AUTHENTIK_INSTANTIATE, "").lower() == "false":
return return
if not instance: if not instance:
instance = BlueprintInstance( instance = BlueprintInstance(

View file

@ -24,6 +24,18 @@ entries:
order: 0 order: 0
""" """
YAML_TAG_TESTS = """version: 1
context:
foo: bar
entries:
- attrs:
expression: return True
identifiers:
name: !Format [foo-%s-%s, !Context foo, !Context bar]
id: default-source-enrollment-if-username
model: authentik_policies_expression.expressionpolicy
"""
class TestBlueprintsV1(TransactionTestCase): class TestBlueprintsV1(TransactionTestCase):
"""Test Blueprints""" """Test Blueprints"""
@ -85,6 +97,14 @@ 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)
def test_import_yaml_tags(self):
"""Test some yaml tags"""
ExpressionPolicy.objects.filter(name="foo-foo-bar").delete()
importer = Importer(YAML_TAG_TESTS, {"bar": "baz"})
self.assertTrue(importer.validate()[0])
self.assertTrue(importer.apply())
self.assertTrue(ExpressionPolicy.objects.filter(name="foo-foo-bar"))
def test_export_validate_import_policies(self): def test_export_validate_import_policies(self):
"""Test export and validate it""" """Test export and validate it"""
flow_slug = generate_id() flow_slug = generate_id()

View file

@ -160,6 +160,29 @@ class Context(YAMLTag):
return value return value
class Format(YAMLTag):
"""Format a string"""
format_string: str
args: list[Any]
# pylint: disable=unused-argument
def __init__(self, loader: "BlueprintLoader", node: SequenceNode) -> None:
super().__init__()
self.format_string = node.value[0].value
self.args = []
for raw_node in node.value[1:]:
self.args.append(raw_node.value)
def resolve(self, entry: BlueprintEntry, blueprint: Blueprint) -> Any:
try:
print(self.format_string)
print(self.args)
return self.format_string % tuple(self.args)
except TypeError as exc:
raise EntryInvalidError(exc)
class Find(YAMLTag): class Find(YAMLTag):
"""Find any object""" """Find any object"""
@ -214,6 +237,7 @@ class BlueprintLoader(SafeLoader):
self.add_constructor("!KeyOf", KeyOf) self.add_constructor("!KeyOf", KeyOf)
self.add_constructor("!Find", Find) self.add_constructor("!Find", Find)
self.add_constructor("!Context", Context) self.add_constructor("!Context", Context)
self.add_constructor("!Format", Format)
class EntryInvalidError(SentryIgnoredException): class EntryInvalidError(SentryIgnoredException):

View file

@ -1,4 +1,4 @@
"""Blueprint labels""" """Blueprint labels"""
LABEL_AUTHENTIK_SYSTEM = "blueprints.goauthentik.io/system" LABEL_AUTHENTIK_SYSTEM = "blueprints.goauthentik.io/system"
LABEL_AUTHENTIK_EXAMPLE = "blueprints.goauthentik.io/example" LABEL_AUTHENTIK_INSTANTIATE = "blueprints.goauthentik.io/instantiate"

View file

@ -14,7 +14,7 @@ from yaml.error import YAMLError
from authentik.blueprints.models import BlueprintInstance, BlueprintInstanceStatus from authentik.blueprints.models import BlueprintInstance, BlueprintInstanceStatus
from authentik.blueprints.v1.common import BlueprintLoader, BlueprintMetadata from authentik.blueprints.v1.common import BlueprintLoader, BlueprintMetadata
from authentik.blueprints.v1.importer import Importer from authentik.blueprints.v1.importer import Importer
from authentik.blueprints.v1.labels import LABEL_AUTHENTIK_EXAMPLE from authentik.blueprints.v1.labels import LABEL_AUTHENTIK_INSTANTIATE
from authentik.events.monitored_tasks import ( from authentik.events.monitored_tasks import (
MonitoredTask, MonitoredTask,
TaskResult, TaskResult,
@ -59,11 +59,6 @@ def blueprints_find():
file_hash = sha512(path.read_bytes()).hexdigest() file_hash = sha512(path.read_bytes()).hexdigest()
blueprint = BlueprintFile(path.relative_to(root), version, file_hash, path.stat().st_mtime) blueprint = BlueprintFile(path.relative_to(root), version, file_hash, path.stat().st_mtime)
blueprint.meta = from_dict(BlueprintMetadata, metadata) if metadata else None blueprint.meta = from_dict(BlueprintMetadata, metadata) if metadata else None
if (
blueprint.meta
and blueprint.meta.labels.get(LABEL_AUTHENTIK_EXAMPLE, "").lower() == "true"
):
continue
blueprints.append(blueprint) blueprints.append(blueprint)
return blueprints return blueprints
@ -89,6 +84,11 @@ def blueprints_discover(self: MonitoredTask):
def check_blueprint_v1_file(blueprint: BlueprintFile): def check_blueprint_v1_file(blueprint: BlueprintFile):
"""Check if blueprint should be imported""" """Check if blueprint should be imported"""
instance: BlueprintInstance = BlueprintInstance.objects.filter(path=blueprint.path).first() instance: BlueprintInstance = BlueprintInstance.objects.filter(path=blueprint.path).first()
if (
blueprint.meta
and blueprint.meta.labels.get(LABEL_AUTHENTIK_INSTANTIATE, "").lower() == "false"
):
return
if not instance: if not instance:
instance = BlueprintInstance( instance = BlueprintInstance(
name=blueprint.meta.name if blueprint.meta else str(blueprint.path), name=blueprint.meta.name if blueprint.meta else str(blueprint.path),

View file

@ -1,7 +1,7 @@
version: 1 version: 1
metadata: metadata:
labels: labels:
blueprints.goauthentik.io/example: "true" blueprints.goauthentik.io/instantiate: "false"
name: Example - Enrollment (2 Stage) name: Example - Enrollment (2 Stage)
entries: entries:
- identifiers: - identifiers:

View file

@ -1,7 +1,7 @@
version: 1 version: 1
metadata: metadata:
labels: labels:
blueprints.goauthentik.io/example: "true" blueprints.goauthentik.io/instantiate: "false"
name: Example - Enrollment with email verification name: Example - Enrollment with email verification
entries: entries:
- identifiers: - identifiers:

View file

@ -1,7 +1,7 @@
version: 1 version: 1
metadata: metadata:
labels: labels:
blueprints.goauthentik.io/example: "true" blueprints.goauthentik.io/instantiate: "false"
name: Example - Two-factor Login name: Example - Two-factor Login
entries: entries:
- identifiers: - identifiers:

View file

@ -1,7 +1,7 @@
version: 1 version: 1
metadata: metadata:
labels: labels:
blueprints.goauthentik.io/example: "true" blueprints.goauthentik.io/instantiate: "false"
name: Example - Login with conditional Captcha name: Example - Login with conditional Captcha
entries: entries:
- identifiers: - identifiers:

View file

@ -1,7 +1,7 @@
version: 1 version: 1
metadata: metadata:
labels: labels:
blueprints.goauthentik.io/example: "true" blueprints.goauthentik.io/instantiate: "false"
name: Example - Recovery with email verification name: Example - Recovery with email verification
entries: entries:
- identifiers: - identifiers:

View file

@ -1,7 +1,7 @@
version: 1 version: 1
metadata: metadata:
labels: labels:
blueprints.goauthentik.io/example: "true" blueprints.goauthentik.io/instantiate: "false"
name: Example - User deletion name: Example - User deletion
entries: entries:
- identifiers: - identifiers: