diff --git a/authentik/enterprise/migrations/0002_rename_users_license_internal_users_and_more.py b/authentik/enterprise/migrations/0002_rename_users_license_internal_users_and_more.py index e8ad7dc4e..b3c199743 100644 --- a/authentik/enterprise/migrations/0002_rename_users_license_internal_users_and_more.py +++ b/authentik/enterprise/migrations/0002_rename_users_license_internal_users_and_more.py @@ -26,4 +26,11 @@ class Migration(migrations.Migration): fields=["key"], name="authentik_e_key_523e13_hash" ), ), + migrations.AlterModelOptions( + name="licenseusage", + options={ + "verbose_name": "License Usage", + "verbose_name_plural": "License Usage Records", + }, + ), ] diff --git a/authentik/enterprise/models.py b/authentik/enterprise/models.py index 37b95ba96..d10acd3ef 100644 --- a/authentik/enterprise/models.py +++ b/authentik/enterprise/models.py @@ -15,6 +15,7 @@ from django.contrib.postgres.indexes import HashIndex from django.db import models from django.db.models.query import QuerySet from django.utils.timezone import now +from django.utils.translation import gettext as _ from guardian.shortcuts import get_anonymous_user from jwt import PyJWTError, decode, get_unverified_header from rest_framework.exceptions import ValidationError @@ -187,3 +188,7 @@ class LicenseUsage(ExpiringModel): within_limits = models.BooleanField() record_date = models.DateTimeField(auto_now_add=True) + + class Meta: + verbose_name = _("License Usage") + verbose_name_plural = _("License Usage Records") diff --git a/authentik/lib/default.yml b/authentik/lib/default.yml index b9aad30bd..4ba45fc9d 100644 --- a/authentik/lib/default.yml +++ b/authentik/lib/default.yml @@ -84,6 +84,9 @@ ldap: tls: ciphers: null +reputation: + expiry: 86400 + cookie_domain: null disable_update_check: false disable_startup_analytics: false diff --git a/authentik/policies/reputation/migrations/0005_reputation_expires_reputation_expiring.py b/authentik/policies/reputation/migrations/0005_reputation_expires_reputation_expiring.py new file mode 100644 index 000000000..b6197e685 --- /dev/null +++ b/authentik/policies/reputation/migrations/0005_reputation_expires_reputation_expiring.py @@ -0,0 +1,33 @@ +# Generated by Django 4.2.4 on 2023-08-31 10:42 + +from django.db import migrations, models + +import authentik.policies.reputation.models + + +class Migration(migrations.Migration): + dependencies = [ + ("authentik_policies_reputation", "0004_reputationpolicy_authentik_p_policy__8f0d70_idx"), + ] + + operations = [ + migrations.AddField( + model_name="reputation", + name="expires", + field=models.DateTimeField( + default=authentik.policies.reputation.models.reputation_expiry + ), + ), + migrations.AddField( + model_name="reputation", + name="expiring", + field=models.BooleanField(default=True), + ), + migrations.AlterModelOptions( + name="reputation", + options={ + "verbose_name": "Reputation Score", + "verbose_name_plural": "Reputation Scores", + }, + ), + ] diff --git a/authentik/policies/reputation/models.py b/authentik/policies/reputation/models.py index 8bc999d01..723614f51 100644 --- a/authentik/policies/reputation/models.py +++ b/authentik/policies/reputation/models.py @@ -1,13 +1,17 @@ """authentik reputation request policy""" +from datetime import timedelta from uuid import uuid4 from django.db import models from django.db.models import Sum from django.db.models.query_utils import Q +from django.utils.timezone import now from django.utils.translation import gettext as _ from rest_framework.serializers import BaseSerializer from structlog import get_logger +from authentik.core.models import ExpiringModel +from authentik.lib.config import CONFIG from authentik.lib.models import SerializerModel from authentik.lib.utils.http import get_client_ip from authentik.policies.models import Policy @@ -17,6 +21,11 @@ LOGGER = get_logger() CACHE_KEY_PREFIX = "goauthentik.io/policies/reputation/scores/" +def reputation_expiry(): + """Reputation expiry""" + return now() + timedelta(seconds=CONFIG.get_int("reputation.expiry")) + + class ReputationPolicy(Policy): """Return true if request IP/target username's score is below a certain threshold""" @@ -59,7 +68,7 @@ class ReputationPolicy(Policy): verbose_name_plural = _("Reputation Policies") -class Reputation(SerializerModel): +class Reputation(ExpiringModel, SerializerModel): """Reputation for user and or IP.""" reputation_uuid = models.UUIDField(primary_key=True, unique=True, default=uuid4) @@ -69,6 +78,8 @@ class Reputation(SerializerModel): ip_geo_data = models.JSONField(default=dict) score = models.BigIntegerField(default=0) + expires = models.DateTimeField(default=reputation_expiry) + updated = models.DateTimeField(auto_now_add=True) @property @@ -81,4 +92,6 @@ class Reputation(SerializerModel): return f"Reputation {self.identifier}/{self.ip} @ {self.score}" class Meta: + verbose_name = _("Reputation Score") + verbose_name_plural = _("Reputation Scores") unique_together = ("identifier", "ip") diff --git a/authentik/sources/plex/tasks.py b/authentik/sources/plex/tasks.py index 39e69547e..c83b43f21 100644 --- a/authentik/sources/plex/tasks.py +++ b/authentik/sources/plex/tasks.py @@ -30,7 +30,7 @@ def check_plex_token(self: MonitoredTask, source_slug: int): self.set_status(TaskResult(TaskResultStatus.SUCCESSFUL, ["Plex token is valid."])) except RequestException as exc: error = exception_to_string(exc) - if len(source.plex_token) < 1: + if len(source.plex_token) > 0: error = error.replace(source.plex_token, "$PLEX_TOKEN") self.set_status( TaskResult( diff --git a/schema.yml b/schema.yml index ed7f520bd..7a1c6d411 100644 --- a/schema.yml +++ b/schema.yml @@ -12961,7 +12961,7 @@ paths: schema: type: string format: uuid - description: A UUID string identifying this reputation. + description: A UUID string identifying this Reputation Score. required: true tags: - policies @@ -12995,7 +12995,7 @@ paths: schema: type: string format: uuid - description: A UUID string identifying this reputation. + description: A UUID string identifying this Reputation Score. required: true tags: - policies @@ -13026,7 +13026,7 @@ paths: schema: type: string format: uuid - description: A UUID string identifying this reputation. + description: A UUID string identifying this Reputation Score. required: true tags: - policies @@ -29523,7 +29523,7 @@ components: * `authentik_policies_expression.expressionpolicy` - Expression Policy * `authentik_policies_password.passwordpolicy` - Password Policy * `authentik_policies_reputation.reputationpolicy` - Reputation Policy - * `authentik_policies_reputation.reputation` - reputation + * `authentik_policies_reputation.reputation` - Reputation Score * `authentik_policies.policybinding` - Policy Binding * `authentik_providers_ldap.ldapprovider` - LDAP Provider * `authentik_providers_oauth2.scopemapping` - Scope Mapping @@ -29713,7 +29713,7 @@ components: * `authentik_policies_expression.expressionpolicy` - Expression Policy * `authentik_policies_password.passwordpolicy` - Password Policy * `authentik_policies_reputation.reputationpolicy` - Reputation Policy - * `authentik_policies_reputation.reputation` - reputation + * `authentik_policies_reputation.reputation` - Reputation Score * `authentik_policies.policybinding` - Policy Binding * `authentik_providers_ldap.ldapprovider` - LDAP Provider * `authentik_providers_oauth2.scopemapping` - Scope Mapping @@ -31943,7 +31943,7 @@ components: * `authentik_policies_expression.expressionpolicy` - Expression Policy * `authentik_policies_password.passwordpolicy` - Password Policy * `authentik_policies_reputation.reputationpolicy` - Reputation Policy - * `authentik_policies_reputation.reputation` - reputation + * `authentik_policies_reputation.reputation` - Reputation Score * `authentik_policies.policybinding` - Policy Binding * `authentik_providers_ldap.ldapprovider` - LDAP Provider * `authentik_providers_oauth2.scopemapping` - Scope Mapping @@ -34930,7 +34930,7 @@ components: * `authentik_policies_expression.expressionpolicy` - Expression Policy * `authentik_policies_password.passwordpolicy` - Password Policy * `authentik_policies_reputation.reputationpolicy` - Reputation Policy - * `authentik_policies_reputation.reputation` - reputation + * `authentik_policies_reputation.reputation` - Reputation Score * `authentik_policies.policybinding` - Policy Binding * `authentik_providers_ldap.ldapprovider` - LDAP Provider * `authentik_providers_oauth2.scopemapping` - Scope Mapping diff --git a/web/src/admin/events/EventInfo.ts b/web/src/admin/events/EventInfo.ts index 178a19f06..0a1b32cc4 100644 --- a/web/src/admin/events/EventInfo.ts +++ b/web/src/admin/events/EventInfo.ts @@ -258,16 +258,18 @@ new?labels=bug,from_authentik&title=${encodeURIComponent(title)} return html`
${msg("Secret:")}
${this.getModelInfo(this.event.context.secret as EventModel)}`; case EventActions.SystemException: - return html` - ${msg("Open issue on GitHub...")} - -
+ return html`
${msg("Exception")}
+
${this.event.context.message}
diff --git a/website/docs/installation/configuration.md b/website/docs/installation/configuration.md index 71d83fe13..3ef47a6dd 100644 --- a/website/docs/installation/configuration.md +++ b/website/docs/installation/configuration.md @@ -51,15 +51,19 @@ kubectl exec -it deployment/authentik-worker -c authentik -- ak dump_config - `AUTHENTIK_REDIS__CACHE_TIMEOUT_POLICIES`: Timeout for cached policies until they expire in seconds, defaults to 300 - `AUTHENTIK_REDIS__CACHE_TIMEOUT_REPUTATION`: Timeout for cached reputation until they expire in seconds, defaults to 300 + :::info + `AUTHENTIK_REDIS__CACHE_TIMEOUT_REPUTATION` only applies to the cache expiry, see [`AUTHENTIK_REPUTATION__EXPIRY`](#authentik_reputation__expiry) to control how long reputation is persisted for. + ::: + ## Listen Setting -- `AUTHENTIK_LISTEN__HTTP`: Listening address:port (e.g. `0.0.0.0:9000`) for HTTP (Server and Proxy outpost) -- `AUTHENTIK_LISTEN__HTTPS`: Listening address:port (e.g. `0.0.0.0:9443`) for HTTPS (Server and Proxy outpost) -- `AUTHENTIK_LISTEN__LDAP`: Listening address:port (e.g. `0.0.0.0:3389`) for LDAP (LDAP outpost) -- `AUTHENTIK_LISTEN__LDAPS`: Listening address:port (e.g. `0.0.0.0:6636`) for LDAPS (LDAP outpost) -- `AUTHENTIK_LISTEN__METRICS`: Listening address:port (e.g. `0.0.0.0:9300`) for Prometheus metrics (All) -- `AUTHENTIK_LISTEN__DEBUG`: Listening address:port (e.g. `0.0.0.0:9900`) for Go Debugging metrics (All) -- `AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS`: List of CIDRs that proxy headers should be accepted from (Server) +- `AUTHENTIK_LISTEN__HTTP`: Listening address:port (e.g. `0.0.0.0:9000`) for HTTP (Applies to Server and Proxy outpost) +- `AUTHENTIK_LISTEN__HTTPS`: Listening address:port (e.g. `0.0.0.0:9443`) for HTTPS (Applies to Server and Proxy outpost) +- `AUTHENTIK_LISTEN__LDAP`: Listening address:port (e.g. `0.0.0.0:3389`) for LDAP (Applies to LDAP outpost) +- `AUTHENTIK_LISTEN__LDAPS`: Listening address:port (e.g. `0.0.0.0:6636`) for LDAPS (Applies to LDAP outpost) +- `AUTHENTIK_LISTEN__METRICS`: Listening address:port (e.g. `0.0.0.0:9300`) for Prometheus metrics (Applies to All) +- `AUTHENTIK_LISTEN__DEBUG`: Listening address:port (e.g. `0.0.0.0:9900`) for Go Debugging metrics (Applies to All) +- `AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS`: List of CIDRs that proxy headers should be accepted from (Applies to Server) Defaults to `127.0.0.0/8`, `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fe80::/10`, `::1/128`. @@ -297,6 +301,16 @@ Allows configuration of TLS Cliphers for LDAP connections used by LDAP sources. Defaults to `null`. +### `AUTHENTIK_REPUTATION__EXPIRY` + +:::info +Requires authentik 2023.8.2 +::: + +Configure how long reputation scores should be saved for in seconds. Note that this is different than [`AUTHENTIK_REDIS__CACHE_TIMEOUT_REPUTATION`](#redis-settings), as reputation is saved to the database every 5 minutes. + +Defaults to `86400`. + ### `AUTHENTIK_WEB__WORKERS` :::info