`ak export_blueprint` does not work
Describe the bug
It seems that there's a series of bugs that prevent ak export_blueprint from working on an up-to-date 2022.8.2 Authentik instance.
To Reproduce Steps to reproduce the behavior:
- Inside the docker container, run
ak export_blueprint
Expected behavior An export of the blueprints in the instance is produced.
Logs
I have no name!@e06979d04acf:/$ ak export_blueprint
{"event": "Loaded config", "level": "debug", "logger": "authentik.lib.config", "timestamp": 1661639588.551532, "file": "/authentik/lib/default.yml"}
{"event": "Loaded environment variables", "level": "debug", "logger": "authentik.lib.config", "timestamp": 1661639588.5517583, "count": 6}
{"event": "Booting authentik", "level": "info", "logger": "authentik.root.settings", "timestamp": 1661639588.913549, "version": "2022.8.2"}
{"event": "Failed to load GeoIP database", "exc": "FileNotFoundError(2, 'No such file or directory')", "level": "warning", "logger": "authentik.events.geo", "pid": 4033, "timestamp": "2022-08-27T22:33:09.280181"}
{"event": "Task published", "level": "info", "logger": "authentik.root.celery", "pid": 4033, "task_id": "8dad8709-53f9-4d5d-8c34-10e4330a2463", "task_name": "authentik.blueprints.v1.tasks.blueprints_discover", "timestamp": "2022-08-27T22:33:09.656647"}
Traceback (most recent call last):
File "/usr/local/lib/python3.10/runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/local/lib/python3.10/runpy.py", line 86, in _run_code
exec(code, run_globals)
File "/manage.py", line 38, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 440, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 402, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 448, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 96, in wrapped
res = handle_func(*args, **kwargs)
File "/authentik/blueprints/management/commands/export_blueprint.py", line 17, in handle
self.stdout.write(exporter.export_to_string())
File "/authentik/blueprints/v1/exporter.py", line 63, in export_to_string
blueprint = self.export()
File "/authentik/blueprints/v1/exporter.py", line 58, in export
blueprint.entries = list(self.get_entries())
File "/authentik/blueprints/v1/exporter.py", line 43, in get_entries
yield BlueprintEntry.from_model(obj)
File "/authentik/blueprints/v1/common.py", line 63, in from_model
all_attrs = get_attrs(model)
File "/authentik/blueprints/v1/common.py", line 22, in get_attrs
data = dict(serializer.data)
File "/usr/local/lib/python3.10/site-packages/rest_framework/serializers.py", line 555, in data
ret = super().data
File "/usr/local/lib/python3.10/site-packages/rest_framework/serializers.py", line 253, in data
self._data = self.to_representation(self.instance)
File "/usr/local/lib/python3.10/site-packages/rest_framework/serializers.py", line 522, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/usr/local/lib/python3.10/site-packages/rest_framework/fields.py", line 1886, in to_representation
return method(value)
File "/authentik/core/api/applications.py", line 53, in get_launch_url
user = self.context["request"].user
KeyError: 'request'
If I monkey-patch around this error,
I have no name!@e06979d04acf:/$ python -m manage shell
{"event": "Loaded config", "level": "debug", "logger": "authentik.lib.config", "timestamp": 1661639750.0241816, "file": "/authentik/l
ib/default.yml"}
{"event": "Loaded environment variables", "level": "debug", "logger": "authentik.lib.config", "timestamp": 1661639750.0244184, "count
": 6}
{"event": "Booting authentik", "level": "info", "logger": "authentik.root.settings", "timestamp": 1661639750.3875265, "version": "202
2.8.2"}
{"event": "Failed to load GeoIP database", "exc": "FileNotFoundError(2, 'No such file or directory')", "level": "warning", "logger":
"authentik.events.geo", "pid": 4090, "timestamp": "2022-08-27T22:35:50.737404"}
{"event": "Task published", "level": "info", "logger": "authentik.root.celery", "pid": 4090, "task_id": "156db57e-730e-44c1-b10a-b6a1
19d37d02", "task_name": "authentik.blueprints.v1.tasks.blueprints_discover", "timestamp": "2022-08-27T22:35:51.097681"}
### authentik shell (2022.8.2)
### Node e06979d04acf | Arch x86_64 | Python 3.10.6
>>> from authentik.blueprints.v1.exporter import Exporter
>>> import authentik.core.api
>>> authentik.core.api.applications.ApplicationSerializer.get_launch_url = lambda x,y: None
I end up with a new stack trace:
>>> exporter = Exporter()
>>> exporter.export_to_string()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/authentik/blueprints/v1/exporter.py", line 64, in export_to_string
return dump(blueprint, Dumper=BlueprintDumper)
File "/usr/local/lib/python3.10/site-packages/yaml/__init__.py", line 253, in dump
return dump_all([data], stream, Dumper=Dumper, **kwds)
File "/usr/local/lib/python3.10/site-packages/yaml/__init__.py", line 241, in dump_all
dumper.represent(data)
File "/authentik/blueprints/v1/common.py", line 240, in represent
return super().represent(data)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 27, in represent
node = self.represent_data(data)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 48, in represent_data
node = self.yaml_representers[data_types[0]](self, data)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 207, in represent_dict
return self.represent_mapping('tag:yaml.org,2002:map', data)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 118, in represent_mapping
node_value = self.represent_data(item_value)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 48, in represent_data
node = self.yaml_representers[data_types[0]](self, data)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 199, in represent_list
return self.represent_sequence('tag:yaml.org,2002:seq', data)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 92, in represent_sequence
node_item = self.represent_data(item)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 48, in represent_data
node = self.yaml_representers[data_types[0]](self, data)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 207, in represent_dict
return self.represent_mapping('tag:yaml.org,2002:map', data)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 118, in represent_mapping
node_value = self.represent_data(item_value)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 48, in represent_data
node = self.yaml_representers[data_types[0]](self, data)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 207, in represent_dict
return self.represent_mapping('tag:yaml.org,2002:map', data)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 118, in represent_mapping
node_value = self.represent_data(item_value)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 48, in represent_data
node = self.yaml_representers[data_types[0]](self, data)
File "/authentik/blueprints/v1/common.py", line 228, in <lambda>
self.add_representer(OrderedDict, lambda self, data: self.represent_dict(dict(data)))
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 207, in represent_dict
return self.represent_mapping('tag:yaml.org,2002:map', data)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 118, in represent_mapping
node_value = self.represent_data(item_value)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 58, in represent_data
node = self.yaml_representers[None](self, data)
File "/usr/local/lib/python3.10/site-packages/yaml/representer.py", line 231, in represent_undefined
raise RepresenterError("cannot represent an object", data)
yaml.representer.RepresenterError: ('cannot represent an object', 'OAuth2/OpenID Provider')
This seems to be because
>>> import pdb
>>> pdb.pm()
> /usr/local/lib/python3.10/site-packages/yaml/representer.py(231)represent_undefined()
-> raise RepresenterError("cannot represent an object", data)
(Pdb) pp data
'OAuth2/OpenID Provider'
(Pdb) type(data)
<class 'django.utils.functional.lazy.<locals>.__proxy__'>
the string "OAuth2/OpenID Provider" is actually an object from Django with a string-like repr, and PyYAML doesn't have a registered representer. At this point I gave up trying to monkey-patch further.
Version and Deployment (please complete the following information):
- authentik version: 2022.8.2
- Deployment: docker-compose
Additional context Add any other context about the problem here.
The initial issue is fixed with the commit above, I was not able to reproduce the second issue yet
Thanks! For the 2nd stack trace I have a fairly simple local instance with Grafana set up as an Application with a dedicated Provider, following the Authentik documentation. I also have an LDAP outpost and the embedded outpost configured.
I created an Application with an OAuth2 provider attached with all default settings and didnt get an error
the 2nd stack trace is caused by the OAuth2 Provider using lazy-translated strings for the model's verbose_name, and the verbose_name is returned via the API, however the blueprint export should filter out all instances of verbose_name fields
I played around with the stacktrace with pdb a bit more. It was definitely trying to export the verbose_name. It seems to be coming from the OpenID provider:
yaml.representer.RepresenterError: ('cannot represent an object', 'OAuth2/OpenID Provider')
>>> import pdb
>>> pdb.pm()
> /usr/local/lib/python3.10/site-packages/yaml/representer.py(231)represent_undefined()
-> raise RepresenterError("cannot represent an object", data)
(Pdb) up
> /usr/local/lib/python3.10/site-packages/yaml/representer.py(58)represent_data()
-> node = self.yaml_representers[None](self, data)
(Pdb)
> /usr/local/lib/python3.10/site-packages/yaml/representer.py(118)represent_mapping()
-> node_value = self.represent_data(item_value)
(Pdb) p item_value
'OAuth2/OpenID Provider'
(Pdb) up
> /usr/local/lib/python3.10/site-packages/yaml/representer.py(207)represent_dict()
-> return self.represent_mapping('tag:yaml.org,2002:map', data)
(Pdb) pp data
{'access_code_validity': 'minutes=1',
'assigned_application_name': 'Grafana',
'assigned_application_slug': 'grafana',
'authorization_flow': UUID('95571512-ce9d-4585-bf0e-524b83f3ad61'),
'client_id': 'REDACTED',
'client_secret': 'REDACTED',
'client_type': 'confidential',
'component': 'ak-provider-oauth2-form',
'include_claims_in_id_token': True,
'issuer_mode': 'per_provider',
'jwks_sources': [],
'meta_model_name': 'authentik_providers_oauth2.oauth2provider',
'name': 'Grafana OpenID',
'pk': 1,
'property_mappings': [UUID('72aaf93c-d397-4646-ac31-29eae0da5fe2'),
UUID('d7bd9c21-4fc2-4ee3-b2c9-faae050c36a2'),
UUID('f741b0f6-0cf5-4a52-874b-49d4d8b74aa2')],
'redirect_uris': 'https://REDACTED/login/generic_oauth',
'signing_key': UUID('5d396d3f-b2eb-4b33-84fd-fdcc3ad143f3'),
'sub_mode': 'hashed_user_id',
'token_validity': 'days=30',
'verbose_name': 'OAuth2/OpenID Provider',
'verbose_name_plural': 'OAuth2/OpenID Providers'}
So, any solution ?