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 ./tests /tests
COPY ./manage.py /
COPY ./blueprints/default /blueprints/default
COPY ./blueprints/system /blueprints/system
COPY ./blueprints /blueprints
COPY ./lifecycle/ /lifecycle
COPY --from=builder /work/authentik /authentik-proxy
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"""
from authentik.blueprints.models import BlueprintInstanceStatus
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:
raw_blueprint = load(blueprint_file.read(), BlueprintLoader)
if not raw_blueprint:
return
metadata = raw_blueprint.get("metadata", None)
version = raw_blueprint.get("version", 1)
if version != 1:
@ -33,7 +35,7 @@ def check_blueprint_v1_file(BlueprintInstance: type["BlueprintInstance"], path:
meta = None
if 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
if not instance:
instance = BlueprintInstance(

View file

@ -24,6 +24,18 @@ entries:
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):
"""Test Blueprints"""
@ -85,6 +97,14 @@ class TestBlueprintsV1(TransactionTestCase):
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):
"""Test export and validate it"""
flow_slug = generate_id()

View file

@ -160,6 +160,29 @@ class Context(YAMLTag):
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):
"""Find any object"""
@ -214,6 +237,7 @@ class BlueprintLoader(SafeLoader):
self.add_constructor("!KeyOf", KeyOf)
self.add_constructor("!Find", Find)
self.add_constructor("!Context", Context)
self.add_constructor("!Format", Format)
class EntryInvalidError(SentryIgnoredException):

View file

@ -1,4 +1,4 @@
"""Blueprint labels"""
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.v1.common import BlueprintLoader, BlueprintMetadata
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 (
MonitoredTask,
TaskResult,
@ -59,11 +59,6 @@ def blueprints_find():
file_hash = sha512(path.read_bytes()).hexdigest()
blueprint = BlueprintFile(path.relative_to(root), version, file_hash, path.stat().st_mtime)
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)
return blueprints
@ -89,6 +84,11 @@ def blueprints_discover(self: MonitoredTask):
def check_blueprint_v1_file(blueprint: BlueprintFile):
"""Check if blueprint should be imported"""
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:
instance = BlueprintInstance(
name=blueprint.meta.name if blueprint.meta else str(blueprint.path),

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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