Merge branch 'master' into version-0.14
This commit is contained in:
commit
101b973cfe
|
@ -74,18 +74,18 @@
|
||||||
},
|
},
|
||||||
"boto3": {
|
"boto3": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:ba8de10d3ede338d51ae47e428b97dcc1d1b507741aa98697e63e879a147f4aa",
|
"sha256:197926eaf0065c2c503914a15edc75f4ac259c1e5ae6d17eabd1ba5d8ebd1554",
|
||||||
"sha256:e3f10ed6d9ca98415fdec15c85e50a89ec38d6229bce3fafd5e7965b16c4ebc5"
|
"sha256:d6991e6fd7d0f63bf94282687700a91f5299b807e544cb3367e9b2faeeaf8c62"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==1.16.44"
|
"version": "==1.16.46"
|
||||||
},
|
},
|
||||||
"botocore": {
|
"botocore": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:4ff05bc089ba78a5996f06dcfddf8ca51583e30ce779ed95e9952e90c1907420",
|
"sha256:85ca6915ad5471e7f6cd1b00610b74601d2970cbf8e9b1bf255697154cf621a3",
|
||||||
"sha256:7725e08c95ae96c4dbd955cb4ae44a0c06d3e41f76a7feb0a941c27a44c63113"
|
"sha256:f7d365c689070368a5a0857aa35a81d7c950556189f23065f42798f810a59cae"
|
||||||
],
|
],
|
||||||
"version": "==1.19.44"
|
"version": "==1.19.46"
|
||||||
},
|
},
|
||||||
"cachetools": {
|
"cachetools": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -1083,11 +1083,11 @@
|
||||||
"standard"
|
"standard"
|
||||||
],
|
],
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:6707fa7f4dbd86fd6982a2d4ecdaad2704e4514d23a1e4278104311288b04691",
|
"sha256:1079c50a06f6338095b4f203e7861dbff318dde5f22f3a324fc6e94c7654164c",
|
||||||
"sha256:d19ca083bebd212843e01f689900e5c637a292c63bb336c7f0735a99300a5f38"
|
"sha256:ef1e0bb5f7941c6fe324e06443ddac0331e1632a776175f87891c7bd02694355"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==0.13.2"
|
"version": "==0.13.3"
|
||||||
},
|
},
|
||||||
"uvloop": {
|
"uvloop": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -1741,38 +1741,38 @@
|
||||||
},
|
},
|
||||||
"typed-ast": {
|
"typed-ast": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355",
|
"sha256:07d49388d5bf7e863f7fa2f124b1b1d89d8aa0e2f7812faff0a5658c01c59aa1",
|
||||||
"sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919",
|
"sha256:14bf1522cdee369e8f5581238edac09150c765ec1cb33615855889cf33dcb92d",
|
||||||
"sha256:0d8110d78a5736e16e26213114a38ca35cb15b6515d535413b090bd50951556d",
|
"sha256:240296b27397e4e37874abb1df2a608a92df85cf3e2a04d0d4d61055c8305ba6",
|
||||||
"sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa",
|
"sha256:36d829b31ab67d6fcb30e185ec996e1f72b892255a745d3a82138c97d21ed1cd",
|
||||||
"sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652",
|
"sha256:37f48d46d733d57cc70fd5f30572d11ab8ed92da6e6b28e024e4a3edfb456e37",
|
||||||
"sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75",
|
"sha256:4c790331247081ea7c632a76d5b2a265e6d325ecd3179d06e9cf8d46d90dd151",
|
||||||
"sha256:3742b32cf1c6ef124d57f95be609c473d7ec4c14d0090e5a5e05a15269fb4d0c",
|
"sha256:5dcfc2e264bd8a1db8b11a892bd1647154ce03eeba94b461effe68790d8b8e07",
|
||||||
"sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01",
|
"sha256:7147e2a76c75f0f64c4319886e7639e490fee87c9d25cb1d4faef1d8cf83a440",
|
||||||
"sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d",
|
"sha256:7703620125e4fb79b64aa52427ec192822e9f45d37d4b6625ab37ef403e1df70",
|
||||||
"sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1",
|
"sha256:8368f83e93c7156ccd40e49a783a6a6850ca25b556c0fa0240ed0f659d2fe496",
|
||||||
"sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907",
|
"sha256:84aa6223d71012c68d577c83f4e7db50d11d6b1399a9c779046d75e24bed74ea",
|
||||||
"sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c",
|
"sha256:85f95aa97a35bdb2f2f7d10ec5bbdac0aeb9dafdaf88e17492da0504de2e6400",
|
||||||
"sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3",
|
"sha256:8db0e856712f79c45956da0c9a40ca4246abc3485ae0d7ecc86a20f5e4c09abc",
|
||||||
"sha256:7e4c9d7658aaa1fc80018593abdf8598bf91325af6af5cce4ce7c73bc45ea53d",
|
"sha256:9044ef2df88d7f33692ae3f18d3be63dec69c4fb1b5a4a9ac950f9b4ba571606",
|
||||||
"sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b",
|
"sha256:963c80b583b0661918718b095e02303d8078950b26cc00b5e5ea9ababe0de1fc",
|
||||||
"sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614",
|
"sha256:987f15737aba2ab5f3928c617ccf1ce412e2e321c77ab16ca5a293e7bbffd581",
|
||||||
"sha256:92c325624e304ebf0e025d1224b77dd4e6393f18aab8d829b5b7e04afe9b7a2c",
|
"sha256:9ec45db0c766f196ae629e509f059ff05fc3148f9ffd28f3cfe75d4afb485412",
|
||||||
"sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb",
|
"sha256:9fc0b3cb5d1720e7141d103cf4819aea239f7d136acf9ee4a69b047b7986175a",
|
||||||
"sha256:b52ccf7cfe4ce2a1064b18594381bccf4179c2ecf7f513134ec2f993dd4ab395",
|
"sha256:a2c927c49f2029291fbabd673d51a2180038f8cd5a5b2f290f78c4516be48be2",
|
||||||
"sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b",
|
"sha256:a38878a223bdd37c9709d07cd357bb79f4c760b29210e14ad0fb395294583787",
|
||||||
"sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41",
|
"sha256:b4fcdcfa302538f70929eb7b392f536a237cbe2ed9cba88e3bf5027b39f5f77f",
|
||||||
"sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6",
|
"sha256:c0c74e5579af4b977c8b932f40a5464764b2f86681327410aa028a22d2f54937",
|
||||||
"sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34",
|
"sha256:c1c876fd795b36126f773db9cbb393f19808edd2637e00fd6caba0e25f2c7b64",
|
||||||
"sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe",
|
"sha256:c9aadc4924d4b5799112837b226160428524a9a45f830e0d0f184b19e4090487",
|
||||||
"sha256:d648b8e3bf2fe648745c8ffcee3db3ff903d0817a01a12dd6a6ea7a8f4889072",
|
"sha256:cc7b98bf58167b7f2db91a4327da24fb93368838eb84a44c472283778fc2446b",
|
||||||
"sha256:f208eb7aff048f6bea9586e61af041ddf7f9ade7caed625742af423f6bae3298",
|
"sha256:cf54cfa843f297991b7388c281cb3855d911137223c6b6d2dd82a47ae5125a41",
|
||||||
"sha256:fac11badff8313e23717f3dada86a15389d0708275bddf766cca67a84ead3e91",
|
"sha256:d003156bb6a59cda9050e983441b7fa2487f7800d76bdc065566b7d728b4581a",
|
||||||
"sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4",
|
"sha256:d175297e9533d8d37437abc14e8a83cbc68af93cc9c1c59c2c292ec59a0697a3",
|
||||||
"sha256:fcf135e17cc74dbfbc05894ebca928ffeb23d9790b3167a674921db19082401f",
|
"sha256:d746a437cdbca200622385305aedd9aef68e8a645e385cc483bdc5e488f07166",
|
||||||
"sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"
|
"sha256:e683e409e5c45d5c9082dc1daf13f6374300806240719f95dc783d1fc942af10"
|
||||||
],
|
],
|
||||||
"version": "==1.4.1"
|
"version": "==1.4.2"
|
||||||
},
|
},
|
||||||
"typing-extensions": {
|
"typing-extensions": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
|
|
@ -6,9 +6,9 @@ As authentik is currently in a pre-stable, only the latest "stable" version is s
|
||||||
|
|
||||||
| Version | Supported |
|
| Version | Supported |
|
||||||
| -------- | ------------------ |
|
| -------- | ------------------ |
|
||||||
| 0.11.x | :white_check_mark: |
|
|
||||||
| 0.12.x | :white_check_mark: |
|
| 0.12.x | :white_check_mark: |
|
||||||
| 0.13.x | :white_check_mark: |
|
| 0.13.x | :white_check_mark: |
|
||||||
|
| 0.14.x | :white_check_mark: |
|
||||||
|
|
||||||
## Reporting a Vulnerability
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ class ApplicationCreateView(
|
||||||
permission_required = "authentik_core.add_application"
|
permission_required = "authentik_core.add_application"
|
||||||
|
|
||||||
template_name = "generic/create.html"
|
template_name = "generic/create.html"
|
||||||
success_url = reverse_lazy("authentik_admin:applications")
|
success_url = reverse_lazy("authentik_core:shell")
|
||||||
success_message = _("Successfully created Application")
|
success_message = _("Successfully created Application")
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ class ApplicationUpdateView(
|
||||||
permission_required = "authentik_core.change_application"
|
permission_required = "authentik_core.change_application"
|
||||||
|
|
||||||
template_name = "generic/update.html"
|
template_name = "generic/update.html"
|
||||||
success_url = reverse_lazy("authentik_admin:applications")
|
success_url = reverse_lazy("authentik_core:shell")
|
||||||
success_message = _("Successfully updated Application")
|
success_message = _("Successfully updated Application")
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,5 +60,5 @@ class ApplicationDeleteView(
|
||||||
permission_required = "authentik_core.delete_application"
|
permission_required = "authentik_core.delete_application"
|
||||||
|
|
||||||
template_name = "generic/delete.html"
|
template_name = "generic/delete.html"
|
||||||
success_url = reverse_lazy("authentik_admin:applications")
|
success_url = reverse_lazy("authentik_core:shell")
|
||||||
success_message = _("Successfully deleted Application")
|
success_message = _("Successfully deleted Application")
|
||||||
|
|
|
@ -11,6 +11,7 @@ from django.views.debug import SafeExceptionReporterFilter
|
||||||
from guardian.utils import get_anonymous_user
|
from guardian.utils import get_anonymous_user
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
|
from authentik.policies.types import PolicyRequest
|
||||||
|
|
||||||
# Special keys which are *not* cleaned, even when the default filter
|
# Special keys which are *not* cleaned, even when the default filter
|
||||||
# is matched
|
# is matched
|
||||||
|
@ -74,6 +75,11 @@ def sanitize_dict(source: Dict[Any, Any]) -> Dict[Any, Any]:
|
||||||
final_dict = {}
|
final_dict = {}
|
||||||
for key, value in source.items():
|
for key, value in source.items():
|
||||||
if is_dataclass(value):
|
if is_dataclass(value):
|
||||||
|
# Because asdict calls `copy.deepcopy(obj)` on everything thats not tuple/dict,
|
||||||
|
# and deepcopy doesn't work with HttpRequests (neither django nor rest_framework).
|
||||||
|
# Currently, the only dataclass that actually holds an http request is a PolicyRequest
|
||||||
|
if isinstance(value, PolicyRequest):
|
||||||
|
value.http_request = None
|
||||||
value = asdict(value)
|
value = asdict(value)
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
final_dict[key] = sanitize_dict(value)
|
final_dict[key] = sanitize_dict(value)
|
||||||
|
|
|
@ -56,6 +56,7 @@ class PolicyEngine:
|
||||||
raise ValueError(f"{pbm} is not instance of PolicyBindingModel")
|
raise ValueError(f"{pbm} is not instance of PolicyBindingModel")
|
||||||
self.__pbm = pbm
|
self.__pbm = pbm
|
||||||
self.request = PolicyRequest(user)
|
self.request = PolicyRequest(user)
|
||||||
|
self.request.obj = pbm
|
||||||
if request:
|
if request:
|
||||||
self.request.http_request = request
|
self.request.http_request = request
|
||||||
self.__cached_policies = []
|
self.__cached_policies = []
|
||||||
|
|
|
@ -93,4 +93,8 @@ class PolicyProcess(Process):
|
||||||
span: Span
|
span: Span
|
||||||
span.set_data("policy", self.binding.policy)
|
span.set_data("policy", self.binding.policy)
|
||||||
span.set_data("request", self.request)
|
span.set_data("request", self.request)
|
||||||
self.connection.send(self.execute())
|
try:
|
||||||
|
self.connection.send(self.execute())
|
||||||
|
except Exception as exc: # pylint: disable=broad-except
|
||||||
|
LOGGER.warning(exc)
|
||||||
|
self.connection.send(PolicyResult(False, str(exc)))
|
||||||
|
|
|
@ -36,17 +36,17 @@ class SAMLProviderForm(forms.ModelForm):
|
||||||
"name",
|
"name",
|
||||||
"authorization_flow",
|
"authorization_flow",
|
||||||
"acs_url",
|
"acs_url",
|
||||||
"audience",
|
|
||||||
"issuer",
|
"issuer",
|
||||||
"sp_binding",
|
"sp_binding",
|
||||||
|
"audience",
|
||||||
|
"signing_kp",
|
||||||
|
"verification_kp",
|
||||||
|
"property_mappings",
|
||||||
"assertion_valid_not_before",
|
"assertion_valid_not_before",
|
||||||
"assertion_valid_not_on_or_after",
|
"assertion_valid_not_on_or_after",
|
||||||
"session_valid_not_on_or_after",
|
"session_valid_not_on_or_after",
|
||||||
"digest_algorithm",
|
"digest_algorithm",
|
||||||
"signature_algorithm",
|
"signature_algorithm",
|
||||||
"signing_kp",
|
|
||||||
"verification_kp",
|
|
||||||
"property_mappings",
|
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
"name": forms.TextInput(),
|
"name": forms.TextInput(),
|
||||||
|
@ -94,6 +94,9 @@ class SAMLProviderImportForm(forms.Form):
|
||||||
"""Create a SAML Provider from SP Metadata."""
|
"""Create a SAML Provider from SP Metadata."""
|
||||||
|
|
||||||
provider_name = forms.CharField()
|
provider_name = forms.CharField()
|
||||||
|
authorization_flow = forms.ModelChoiceField(
|
||||||
|
queryset=Flow.objects.filter(designation=FlowDesignation.AUTHORIZATION)
|
||||||
|
)
|
||||||
metadata = forms.FileField(
|
metadata = forms.FileField(
|
||||||
validators=[FileExtensionValidator(allowed_extensions=["xml"])]
|
validators=[FileExtensionValidator(allowed_extensions=["xml"])]
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Generated by Django 3.1.4 on 2020-12-30 21:12
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("authentik_providers_saml", "0009_auto_20201112_2016"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="samlprovider",
|
||||||
|
name="audience",
|
||||||
|
field=models.TextField(
|
||||||
|
blank=True,
|
||||||
|
default="",
|
||||||
|
help_text="Value of the audience restriction field of the asseration. When left empty, no audience restriction will be added.",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -42,7 +42,13 @@ class SAMLProvider(Provider):
|
||||||
acs_url = models.URLField(verbose_name=_("ACS URL"))
|
acs_url = models.URLField(verbose_name=_("ACS URL"))
|
||||||
audience = models.TextField(
|
audience = models.TextField(
|
||||||
default="",
|
default="",
|
||||||
help_text=_("Value of the audience restriction field of the asseration."),
|
blank=True,
|
||||||
|
help_text=_(
|
||||||
|
(
|
||||||
|
"Value of the audience restriction field of the asseration. When left empty, "
|
||||||
|
"no audience restriction will be added."
|
||||||
|
)
|
||||||
|
),
|
||||||
)
|
)
|
||||||
issuer = models.TextField(
|
issuer = models.TextField(
|
||||||
help_text=_("Also known as EntityID"), default="authentik"
|
help_text=_("Also known as EntityID"), default="authentik"
|
||||||
|
|
|
@ -127,11 +127,14 @@ class AssertionProcessor:
|
||||||
conditions = Element(f"{{{NS_SAML_ASSERTION}}}Conditions")
|
conditions = Element(f"{{{NS_SAML_ASSERTION}}}Conditions")
|
||||||
conditions.attrib["NotBefore"] = self._valid_not_before
|
conditions.attrib["NotBefore"] = self._valid_not_before
|
||||||
conditions.attrib["NotOnOrAfter"] = self._valid_not_on_or_after
|
conditions.attrib["NotOnOrAfter"] = self._valid_not_on_or_after
|
||||||
audience_restriction = SubElement(
|
if self.provider.audience != "":
|
||||||
conditions, f"{{{NS_SAML_ASSERTION}}}AudienceRestriction"
|
audience_restriction = SubElement(
|
||||||
)
|
conditions, f"{{{NS_SAML_ASSERTION}}}AudienceRestriction"
|
||||||
audience = SubElement(audience_restriction, f"{{{NS_SAML_ASSERTION}}}Audience")
|
)
|
||||||
audience.text = self.provider.audience
|
audience = SubElement(
|
||||||
|
audience_restriction, f"{{{NS_SAML_ASSERTION}}}Audience"
|
||||||
|
)
|
||||||
|
audience.text = self.provider.audience
|
||||||
return conditions
|
return conditions
|
||||||
|
|
||||||
def get_name_id(self) -> Element:
|
def get_name_id(self) -> Element:
|
||||||
|
|
|
@ -5,6 +5,7 @@ from typing import Optional
|
||||||
import xmlsec
|
import xmlsec
|
||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
from cryptography.x509 import load_pem_x509_certificate
|
from cryptography.x509 import load_pem_x509_certificate
|
||||||
|
from defusedxml.lxml import fromstring
|
||||||
from lxml import etree # nosec
|
from lxml import etree # nosec
|
||||||
from structlog import get_logger
|
from structlog import get_logger
|
||||||
|
|
||||||
|
@ -23,6 +24,8 @@ LOGGER = get_logger()
|
||||||
|
|
||||||
def format_pem_certificate(unformatted_cert: str) -> str:
|
def format_pem_certificate(unformatted_cert: str) -> str:
|
||||||
"""Format single, inline certificate into PEM Format"""
|
"""Format single, inline certificate into PEM Format"""
|
||||||
|
# Ensure that all linebreaks are gone
|
||||||
|
unformatted_cert = unformatted_cert.replace("\n", "")
|
||||||
chunks, chunk_size = len(unformatted_cert), 64
|
chunks, chunk_size = len(unformatted_cert), 64
|
||||||
lines = [PEM_HEADER]
|
lines = [PEM_HEADER]
|
||||||
for i in range(0, chunks, chunk_size):
|
for i in range(0, chunks, chunk_size):
|
||||||
|
@ -52,10 +55,14 @@ class ServiceProviderMetadata:
|
||||||
provider.issuer = self.entity_id
|
provider.issuer = self.entity_id
|
||||||
provider.sp_binding = self.acs_binding
|
provider.sp_binding = self.acs_binding
|
||||||
provider.acs_url = self.acs_location
|
provider.acs_url = self.acs_location
|
||||||
if self.signing_keypair:
|
if self.signing_keypair and self.auth_n_request_signed:
|
||||||
self.signing_keypair.name = f"Provider {name} - SAML Signing Certificate"
|
self.signing_keypair.name = f"Provider {name} - SAML Signing Certificate"
|
||||||
self.signing_keypair.save()
|
self.signing_keypair.save()
|
||||||
provider.signing_kp = self.signing_keypair
|
provider.verification_kp = self.signing_keypair
|
||||||
|
if self.assertion_signed:
|
||||||
|
provider.signing_kp = CertificateKeyPair.objects.exclude(
|
||||||
|
key_data__iexact=""
|
||||||
|
).first()
|
||||||
return provider
|
return provider
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,7 +111,7 @@ class ServiceProviderMetadataParser:
|
||||||
|
|
||||||
def parse(self, raw_xml: str) -> ServiceProviderMetadata:
|
def parse(self, raw_xml: str) -> ServiceProviderMetadata:
|
||||||
"""Parse raw XML to ServiceProviderMetadata"""
|
"""Parse raw XML to ServiceProviderMetadata"""
|
||||||
root = etree.fromstring(raw_xml) # nosec
|
root = fromstring(raw_xml.encode())
|
||||||
|
|
||||||
entity_id = root.attrib["entityID"]
|
entity_id = root.attrib["entityID"]
|
||||||
sp_sso_descriptors = root.findall(f"{{{NS_SAML_METADATA}}}SPSSODescriptor")
|
sp_sso_descriptors = root.findall(f"{{{NS_SAML_METADATA}}}SPSSODescriptor")
|
||||||
|
|
|
@ -84,7 +84,9 @@ class TestServiceProviderMetadataParser(TestCase):
|
||||||
provider.issuer, "http://localhost:8080/apps/user_saml/saml/metadata"
|
provider.issuer, "http://localhost:8080/apps/user_saml/saml/metadata"
|
||||||
)
|
)
|
||||||
self.assertEqual(provider.sp_binding, SAMLBindings.POST)
|
self.assertEqual(provider.sp_binding, SAMLBindings.POST)
|
||||||
self.assertEqual(provider.signing_kp.certificate_data, CERT)
|
self.assertEqual(provider.verification_kp.certificate_data, CERT)
|
||||||
|
self.assertIsNotNone(provider.signing_kp)
|
||||||
|
self.assertEqual(provider.audience, "")
|
||||||
|
|
||||||
def test_with_signing_cert_invalid_signature(self):
|
def test_with_signing_cert_invalid_signature(self):
|
||||||
"""Test Metadata with signing cert (invalid signature)"""
|
"""Test Metadata with signing cert (invalid signature)"""
|
||||||
|
|
|
@ -270,8 +270,14 @@ class MetadataImportView(LoginRequiredMixin, FormView):
|
||||||
form.cleaned_data["metadata"].read().decode()
|
form.cleaned_data["metadata"].read().decode()
|
||||||
)
|
)
|
||||||
provider = metadata.to_provider(form.cleaned_data["provider_name"])
|
provider = metadata.to_provider(form.cleaned_data["provider_name"])
|
||||||
|
provider.authorization_flow = form.cleaned_data["authorization_flow"]
|
||||||
provider.save()
|
provider.save()
|
||||||
messages.success(self.request, _("Successfully created Provider"))
|
messages.success(self.request, _("Successfully created Provider"))
|
||||||
except ValueError:
|
except ValueError as exc:
|
||||||
messages.error(self.request, _("Failed to import Metadata."))
|
LOGGER.warning(exc)
|
||||||
|
messages.error(
|
||||||
|
self.request,
|
||||||
|
_("Failed to import Metadata: %(message)s" % {"message": str(exc)}),
|
||||||
|
)
|
||||||
|
return super().form_invalid(form)
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
|
@ -8004,9 +8004,9 @@ definitions:
|
||||||
minLength: 1
|
minLength: 1
|
||||||
audience:
|
audience:
|
||||||
title: Audience
|
title: Audience
|
||||||
description: Value of the audience restriction field of the asseration.
|
description: Value of the audience restriction field of the asseration. When
|
||||||
|
left empty, no audience restriction will be added.
|
||||||
type: string
|
type: string
|
||||||
minLength: 1
|
|
||||||
issuer:
|
issuer:
|
||||||
title: Issuer
|
title: Issuer
|
||||||
description: Also known as EntityID
|
description: Also known as EntityID
|
||||||
|
|
|
@ -968,9 +968,9 @@
|
||||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||||
},
|
},
|
||||||
"construct-style-sheets-polyfill": {
|
"construct-style-sheets-polyfill": {
|
||||||
"version": "2.4.3",
|
"version": "2.4.6",
|
||||||
"resolved": "https://registry.npmjs.org/construct-style-sheets-polyfill/-/construct-style-sheets-polyfill-2.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/construct-style-sheets-polyfill/-/construct-style-sheets-polyfill-2.4.6.tgz",
|
||||||
"integrity": "sha512-ECo96zFPsdghrMJmJ0vomcHsqLOIYpudobcNCIPeMubyFzBcLCfljuY0oFA3DD7btiFqB0sZ+0szbsiE8I24VA=="
|
"integrity": "sha512-lU0to7dFDjKslMF+M5NUa4s0RQMBRVyZMXvD/vp7vmjdEPgziTkHSfZHQxfoIvVWajWRJUVJMLfrMwcx8fTh4A=="
|
||||||
},
|
},
|
||||||
"copy-descriptor": {
|
"copy-descriptor": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
"@types/codemirror": "0.0.103",
|
"@types/codemirror": "0.0.103",
|
||||||
"chart.js": "^2.9.4",
|
"chart.js": "^2.9.4",
|
||||||
"codemirror": "^5.59.0",
|
"codemirror": "^5.59.0",
|
||||||
"construct-style-sheets-polyfill": "^2.4.3",
|
"construct-style-sheets-polyfill": "^2.4.6",
|
||||||
"flowchart.js": "^1.15.0",
|
"flowchart.js": "^1.15.0",
|
||||||
"lit-element": "^2.4.0",
|
"lit-element": "^2.4.0",
|
||||||
"lit-html": "^1.3.0",
|
"lit-html": "^1.3.0",
|
||||||
|
|
|
@ -8,7 +8,7 @@ export interface EventUser {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EventContext {
|
export interface EventContext {
|
||||||
[key: string]: EventContext | string | number;
|
[key: string]: EventContext | string | number | string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Event {
|
export class Event {
|
||||||
|
|
|
@ -137,6 +137,9 @@ select[multiple] {
|
||||||
--pf-c-table--cell--Color: var(--ak-dark-foreground);
|
--pf-c-table--cell--Color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
.pf-c-table__text {
|
.pf-c-table__text {
|
||||||
|
color: var(--ak-dark-foreground);
|
||||||
|
}
|
||||||
|
.pf-c-table__sort:not(.pf-m-selected) .pf-c-table__button .pf-c-table__text {
|
||||||
color: var(--ak-dark-foreground) !important;
|
color: var(--ak-dark-foreground) !important;
|
||||||
}
|
}
|
||||||
.pf-c-table__sort-indicator i {
|
.pf-c-table__sort-indicator i {
|
||||||
|
|
|
@ -15,10 +15,10 @@ export const SIDEBAR_ITEMS: SidebarItem[] = [
|
||||||
}),
|
}),
|
||||||
new SidebarItem("Administration").children(
|
new SidebarItem("Administration").children(
|
||||||
new SidebarItem("Applications", "/applications").activeWhen(
|
new SidebarItem("Applications", "/applications").activeWhen(
|
||||||
`^/applications/(?<slug>${SLUG_REGEX})/$`
|
`^/applications/(?<slug>${SLUG_REGEX})$`
|
||||||
),
|
),
|
||||||
new SidebarItem("Sources", "/administration/sources/").activeWhen(
|
new SidebarItem("Sources", "/administration/sources/").activeWhen(
|
||||||
`^/sources/(?<slug>${SLUG_REGEX})/$`,
|
`^/sources/(?<slug>${SLUG_REGEX})$`,
|
||||||
),
|
),
|
||||||
new SidebarItem("Providers", "/administration/providers/"),
|
new SidebarItem("Providers", "/administration/providers/"),
|
||||||
new SidebarItem("Outposts", "/administration/outposts/"),
|
new SidebarItem("Outposts", "/administration/outposts/"),
|
||||||
|
|
|
@ -8,7 +8,7 @@ import "../elements/sidebar/SidebarHamburger";
|
||||||
|
|
||||||
export abstract class Interface extends LitElement {
|
export abstract class Interface extends LitElement {
|
||||||
@property({type: Boolean})
|
@property({type: Boolean})
|
||||||
sidebarOpen?: boolean;
|
sidebarOpen = true;
|
||||||
|
|
||||||
abstract get sidebar(): SidebarItem[];
|
abstract get sidebar(): SidebarItem[];
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ export class ApplicationListPage extends TablePage<Application> {
|
||||||
${item.meta_icon ?
|
${item.meta_icon ?
|
||||||
html`<img class="app-icon pf-c-avatar" src="${item.meta_icon}" alt="${gettext("Application Icon")}">` :
|
html`<img class="app-icon pf-c-avatar" src="${item.meta_icon}" alt="${gettext("Application Icon")}">` :
|
||||||
html`<i class="pf-icon pf-icon-arrow"></i>`}`,
|
html`<i class="pf-icon pf-icon-arrow"></i>`}`,
|
||||||
html`<a href="#/applications/${item.slug}/">
|
html`<a href="#/applications/${item.slug}">
|
||||||
<div>
|
<div>
|
||||||
${item.name}
|
${item.name}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -94,6 +94,29 @@ export class EventInfo extends LitElement {
|
||||||
<code>${this.event.context.expression}</code>
|
<code>${this.event.context.expression}</code>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
case "policy_execution":
|
||||||
|
return html`<div class="pf-l-flex">
|
||||||
|
<div class="pf-l-flex__item">
|
||||||
|
<h3>${gettext("Request")}</h3>
|
||||||
|
<ul class="pf-c-list">
|
||||||
|
<li>${gettext("Object")}: ${(this.event.context.request as EventContext).obj as string}</li>
|
||||||
|
<li><span>${gettext("Context")}: <code>${JSON.stringify((this.event.context.request as EventContext).context)}</code></span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="pf-l-flex__item">
|
||||||
|
<h3>${gettext("Result")}</h3>
|
||||||
|
<ul class="pf-c-list">
|
||||||
|
<li>${gettext("Passing")}: ${(this.event.context.result as EventContext).passing}</li>
|
||||||
|
<li>${gettext("Messages")}:
|
||||||
|
<ul class="pf-c-list">
|
||||||
|
${((this.event.context.result as EventContext).messages as string[]).map(msg => {
|
||||||
|
return html`<li>${msg}</li>`;
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
case "configuration_error":
|
case "configuration_error":
|
||||||
return html`<h3>${this.event.context.message}</h3>`;
|
return html`<h3>${this.event.context.message}</h3>`;
|
||||||
case "update_available":
|
case "update_available":
|
||||||
|
|
|
@ -30,6 +30,12 @@ export class SiteShell extends LitElement {
|
||||||
::slotted(*) {
|
::slotted(*) {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
.pf-l-bullseye {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
BackdropStyle,
|
BackdropStyle,
|
||||||
BullseyeStyle,
|
BullseyeStyle,
|
||||||
|
|
Reference in New Issue