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:
parent
201bea6d30
commit
872c18dddc
|
@ -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/
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
version: 1
|
||||
metadata:
|
||||
labels:
|
||||
blueprints.goauthentik.io/example: "true"
|
||||
blueprints.goauthentik.io/instantiate: "false"
|
||||
name: Example - User deletion
|
||||
entries:
|
||||
- identifiers:
|
||||
|
|
Reference in a new issue