Merge branch 'master' into ldap-groupOfNames

This commit is contained in:
Jens Langhammer 2021-02-05 14:52:39 +01:00
commit ef70e93bbd
15 changed files with 245 additions and 104 deletions

15
Pipfile.lock generated
View file

@ -74,17 +74,17 @@
}, },
"boto3": { "boto3": {
"hashes": [ "hashes": [
"sha256:58a440f4c96a1f2f076577c7085237854ba6db41a7c91e4a33fb30068f8d4692" "sha256:1a282c1cd7d5028cbb3a75d747df32162295253f55d263ac85840e264830963b"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.17.1" "version": "==1.17.2"
}, },
"botocore": { "botocore": {
"hashes": [ "hashes": [
"sha256:9488ba35e2d4d17375f67b8fd300df5ec2f8317a2924032901009c999d563b59", "sha256:7442fdbbdc841bfac7f94f92ecb807de070e32ed205743eb72d4ea27c5e8e778",
"sha256:e533b1da7af2e4d69d314375ec7052d95271a878a6040c3af1facd59bfbb7f3b" "sha256:bf587b044983a91a0124cc133ff167b8528c19fbbc8f0b956d9a1ac256cad7d7"
], ],
"version": "==1.20.1" "version": "==1.20.2"
}, },
"cachetools": { "cachetools": {
"hashes": [ "hashes": [
@ -1293,10 +1293,11 @@
}, },
"autopep8": { "autopep8": {
"hashes": [ "hashes": [
"sha256:d21d3901cb0da6ebd1e83fc9b0dfbde8b46afc2ede4fe32fbda0c7c6118ca094" "sha256:9e136c472c475f4ee4978b51a88a494bfcd4e3ed17950a44a988d9e434837bea",
"sha256:cae4bc0fb616408191af41d062d7ec7ef8679c7f27b068875ca3a9e2878d5443"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.5.4" "version": "==1.5.5"
}, },
"bandit": { "bandit": {
"hashes": [ "hashes": [

View file

@ -272,17 +272,24 @@ class NotificationTransport(models.Model):
def send_email(self, notification: "Notification") -> list[str]: def send_email(self, notification: "Notification") -> list[str]:
"""Send notification via global email configuration""" """Send notification via global email configuration"""
body_trunc = ( subject = "authentik Notification: "
(notification.body[:75] + "..") key_value = {}
if len(notification.body) > 75 if notification.event:
else notification.body subject += notification.event.action
) for key, value in notification.event.context.items():
if not isinstance(value, str):
continue
key_value[key] = value
else:
subject += notification.body[:75]
mail = TemplateEmailMessage( mail = TemplateEmailMessage(
subject=f"authentik Notification: {body_trunc}", subject=subject,
template_name="email/generic.html", template_name="email/generic.html",
to=[notification.user.email], to=[notification.user.email],
template_context={ template_context={
"title": subject,
"body": notification.body, "body": notification.body,
"key_value": key_value,
}, },
) )
# Email is sent directly here, as the call to send() should have been from a task. # Email is sent directly here, as the call to send() should have been from a task.

View file

@ -23,11 +23,12 @@ class OAuth2Error(SentryIgnoredException):
def __repr__(self) -> str: def __repr__(self) -> str:
return self.error return self.error
def to_event(self, message: Optional[str] = None) -> Event: def to_event(self, message: Optional[str] = None, **kwargs) -> Event:
"""Create configuration_error Event and save it.""" """Create configuration_error Event and save it."""
return Event.new( return Event.new(
EventAction.CONFIGURATION_ERROR, EventAction.CONFIGURATION_ERROR,
message=message or self.description, message=message or self.description,
**kwargs,
) )
@ -49,10 +50,11 @@ class RedirectUriError(OAuth2Error):
self.provided_uri = provided_uri self.provided_uri = provided_uri
self.allowed_uris = allowed_uris self.allowed_uris = allowed_uris
def to_event(self) -> Event: def to_event(self, **kwargs) -> Event:
return super().to_event( return super().to_event(
f"Invalid redirect URI was used. Client used '{self.provided_uri}'. " f"Invalid redirect URI was used. Client used '{self.provided_uri}'. "
f"Allowed redirect URIs are {','.join(self.allowed_uris)}" f"Allowed redirect URIs are {','.join(self.allowed_uris)}",
**kwargs,
) )
@ -68,8 +70,10 @@ class ClientIdError(OAuth2Error):
super().__init__() super().__init__()
self.client_id = client_id self.client_id = client_id
def to_event(self) -> Event: def to_event(self, **kwargs) -> Event:
return super().to_event(f"Invalid client identifier: {self.client_id}.") return super().to_event(
f"Invalid client identifier: {self.client_id}.", **kwargs
)
class UserAuthError(OAuth2Error): class UserAuthError(OAuth2Error):

View file

@ -256,12 +256,12 @@ class OAuthFulfillmentStage(StageView):
).from_http(self.request) ).from_http(self.request)
return redirect(self.create_response_uri()) return redirect(self.create_response_uri())
except (ClientIdError, RedirectUriError) as error: except (ClientIdError, RedirectUriError) as error:
error.to_event().from_http(request) error.to_event(application=application).from_http(request)
self.executor.stage_invalid() self.executor.stage_invalid()
# pylint: disable=no-member # pylint: disable=no-member
return bad_request_message(request, error.description, title=error.error) return bad_request_message(request, error.description, title=error.error)
except AuthorizeError as error: except AuthorizeError as error:
error.to_event().from_http(request) error.to_event(application=application).from_http(request)
self.executor.stage_invalid() self.executor.stage_invalid()
return redirect(error.create_uri()) return redirect(error.create_uri())
@ -379,7 +379,7 @@ class AuthorizationFlowInitView(PolicyAccessView):
try: try:
self.params = OAuthAuthorizationParams.from_request(self.request) self.params = OAuthAuthorizationParams.from_request(self.request)
except AuthorizeError as error: except AuthorizeError as error:
error.to_event().from_http(self.request) error.to_event(redirect_uri=error.redirect_uri).from_http(self.request)
raise RequestValidationError(redirect(error.create_uri())) raise RequestValidationError(redirect(error.create_uri()))
except OAuth2Error as error: except OAuth2Error as error:
error.to_event().from_http(self.request) error.to_event().from_http(self.request)
@ -396,7 +396,7 @@ class AuthorizationFlowInitView(PolicyAccessView):
self.params.grant_type, self.params.grant_type,
self.params.state, self.params.state,
) )
error.to_event().from_http(self.request) error.to_event(redirect_uri=error.redirect_uri).from_http(self.request)
raise RequestValidationError(redirect(error.create_uri())) raise RequestValidationError(redirect(error.create_uri()))
def resolve_provider_application(self): def resolve_provider_application(self):

View file

@ -1,5 +1,7 @@
{% extends "email/base.html" %} {% extends "email/base.html" %}
{% load i18n %}
{% block content %} {% block content %}
<tr> <tr>
<td class="alert alert-brand"> <td class="alert alert-brand">
@ -14,6 +16,29 @@
{{ body }} {{ body }}
</td> </td>
</tr> </tr>
{% if key_value %}
<tr>
<td class="content-block aligncenter">
<table class="invoice">
<tr>
<td>{% trans "Additional Information" %}</td>
</tr>
<tr>
<td>
<table class="invoice-items" cellpadding="0" cellspacing="0">
{% for key, value in key_value.items %}
<tr>
<td>{{ key }}</td>
<td class="alignright">{{ value }}</td>
</tr>
{% endfor %}
</table>
</td>
</tr>
</table>
</td>
</tr>
{% endif %}
</table> </table>
</td> </td>
</tr> </tr>

122
web/package-lock.json generated
View file

@ -144,27 +144,27 @@
} }
}, },
"@sentry/browser": { "@sentry/browser": {
"version": "6.0.4", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.1.0.tgz",
"integrity": "sha512-DrlH53IPNZmW6XWT0Za7vGtIyKpm45An662xvXavI8LQQH0qhPU9mb7NcvecwDfs6jXEV2w5Y8rKjuu/J4QxAA==", "integrity": "sha512-t3y2TLXDWgvfknyH8eKj/9mghJfSEqItFyp74zPu1Src6kOPjkd4Sa7o4+bdkNgA8dIIOrDAhRUbB2sq4sWMCA==",
"requires": { "requires": {
"@sentry/core": "6.0.4", "@sentry/core": "6.1.0",
"@sentry/types": "6.0.4", "@sentry/types": "6.1.0",
"@sentry/utils": "6.0.4", "@sentry/utils": "6.1.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"dependencies": { "dependencies": {
"@sentry/types": { "@sentry/types": {
"version": "6.0.4", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.1.0.tgz",
"integrity": "sha512-VqmnhJPpPmsu4gMzSZw8UHgYlP1QSikMZ5X6E3q6zwmbWu+2oniQHD6xGB6PXv6uTo5zg2NseQEiWnEjJRUYWw==" "integrity": "sha512-kIaN52Fw5K+2mKRaHE2YluJ+F/qMGSUzZXIFDNdC6OUMXQ4TM8gZTrITXs8CLDm7cK8iCqFCtzKOjKK6KyOKAg=="
}, },
"@sentry/utils": { "@sentry/utils": {
"version": "6.0.4", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.1.0.tgz",
"integrity": "sha512-UOAz5p5IIntmIcmX04Cjk7l7+EwnuBn2S/rhNN92I1vDCaL010OmUZOHGHJExoXBE75zVh/LDssAPQTKXo0F+g==", "integrity": "sha512-6JAplzUOS6bEwfX0PDRZBbYRvn9EN22kZfcL0qGHtM9L0QQ5ybjbbVwOpbXgRkiZx++dQbzLFtelxnDhsbFG+Q==",
"requires": { "requires": {
"@sentry/types": "6.0.4", "@sentry/types": "6.1.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
} }
}, },
@ -176,48 +176,48 @@
} }
}, },
"@sentry/core": { "@sentry/core": {
"version": "6.0.4", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.1.0.tgz",
"integrity": "sha512-5+Xnk3jb0nkKYvgBV/kKWUqrNsNeM38r98ZRqfHrl69WoSrv+ynTsj8gn0tZO+VvhxUDRLOYvDha+QZgkYZt/w==", "integrity": "sha512-57mXkp3NoyxRycXrL+Ec6bYS6UYJZp9tYX0lUp5Ry2M0FxDZ3Q4drkjr8MIQOhBaQXP2ukSX4QTVLGMPm60zMw==",
"requires": { "requires": {
"@sentry/hub": "6.0.4", "@sentry/hub": "6.1.0",
"@sentry/minimal": "6.0.4", "@sentry/minimal": "6.1.0",
"@sentry/types": "6.0.4", "@sentry/types": "6.1.0",
"@sentry/utils": "6.0.4", "@sentry/utils": "6.1.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"dependencies": { "dependencies": {
"@sentry/hub": { "@sentry/hub": {
"version": "6.0.4", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.1.0.tgz",
"integrity": "sha512-gutuxH8M3CdElSbwqNq9G29MiNuGsPESB22w4k4wx+pc632bi6w0v53+BLjGO6wh2EMfHVWptgAYmojEk5yKQg==", "integrity": "sha512-JnBSCgNg3VHiMojUl5tCHU8iWPVuE+qqENIzG9A722oJms1kKWBvWl+yQzhWBNdgk5qeAY3F5UzKWJZkbJ6xow==",
"requires": { "requires": {
"@sentry/types": "6.0.4", "@sentry/types": "6.1.0",
"@sentry/utils": "6.0.4", "@sentry/utils": "6.1.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
} }
}, },
"@sentry/minimal": { "@sentry/minimal": {
"version": "6.0.4", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.1.0.tgz",
"integrity": "sha512-COL0tjznrCaatOPH2eGgT1Y9vUUKJw+W0srCn5V1dHgRu3t00rGFXrcyOXQmHfEWmBaagt9lXEJCFaN7yMucVQ==", "integrity": "sha512-g6sfNKenL7wnsr/tibp8nFiMv/XRH0s0Pt4p151npmNI+SmjuUz3GGYEXk8ChCyaKldYKilkNOFdVXJxUf5gZw==",
"requires": { "requires": {
"@sentry/hub": "6.0.4", "@sentry/hub": "6.1.0",
"@sentry/types": "6.0.4", "@sentry/types": "6.1.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
} }
}, },
"@sentry/types": { "@sentry/types": {
"version": "6.0.4", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.1.0.tgz",
"integrity": "sha512-VqmnhJPpPmsu4gMzSZw8UHgYlP1QSikMZ5X6E3q6zwmbWu+2oniQHD6xGB6PXv6uTo5zg2NseQEiWnEjJRUYWw==" "integrity": "sha512-kIaN52Fw5K+2mKRaHE2YluJ+F/qMGSUzZXIFDNdC6OUMXQ4TM8gZTrITXs8CLDm7cK8iCqFCtzKOjKK6KyOKAg=="
}, },
"@sentry/utils": { "@sentry/utils": {
"version": "6.0.4", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.1.0.tgz",
"integrity": "sha512-UOAz5p5IIntmIcmX04Cjk7l7+EwnuBn2S/rhNN92I1vDCaL010OmUZOHGHJExoXBE75zVh/LDssAPQTKXo0F+g==", "integrity": "sha512-6JAplzUOS6bEwfX0PDRZBbYRvn9EN22kZfcL0qGHtM9L0QQ5ybjbbVwOpbXgRkiZx++dQbzLFtelxnDhsbFG+Q==",
"requires": { "requires": {
"@sentry/types": "6.0.4", "@sentry/types": "6.1.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
} }
}, },
@ -229,12 +229,12 @@
} }
}, },
"@sentry/hub": { "@sentry/hub": {
"version": "6.0.4", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.1.0.tgz",
"integrity": "sha512-gutuxH8M3CdElSbwqNq9G29MiNuGsPESB22w4k4wx+pc632bi6w0v53+BLjGO6wh2EMfHVWptgAYmojEk5yKQg==", "integrity": "sha512-JnBSCgNg3VHiMojUl5tCHU8iWPVuE+qqENIzG9A722oJms1kKWBvWl+yQzhWBNdgk5qeAY3F5UzKWJZkbJ6xow==",
"requires": { "requires": {
"@sentry/types": "6.0.4", "@sentry/types": "6.1.0",
"@sentry/utils": "6.0.4", "@sentry/utils": "6.1.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"dependencies": { "dependencies": {
@ -246,12 +246,12 @@
} }
}, },
"@sentry/minimal": { "@sentry/minimal": {
"version": "6.0.4", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.1.0.tgz",
"integrity": "sha512-COL0tjznrCaatOPH2eGgT1Y9vUUKJw+W0srCn5V1dHgRu3t00rGFXrcyOXQmHfEWmBaagt9lXEJCFaN7yMucVQ==", "integrity": "sha512-g6sfNKenL7wnsr/tibp8nFiMv/XRH0s0Pt4p151npmNI+SmjuUz3GGYEXk8ChCyaKldYKilkNOFdVXJxUf5gZw==",
"requires": { "requires": {
"@sentry/hub": "6.0.4", "@sentry/hub": "6.1.0",
"@sentry/types": "6.0.4", "@sentry/types": "6.1.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"dependencies": { "dependencies": {
@ -263,14 +263,14 @@
} }
}, },
"@sentry/tracing": { "@sentry/tracing": {
"version": "6.0.4", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.1.0.tgz",
"integrity": "sha512-/da81kbkpiA17kAVjW8ZdpASwgsdYUXZg3jdOfbV07HK/6aFkfOF8/sHKMjVG2Iy4oaRel/F7l6/wf+XlKbBMw==", "integrity": "sha512-s6a4Ra3hHn4awiNz4fOEK6TCV2w2iLcxdppijcYEB7S/1rJpmqZgHWDicqufbOmVMOLmyKLEQ7w+pZq3TR3WgQ==",
"requires": { "requires": {
"@sentry/hub": "6.0.4", "@sentry/hub": "6.1.0",
"@sentry/minimal": "6.0.4", "@sentry/minimal": "6.1.0",
"@sentry/types": "6.0.4", "@sentry/types": "6.1.0",
"@sentry/utils": "6.0.4", "@sentry/utils": "6.1.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"dependencies": { "dependencies": {
@ -282,16 +282,16 @@
} }
}, },
"@sentry/types": { "@sentry/types": {
"version": "6.0.4", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.1.0.tgz",
"integrity": "sha512-VqmnhJPpPmsu4gMzSZw8UHgYlP1QSikMZ5X6E3q6zwmbWu+2oniQHD6xGB6PXv6uTo5zg2NseQEiWnEjJRUYWw==" "integrity": "sha512-kIaN52Fw5K+2mKRaHE2YluJ+F/qMGSUzZXIFDNdC6OUMXQ4TM8gZTrITXs8CLDm7cK8iCqFCtzKOjKK6KyOKAg=="
}, },
"@sentry/utils": { "@sentry/utils": {
"version": "6.0.4", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.0.4.tgz", "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.1.0.tgz",
"integrity": "sha512-UOAz5p5IIntmIcmX04Cjk7l7+EwnuBn2S/rhNN92I1vDCaL010OmUZOHGHJExoXBE75zVh/LDssAPQTKXo0F+g==", "integrity": "sha512-6JAplzUOS6bEwfX0PDRZBbYRvn9EN22kZfcL0qGHtM9L0QQ5ybjbbVwOpbXgRkiZx++dQbzLFtelxnDhsbFG+Q==",
"requires": { "requires": {
"@sentry/types": "6.0.4", "@sentry/types": "6.1.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
}, },
"dependencies": { "dependencies": {

View file

@ -12,8 +12,8 @@
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "^5.15.2", "@fortawesome/fontawesome-free": "^5.15.2",
"@patternfly/patternfly": "^4.80.3", "@patternfly/patternfly": "^4.80.3",
"@sentry/browser": "^6.0.4", "@sentry/browser": "^6.1.0",
"@sentry/tracing": "^6.0.4", "@sentry/tracing": "^6.1.0",
"@types/chart.js": "^2.9.30", "@types/chart.js": "^2.9.30",
"@types/codemirror": "0.0.108", "@types/codemirror": "0.0.108",
"chart.js": "^2.9.4", "chart.js": "^2.9.4",

View file

@ -13,7 +13,9 @@ export class Client {
if (query) { if (query) {
const queryString = Object.keys(query) const queryString = Object.keys(query)
.filter((k) => query[k] !== null) .filter((k) => query[k] !== null)
.map((k) => encodeURIComponent(k) + "=" + encodeURIComponent(query[k])) // we default to a string in query[k] as we've filtered out the null above
// this is just for type-hinting
.map((k) => encodeURIComponent(k) + "=" + encodeURIComponent(query[k] || ""))
.join("&"); .join("&");
builtUrl += `?${queryString}`; builtUrl += `?${queryString}`;
} }

View file

@ -169,6 +169,13 @@ select[multiple] {
.pf-c-table__toggle-icon { .pf-c-table__toggle-icon {
color: var(--ak-dark-foreground); color: var(--ak-dark-foreground);
} }
/* expandable elements */
.pf-c-expandable-section__toggle-text {
color: var(--ak-dark-foreground);
}
.pf-c-expandable-section__toggle-icon {
color: var(--ak-dark-foreground);
}
/* inputs */ /* inputs */
.pf-c-input-group { .pf-c-input-group {
--pf-c-input-group--BackgroundColor: transparent; --pf-c-input-group--BackgroundColor: transparent;

View file

@ -0,0 +1,36 @@
import { gettext } from "django";
import { CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import { COMMON_STYLES } from "../common/styles";
@customElement("ak-expand")
export class Expand extends LitElement {
@property({ type: Boolean })
expanded = false;
@property()
textOpen = "Show less";
@property()
textClosed = "Show more";
static get styles(): CSSResult[] {
return COMMON_STYLES;
}
render(): TemplateResult {
console.log(this.expanded);
return html`<div class="pf-c-expandable-section ${this.expanded ? "pf-m-expanded" : ""}">
<button type="button" class="pf-c-expandable-section__toggle" aria-expanded="${this.expanded}" @click=${() => {
this.expanded = !this.expanded;
}}>
<span class="pf-c-expandable-section__toggle-icon">
<i class="fas fa-angle-right" aria-hidden="true"></i>
</span>
<span class="pf-c-expandable-section__toggle-text">${gettext(this.expanded ? this.textOpen : this.textClosed)}</span>
</button>
<slot ?hidden=${!this.expanded} class="pf-c-expandable-section__content"></slot>
</div>`;
}
}

View file

@ -2,6 +2,7 @@ import { html, TemplateResult } from "lit-html";
export const SLUG_REGEX = "[-a-zA-Z0-9_]+"; export const SLUG_REGEX = "[-a-zA-Z0-9_]+";
export const ID_REGEX = "\\d+"; export const ID_REGEX = "\\d+";
export const UUID_REGEX = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
export class Route { export class Route {
url: RegExp; url: RegExp;

View file

@ -1,3 +1,4 @@
import { gettext } from "django";
import { html, TemplateResult } from "lit-html"; import { html, TemplateResult } from "lit-html";
import { ifDefined } from "lit-html/directives/if-defined"; import { ifDefined } from "lit-html/directives/if-defined";
import { Table } from "./Table"; import { Table } from "./Table";
@ -26,9 +27,9 @@ export abstract class TablePage<T> extends Table<T> {
<div class="pf-c-content"> <div class="pf-c-content">
<h1> <h1>
<i class="${this.pageIcon()}"></i> <i class="${this.pageIcon()}"></i>
${this.pageTitle()} ${gettext(this.pageTitle())}
</h1> </h1>
${description ? html`<p>${description}</p>` : html``} ${description ? html`<p>${gettext(description)}</p>` : html``}
</div> </div>
</section> </section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile"> <section class="pf-c-page__main-section pf-m-no-padding-mobile">

View file

@ -5,6 +5,7 @@ import { Event, EventContext } from "../../api/Events";
import { Flow } from "../../api/Flows"; import { Flow } from "../../api/Flows";
import { COMMON_STYLES } from "../../common/styles"; import { COMMON_STYLES } from "../../common/styles";
import "../../elements/Spinner"; import "../../elements/Spinner";
import "../../elements/Expand";
import { SpinnerSize } from "../../elements/Spinner"; import { SpinnerSize } from "../../elements/Spinner";
@customElement("ak-event-info") @customElement("ak-event-info")
@ -76,21 +77,21 @@ export class EventInfo extends LitElement {
<div class="pf-l-flex__item"> <div class="pf-l-flex__item">
<h3>${gettext("Using flow")}</h3> <h3>${gettext("Using flow")}</h3>
<span>${until(Flow.list({ <span>${until(Flow.list({
flow_uuid: this.event.context.flow as string, flow_uuid: this.event.context.flow as string,
}).then(resp => { }).then(resp => {
return html`<a href="#/flows/${resp.results[0].slug}">${resp.results[0].name}</a>`; return html`<a href="#/flows/${resp.results[0].slug}">${resp.results[0].name}</a>`;
}), html`<ak-spinner size=${SpinnerSize.Medium}></ak-spinner>`)}</span> }), html`<ak-spinner size=${SpinnerSize.Medium}></ak-spinner>`)}
</span>
</div> </div>
</div>`; </div>`;
case "login_failed": case "login_failed":
return html` return html`
<h3>${gettext(`Attempted to log in as ${this.event.context.username}`)}</h3> <h3>${gettext(`Attempted to log in as ${this.event.context.username}`)}</h3>
`; <ak-expand>${this.defaultResponse()}</ak-expand>`;
case "token_view": case "token_view":
return html` return html`
<h3>${gettext("Token:")}</h3><hr> <h3>${gettext("Token:")}</h3><hr>
${this.getModelInfo(this.event.context.token as EventContext)} ${this.getModelInfo(this.event.context.token as EventContext)}`;
`;
case "property_mapping_exception": case "property_mapping_exception":
return html`<div class="pf-l-flex"> return html`<div class="pf-l-flex">
<div class="pf-l-flex__item"> <div class="pf-l-flex__item">
@ -101,7 +102,8 @@ export class EventInfo extends LitElement {
<h3>${gettext("Expression")}</h3> <h3>${gettext("Expression")}</h3>
<code>${this.event.context.expression}</code> <code>${this.event.context.expression}</code>
</div> </div>
</div>`; </div>
<ak-expand>${this.defaultResponse()}</ak-expand>`;
case "policy_exception": case "policy_exception":
return html`<div class="pf-l-flex"> return html`<div class="pf-l-flex">
<div class="pf-l-flex__item"> <div class="pf-l-flex__item">
@ -119,7 +121,8 @@ export class EventInfo extends LitElement {
<h3>${gettext("Exception")}</h3> <h3>${gettext("Exception")}</h3>
<code>${this.event.context.message || this.event.context.error}</code> <code>${this.event.context.message || this.event.context.error}</code>
</div> </div>
</div>`; </div>
<ak-expand>${this.defaultResponse()}</ak-expand>`;
case "policy_execution": case "policy_execution":
return html`<div class="pf-l-flex"> return html`<div class="pf-l-flex">
<div class="pf-l-flex__item"> <div class="pf-l-flex__item">
@ -140,21 +143,23 @@ export class EventInfo extends LitElement {
<li>${gettext("Messages")}: <li>${gettext("Messages")}:
<ul class="pf-c-list"> <ul class="pf-c-list">
${((this.event.context.result as EventContext).messages as string[]).map(msg => { ${((this.event.context.result as EventContext).messages as string[]).map(msg => {
return html`<li>${msg}</li>`; return html`<li>${msg}</li>`;
})} })}
</ul> </ul>
</li> </li>
</ul> </ul>
</div> </div>
</div>`; </div>
<ak-expand>${this.defaultResponse()}</ak-expand>`;
case "configuration_error": case "configuration_error":
return html`<h3>${this.event.context.message}</h3>`; return html`<h3>${this.event.context.message}</h3>
<ak-expand>${this.defaultResponse()}</ak-expand>`;
case "update_available": case "update_available":
return html`<h3>${gettext("New version available!")}</h3> return html`<h3>${gettext("New version available!")}</h3>
<a target="_blank" href="https://github.com/BeryJu/authentik/releases/tag/version%2F${this.event.context.new_version}">${this.event.context.new_version}</a> <a target="_blank" href="https://github.com/BeryJu/authentik/releases/tag/version%2F${this.event.context.new_version}">${this.event.context.new_version}</a>
`; `;
// Action types which typically don't record any extra context. // Action types which typically don't record any extra context.
// If context is not empty, we fall to the default response. // If context is not empty, we fall to the default response.
case "login": case "login":
if ("using_source" in this.event.context) { if ("using_source" in this.event.context) {
return html`<div class="pf-l-flex"> return html`<div class="pf-l-flex">

View file

@ -0,0 +1,48 @@
import { gettext } from "django";
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import { Event } from "../../api/Events";
import { COMMON_STYLES } from "../../common/styles";
import "./EventInfo";
@customElement("ak-event-info-page")
export class EventInfoPage extends LitElement {
@property()
set args(value: { [key: string]: string }) {
this.eventID = value.id;
}
@property()
set eventID(value: string) {
Event.get(value).then((e) => (this.event = e));
}
@property({ attribute: false })
event?: Event;
static get styles(): CSSResult[] {
return COMMON_STYLES.concat(css`
.pf-c-card {
color: var(--ak-dark-foreground);
}
`);
}
render(): TemplateResult {
return html`<section class="pf-c-page__main-section pf-m-light">
<div class="pf-c-content">
<h1>
<i class="pf-icon pf-icon-catalog"></i>
${gettext(`Event ${this.event?.pk || ""}`)}
</h1>
</div>
</section>
<section class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-card__body">
<ak-event-info .event=${this.event}></ak-event-info>
</div>
</div>
</section>`;
}
}

View file

@ -1,5 +1,5 @@
import { html } from "lit-html"; import { html } from "lit-html";
import { Route, SLUG_REGEX, ID_REGEX } from "./elements/router/Route"; import { Route, SLUG_REGEX, ID_REGEX, UUID_REGEX } from "./elements/router/Route";
import "./pages/LibraryPage"; import "./pages/LibraryPage";
import "./pages/admin-overview/AdminOverviewPage"; import "./pages/admin-overview/AdminOverviewPage";
@ -8,6 +8,7 @@ import "./pages/applications/ApplicationViewPage";
import "./pages/sources/SourceViewPage"; import "./pages/sources/SourceViewPage";
import "./pages/flows/FlowViewPage"; import "./pages/flows/FlowViewPage";
import "./pages/events/EventListPage"; import "./pages/events/EventListPage";
import "./pages/events/EventInfoPage";
import "./pages/events/TransportListPage"; import "./pages/events/TransportListPage";
import "./pages/events/RuleListPage"; import "./pages/events/RuleListPage";
import "./pages/providers/ProviderListPage"; import "./pages/providers/ProviderListPage";
@ -35,6 +36,9 @@ export const ROUTES: Route[] = [
return html`<ak-flow-view .args=${args}></ak-flow-view>`; return html`<ak-flow-view .args=${args}></ak-flow-view>`;
}), }),
new Route(new RegExp("^/events/log$"), html`<ak-event-list></ak-event-list>`), new Route(new RegExp("^/events/log$"), html`<ak-event-list></ak-event-list>`),
new Route(new RegExp(`^/events/log/(?<id>${UUID_REGEX})$`)).then((args) => {
return html`<ak-event-info-page .args=${args}></ak-event-info-page>`;
}),
new Route(new RegExp("^/events/transports$"), html`<ak-event-transport-list></ak-event-transport-list>`), new Route(new RegExp("^/events/transports$"), html`<ak-event-transport-list></ak-event-transport-list>`),
new Route(new RegExp("^/events/rules$"), html`<ak-event-rule-list></ak-event-rule-list>`), new Route(new RegExp("^/events/rules$"), html`<ak-event-rule-list></ak-event-rule-list>`),
new Route(new RegExp("^/property-mappings$"), html`<ak-property-mapping-list></ak-property-mapping-list>`), new Route(new RegExp("^/property-mappings$"), html`<ak-property-mapping-list></ak-property-mapping-list>`),