diff --git a/authentik/admin/views/overview.py b/authentik/admin/views/overview.py index cc6d42f9c..021154f9a 100644 --- a/authentik/admin/views/overview.py +++ b/authentik/admin/views/overview.py @@ -18,7 +18,7 @@ class PolicyCacheClearView(AdminRequiredMixin, SuccessMessageMixin, FormView): """View to clear Policy cache""" form_class = PolicyCacheClearForm - + success_url = "/" template_name = "generic/form_non_model.html" success_message = _("Successfully cleared Policy cache") @@ -36,7 +36,7 @@ class FlowCacheClearView(AdminRequiredMixin, SuccessMessageMixin, FormView): """View to clear Flow cache""" form_class = FlowCacheClearForm - + success_url = "/" template_name = "generic/form_non_model.html" success_message = _("Successfully cleared Flow cache") diff --git a/authentik/events/geo.py b/authentik/events/geo.py index e6bbd6b54..b249a562e 100644 --- a/authentik/events/geo.py +++ b/authentik/events/geo.py @@ -10,7 +10,7 @@ from authentik.lib.config import CONFIG def get_geoip_reader() -> Optional[Reader]: """Get GeoIP Reader, if configured, otherwise none""" path = CONFIG.y("authentik.geoip") - if path == "": + if path == "" or not path: return None return Reader(path) diff --git a/authentik/flows/transfer/importer.py b/authentik/flows/transfer/importer.py index fd5ab82b6..04ed65220 100644 --- a/authentik/flows/transfer/importer.py +++ b/authentik/flows/transfer/importer.py @@ -157,7 +157,13 @@ class FlowImporter: entries = deepcopy(self.__import.entries) for entry in entries: model_app_label, model_name = entry.model.split(".") - model: SerializerModel = apps.get_model(model_app_label, model_name) + try: + model: SerializerModel = apps.get_model(model_app_label, model_name) + except LookupError: + self.logger.error( + "app or model does not exist", app=model_app_label, model=model_name + ) + return False # Validate each single entry try: serializer = self._validate_single(entry) diff --git a/authentik/sources/ldap/api.py b/authentik/sources/ldap/api.py index abe9e8c82..60551bc85 100644 --- a/authentik/sources/ldap/api.py +++ b/authentik/sources/ldap/api.py @@ -1,5 +1,6 @@ """Source API Views""" from datetime import datetime +from time import time from django.core.cache import cache from django.db.models.base import Model @@ -68,7 +69,7 @@ class LDAPSourceViewSet(ModelViewSet): def sync_status(self, request: Request, slug: str) -> Response: """Get source's sync status""" source = self.get_object() - last_sync = cache.get(source.state_cache_prefix("last_sync"), None) + last_sync = cache.get(source.state_cache_prefix("last_sync"), time()) return Response( LDAPSourceSyncStatusSerializer( {"last_sync": datetime.fromtimestamp(last_sync)} diff --git a/authentik/sources/ldap/password.py b/authentik/sources/ldap/password.py index fc26a0431..65c042b68 100644 --- a/authentik/sources/ldap/password.py +++ b/authentik/sources/ldap/password.py @@ -77,7 +77,8 @@ class LDAPPasswordChanger: """Change user's password""" user_dn = user.attributes.get(LDAP_DISTINGUISHED_NAME, None) if not user_dn: - raise AttributeError(f"User has no {LDAP_DISTINGUISHED_NAME} set.") + LOGGER.info(f"User has no {LDAP_DISTINGUISHED_NAME} set.") + return self._source.connection.extend.microsoft.modify_password(user_dn, password) def _ad_check_password_existing(self, password: str, user_dn: str) -> bool: diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f087d013a..e250ddcf8 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,6 +1,7 @@ trigger: - master - next + - version-* resources: - repo: self diff --git a/outpost/azure-pipelines.yml b/outpost/azure-pipelines.yml index 012784ce3..eb704da05 100644 --- a/outpost/azure-pipelines.yml +++ b/outpost/azure-pipelines.yml @@ -1,6 +1,7 @@ trigger: - master - next + - version-* variables: ${{ if startsWith(variables['Build.SourceBranch'], 'refs/pull/') }}: diff --git a/tests/e2e/utils.py b/tests/e2e/utils.py index 92aec6b13..1cc481221 100644 --- a/tests/e2e/utils.py +++ b/tests/e2e/utils.py @@ -203,11 +203,11 @@ def apply_migration(app_name: str, migration_name: str): def wrapper_outter(func: Callable): """Retry test multiple times""" - LOADER = MigrationLoader(connection) + loader = MigrationLoader(connection) @wraps(func) def wrapper(self: TransactionTestCase, *args, **kwargs): - migration = LOADER.get_migration(app_name, migration_name) + migration = loader.get_migration(app_name, migration_name) with connection.schema_editor() as schema_editor: for operation in migration.operations: if not isinstance(operation, RunPython): diff --git a/web/azure-pipelines.yml b/web/azure-pipelines.yml index 45ba50d2f..024a1d9ad 100644 --- a/web/azure-pipelines.yml +++ b/web/azure-pipelines.yml @@ -1,6 +1,7 @@ trigger: - master - next + - version-* variables: ${{ if startsWith(variables['Build.SourceBranch'], 'refs/pull/') }}: diff --git a/web/package-lock.json b/web/package-lock.json index bdcbb382d..9ad7ea231 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -197,6 +197,24 @@ } } }, + "@sentry/integrations": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-6.2.0.tgz", + "integrity": "sha512-gvAhP61qs2fog2xCTDs94ZT8cZbWEjFZmOWfT1VXlZDIVopIporj5Qe6IgrLTiCWL61Yko5h5nFnPZ4mpjf+0w==", + "requires": { + "@sentry/types": "6.2.0", + "@sentry/utils": "6.2.0", + "localforage": "^1.8.1", + "tslib": "^1.9.3" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, "@sentry/minimal": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.2.0.tgz", @@ -1727,6 +1745,11 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" + }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -1981,6 +2004,14 @@ "type-check": "~0.4.0" } }, + "lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", + "requires": { + "immediate": "~3.0.5" + } + }, "lit-analyzer": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/lit-analyzer/-/lit-analyzer-1.2.1.tgz", @@ -2162,6 +2193,14 @@ "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-1.3.0.tgz", "integrity": "sha512-0Q1bwmaFH9O14vycPHw8C/IeHMk/uSDldVLIefu/kfbTBGIc44KGH6A8p1bDfxUfHdc8q6Ct7kQklWoHgr4t1Q==" }, + "localforage": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.9.0.tgz", + "integrity": "sha512-rR1oyNrKulpe+VM9cYmcFn6tsHuokyVHFaCM3+osEmxaHTbEk8oQu6eGDfS6DQLWi/N67XRmB8ECG37OES368g==", + "requires": { + "lie": "3.1.1" + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", diff --git a/web/package.json b/web/package.json index 251356951..aa2ea896d 100644 --- a/web/package.json +++ b/web/package.json @@ -13,6 +13,7 @@ "@fortawesome/fontawesome-free": "^5.15.2", "@patternfly/patternfly": "^4.87.3", "@sentry/browser": "^6.2.0", + "@sentry/integrations": "^6.2.0", "@sentry/tracing": "^6.2.0", "@types/chart.js": "^2.9.31", "@types/codemirror": "0.0.108", diff --git a/web/src/api/Config.ts b/web/src/api/Config.ts index 7e28086a5..c5066ed7e 100644 --- a/web/src/api/Config.ts +++ b/web/src/api/Config.ts @@ -3,6 +3,7 @@ import * as Sentry from "@sentry/browser"; import { Integrations } from "@sentry/tracing"; import { VERSION } from "../constants"; import { SentryIgnoredError } from "../common/errors"; +import { CaptureConsole as CaptureConsoleIntegration } from "@sentry/integrations"; export class Config { branding_logo: string; @@ -22,7 +23,10 @@ export class Config { Sentry.init({ dsn: "https://a579bb09306d4f8b8d8847c052d3a1d3@sentry.beryju.org/8", release: `authentik@${VERSION}`, - integrations: [new Integrations.BrowserTracing()], + integrations: [ + new Integrations.BrowserTracing(), + new CaptureConsoleIntegration(), + ], tracesSampleRate: 0.6, environment: config.error_reporting_environment, beforeSend(event: Sentry.Event, hint: Sentry.EventHint) { diff --git a/web/src/common/styles.ts b/web/src/common/styles.ts index 41ec8d363..0480da4a6 100644 --- a/web/src/common/styles.ts +++ b/web/src/common/styles.ts @@ -1,3 +1,4 @@ +import { css, CSSResult } from "lit-element"; // @ts-ignore import PF from "@patternfly/patternfly/patternfly.css"; // @ts-ignore @@ -6,10 +7,31 @@ import PFAddons from "@patternfly/patternfly/patternfly-addons.css"; import FA from "@fortawesome/fontawesome-free/css/fontawesome.css"; // @ts-ignore import AKGlobal from "../authentik.css"; -import { CSSResult } from "lit-element"; // @ts-ignore import CodeMirrorStyle from "codemirror/lib/codemirror.css"; // @ts-ignore import CodeMirrorTheme from "codemirror/theme/monokai.css"; - -export const COMMON_STYLES: CSSResult[] = [PF, PFAddons, FA, AKGlobal, CodeMirrorStyle, CodeMirrorTheme]; +export const ColorStyles = css` + .pf-m-success { + color: var(--pf-global--success-color--100); + } + .pf-c-button.pf-m-success { + color: var(--pf-c-button--m-primary--Color); + background-color: var(--pf-global--success-color--100); + } + .pf-m-warning { + color: var(--pf-global--warning-color--100); + } + .pf-c-button.pf-m-warning { + color: var(--pf-c-button--m-primary--Color); + background-color: var(--pf-global--warning-color--100); + } + .pf-m-danger { + color: var(--pf-global--danger-color--100); + } + .pf-c-button.pf-m-danger { + color: var(--pf-c-button--m-primary--Color); + background-color: var(--pf-global--danger-color--100); + } +`; +export const COMMON_STYLES: CSSResult[] = [PF, PFAddons, FA, AKGlobal, CodeMirrorStyle, CodeMirrorTheme, ColorStyles]; diff --git a/web/src/constants.ts b/web/src/constants.ts index 73871e963..9079f262a 100644 --- a/web/src/constants.ts +++ b/web/src/constants.ts @@ -1,31 +1,6 @@ -import { css } from "lit-element"; - export const PRIMARY_CLASS = "pf-m-primary"; export const SUCCESS_CLASS = "pf-m-success"; export const ERROR_CLASS = "pf-m-danger"; export const PROGRESS_CLASS = "pf-m-in-progress"; export const CURRENT_CLASS = "pf-m-current"; -export const ColorStyles = css` - .pf-m-success { - color: var(--pf-global--success-color--100); - } - .pf-c-button.pf-m-success { - color: var(--pf-c-button--m-primary--Color); - background-color: var(--pf-global--success-color--100); - } - .pf-m-warning { - color: var(--pf-global--warning-color--100); - } - .pf-c-button.pf-m-warning { - color: var(--pf-c-button--m-primary--Color); - background-color: var(--pf-global--warning-color--100); - } - .pf-m-danger { - color: var(--pf-global--danger-color--100); - } - .pf-c-button.pf-m-danger { - color: var(--pf-c-button--m-primary--Color); - background-color: var(--pf-global--danger-color--100); - } -`; export const VERSION = "2021.2.5-stable"; diff --git a/web/src/elements/buttons/SpinnerButton.ts b/web/src/elements/buttons/SpinnerButton.ts index a97ad2ae3..5213e3e75 100644 --- a/web/src/elements/buttons/SpinnerButton.ts +++ b/web/src/elements/buttons/SpinnerButton.ts @@ -5,8 +5,9 @@ import GlobalsStyle from "@patternfly/patternfly/base/patternfly-globals.css"; import ButtonStyle from "@patternfly/patternfly/components/Button/button.css"; // @ts-ignore import SpinnerStyle from "@patternfly/patternfly/components/Spinner/spinner.css"; -import { ColorStyles, PRIMARY_CLASS, PROGRESS_CLASS } from "../../constants"; import { SpinnerSize } from "../Spinner"; +import { PRIMARY_CLASS, PROGRESS_CLASS } from "../../constants"; +import { ColorStyles } from "../../common/styles"; @customElement("ak-spinner-button") export class SpinnerButton extends LitElement { diff --git a/web/src/elements/buttons/TokenCopyButton.ts b/web/src/elements/buttons/TokenCopyButton.ts index 075469812..ee8b214df 100644 --- a/web/src/elements/buttons/TokenCopyButton.ts +++ b/web/src/elements/buttons/TokenCopyButton.ts @@ -4,7 +4,8 @@ import GlobalsStyle from "@patternfly/patternfly/base/patternfly-globals.css"; // @ts-ignore import ButtonStyle from "@patternfly/patternfly/components/Button/button.css"; import { Token } from "../../api/Tokens"; -import { ColorStyles, ERROR_CLASS, PRIMARY_CLASS, SUCCESS_CLASS } from "../../constants"; +import { ERROR_CLASS, PRIMARY_CLASS, SUCCESS_CLASS } from "../../constants"; +import { ColorStyles } from "../../common/styles"; @customElement("ak-token-copy-button") export class TokenCopyButton extends LitElement { diff --git a/web/src/elements/cards/AggregateCard.ts b/web/src/elements/cards/AggregateCard.ts index 4f21daf5f..101114df0 100644 --- a/web/src/elements/cards/AggregateCard.ts +++ b/web/src/elements/cards/AggregateCard.ts @@ -2,7 +2,6 @@ import { gettext } from "django"; import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element"; import { ifDefined } from "lit-html/directives/if-defined"; import { COMMON_STYLES } from "../../common/styles"; -import { ColorStyles } from "../../constants"; @customElement("ak-aggregate-card") export class AggregateCard extends LitElement { @@ -25,7 +24,7 @@ export class AggregateCard extends LitElement { text-align: center; color: var(--pf-global--Color--100); } - `, ColorStyles]); + `]); } renderInner(): TemplateResult { diff --git a/web/src/elements/router/RouterOutlet.ts b/web/src/elements/router/RouterOutlet.ts index 54391b6b7..796511c34 100644 --- a/web/src/elements/router/RouterOutlet.ts +++ b/web/src/elements/router/RouterOutlet.ts @@ -3,7 +3,6 @@ import { css, CSSResult, customElement, html, LitElement, property, TemplateResu import CodeMirrorStyle from "codemirror/lib/codemirror.css"; // @ts-ignore import CodeMirrorTheme from "codemirror/theme/monokai.css"; -import { ColorStyles } from "../../constants"; import { COMMON_STYLES } from "../../common/styles"; import { Route } from "./Route"; import { ROUTES } from "../../routes"; @@ -24,7 +23,6 @@ export class RouterOutlet extends LitElement { return [ CodeMirrorStyle, CodeMirrorTheme, - ColorStyles, css` :host { height: 100vh; diff --git a/website/static/flows/enrollment-2-stage.akflow b/website/static/flows/enrollment-2-stage.akflow index ece4d86a3..924a83c67 100644 --- a/website/static/flows/enrollment-2-stage.akflow +++ b/website/static/flows/enrollment-2-stage.akflow @@ -117,7 +117,7 @@ }, "model": "authentik_stages_user_login.userloginstage", "attrs": { - "session_duration": "seconds=-1" + "session_duration": "seconds=0" } }, { diff --git a/website/static/flows/enrollment-email-verification.akflow b/website/static/flows/enrollment-email-verification.akflow index b002933a1..2c75d1759 100644 --- a/website/static/flows/enrollment-email-verification.akflow +++ b/website/static/flows/enrollment-email-verification.akflow @@ -136,7 +136,7 @@ }, "model": "authentik_stages_user_login.userloginstage", "attrs": { - "session_duration": "seconds=-1" + "session_duration": "seconds=0" } }, { diff --git a/website/static/flows/login-2fa.akflow b/website/static/flows/login-2fa.akflow index ada439967..c37f71f37 100644 --- a/website/static/flows/login-2fa.akflow +++ b/website/static/flows/login-2fa.akflow @@ -20,7 +20,7 @@ }, "model": "authentik_stages_user_login.userloginstage", "attrs": { - "session_duration": "seconds=-1" + "session_duration": "seconds=0" } }, { diff --git a/website/static/flows/login-conditional-captcha.akflow b/website/static/flows/login-conditional-captcha.akflow index 0bc8003a5..b08969683 100644 --- a/website/static/flows/login-conditional-captcha.akflow +++ b/website/static/flows/login-conditional-captcha.akflow @@ -20,7 +20,7 @@ }, "model": "authentik_stages_user_login.userloginstage", "attrs": { - "session_duration": "seconds=-1" + "session_duration": "seconds=0" } }, { diff --git a/website/static/flows/recovery-email-verification.akflow b/website/static/flows/recovery-email-verification.akflow index d6b9f65e0..de3568d7e 100644 --- a/website/static/flows/recovery-email-verification.akflow +++ b/website/static/flows/recovery-email-verification.akflow @@ -115,7 +115,7 @@ }, "model": "authentik_stages_user_login.userloginstage", "attrs": { - "session_duration": "seconds=-1" + "session_duration": "seconds=0" } }, {