From a2cc87e5f0fce2640000872d6f6bc4bf9a5113f8 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Jan 2025 22:01:16 +0100 Subject: [PATCH] fix ui, fix missing api Signed-off-by: Jens Langhammer --- authentik/policies/geoip/api.py | 4 +- ...policy_check_history_distance_and_more.py} | 6 +- authentik/policies/geoip/models.py | 7 +- authentik/policies/geoip/tests.py | 6 +- blueprints/schema.json | 14 +- schema.yml | 24 ++- .../admin/policies/geoip/GeoIPPolicyForm.ts | 138 +++++++++++++++--- 7 files changed, 162 insertions(+), 37 deletions(-) rename authentik/policies/geoip/migrations/{0002_geoippolicy_check_history_and_more.py => 0002_geoippolicy_check_history_distance_and_more.py} (88%) diff --git a/authentik/policies/geoip/api.py b/authentik/policies/geoip/api.py index 58bced6c2fc8..6d171c137817 100644 --- a/authentik/policies/geoip/api.py +++ b/authentik/policies/geoip/api.py @@ -42,10 +42,12 @@ class Meta: "asns", "countries", "countries_obj", - "check_history", + "check_history_distance", "history_max_distance_km", "distance_tolerance_km", "history_login_count", + "check_impossible_travel", + "impossible_tolerance_km", ] diff --git a/authentik/policies/geoip/migrations/0002_geoippolicy_check_history_and_more.py b/authentik/policies/geoip/migrations/0002_geoippolicy_check_history_distance_and_more.py similarity index 88% rename from authentik/policies/geoip/migrations/0002_geoippolicy_check_history_and_more.py rename to authentik/policies/geoip/migrations/0002_geoippolicy_check_history_distance_and_more.py index b6b2e220b31f..9e44800c94bb 100644 --- a/authentik/policies/geoip/migrations/0002_geoippolicy_check_history_and_more.py +++ b/authentik/policies/geoip/migrations/0002_geoippolicy_check_history_distance_and_more.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.10 on 2024-12-22 17:55 +# Generated by Django 5.0.10 on 2025-01-02 20:40 from django.db import migrations, models @@ -12,7 +12,7 @@ class Migration(migrations.Migration): operations = [ migrations.AddField( model_name="geoippolicy", - name="check_history", + name="check_history_distance", field=models.BooleanField(default=False), ), migrations.AddField( @@ -33,7 +33,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name="geoippolicy", name="history_max_distance_km", - field=models.PositiveBigIntegerField(default=0), + field=models.PositiveBigIntegerField(default=100), ), migrations.AddField( model_name="geoippolicy", diff --git a/authentik/policies/geoip/models.py b/authentik/policies/geoip/models.py index f9695f115735..d87f303d1329 100644 --- a/authentik/policies/geoip/models.py +++ b/authentik/policies/geoip/models.py @@ -28,7 +28,8 @@ class GeoIPPolicy(Policy): countries = CountryField(multiple=True, blank=True) distance_tolerance_km = models.PositiveIntegerField(default=50) - check_history = models.BooleanField(default=False) + + check_history_distance = models.BooleanField(default=False) history_max_distance_km = models.PositiveBigIntegerField(default=100) history_login_count = models.PositiveIntegerField(default=5) @@ -59,7 +60,7 @@ def passes(self, request: PolicyRequest) -> PolicyResult: if self.countries: static_results.append(self.passes_country(request)) - if self.check_history or self.check_impossible_travel: + if self.check_history_distance or self.check_impossible_travel: dynamic_results.append(self.passes_distance(request)) if not static_results and not dynamic_results: @@ -126,7 +127,7 @@ def passes_distance(self, request: PolicyRequest) -> PolicyResult: (previous_login_geoip["lat"], previous_login_geoip["long"]), (geoip_data["lat"], geoip_data["long"]), ) - if self.check_history and dist.km >= ( + if self.check_history_distance and dist.km >= ( self.history_max_distance_km - self.distance_tolerance_km ): return PolicyResult( diff --git a/authentik/policies/geoip/tests.py b/authentik/policies/geoip/tests.py index 6fe918334804..a1178f35c466 100644 --- a/authentik/policies/geoip/tests.py +++ b/authentik/policies/geoip/tests.py @@ -142,7 +142,7 @@ def test_history(self): # Random location in Poland self.request.context["geoip"] = {"lat": 50.950613, "long": 20.363679} - policy = GeoIPPolicy.objects.create(check_history=True) + policy = GeoIPPolicy.objects.create(check_history_distance=True) result: PolicyResult = policy.passes(self.request) self.assertFalse(result.passing) @@ -158,7 +158,7 @@ def test_history_no_data(self): }, ) - policy = GeoIPPolicy.objects.create(check_history=True) + policy = GeoIPPolicy.objects.create(check_history_distance=True) result: PolicyResult = policy.passes(self.request) self.assertFalse(result.passing) @@ -191,7 +191,7 @@ def test_history_no_geoip(self): # Random location in Poland self.request.context["geoip"] = {"lat": 50.950613, "long": 20.363679} - policy = GeoIPPolicy.objects.create(check_history=True) + policy = GeoIPPolicy.objects.create(check_history_distance=True) result: PolicyResult = policy.passes(self.request) self.assertFalse(result.passing) diff --git a/blueprints/schema.json b/blueprints/schema.json index a61b0f881bcc..5a2fa87d85e0 100644 --- a/blueprints/schema.json +++ b/blueprints/schema.json @@ -5108,9 +5108,9 @@ "maxItems": 249, "title": "Countries" }, - "check_history": { + "check_history_distance": { "type": "boolean", - "title": "Check history" + "title": "Check history distance" }, "history_max_distance_km": { "type": "integer", @@ -5129,6 +5129,16 @@ "minimum": 0, "maximum": 2147483647, "title": "History login count" + }, + "check_impossible_travel": { + "type": "boolean", + "title": "Check impossible travel" + }, + "impossible_tolerance_km": { + "type": "integer", + "minimum": 0, + "maximum": 2147483647, + "title": "Impossible tolerance km" } }, "required": [] diff --git a/schema.yml b/schema.yml index 0cd81a5eef4a..986bfae9ebb2 100644 --- a/schema.yml +++ b/schema.yml @@ -42553,7 +42553,7 @@ components: items: $ref: '#/components/schemas/DetailedCountryField' readOnly: true - check_history: + check_history_distance: type: boolean history_max_distance_km: type: integer @@ -42568,6 +42568,12 @@ components: type: integer maximum: 2147483647 minimum: 0 + check_impossible_travel: + type: boolean + impossible_tolerance_km: + type: integer + maximum: 2147483647 + minimum: 0 required: - bound_to - component @@ -42600,7 +42606,7 @@ components: items: $ref: '#/components/schemas/CountryCodeEnum' maxItems: 249 - check_history: + check_history_distance: type: boolean history_max_distance_km: type: integer @@ -42615,6 +42621,12 @@ components: type: integer maximum: 2147483647 minimum: 0 + check_impossible_travel: + type: boolean + impossible_tolerance_km: + type: integer + maximum: 2147483647 + minimum: 0 required: - countries - name @@ -49015,7 +49027,7 @@ components: items: $ref: '#/components/schemas/CountryCodeEnum' maxItems: 249 - check_history: + check_history_distance: type: boolean history_max_distance_km: type: integer @@ -49030,6 +49042,12 @@ components: type: integer maximum: 2147483647 minimum: 0 + check_impossible_travel: + type: boolean + impossible_tolerance_km: + type: integer + maximum: 2147483647 + minimum: 0 PatchedGoogleWorkspaceProviderMappingRequest: type: object description: GoogleWorkspaceProviderMapping Serializer diff --git a/web/src/admin/policies/geoip/GeoIPPolicyForm.ts b/web/src/admin/policies/geoip/GeoIPPolicyForm.ts index 535f21a7aed1..9a0355da1238 100644 --- a/web/src/admin/policies/geoip/GeoIPPolicyForm.ts +++ b/web/src/admin/policies/geoip/GeoIPPolicyForm.ts @@ -1,5 +1,6 @@ import { BasePolicyForm } from "@goauthentik/admin/policies/BasePolicyForm"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; +import { first } from "@goauthentik/common/utils"; import "@goauthentik/elements/ak-dual-select"; import { DataProvision, DualSelectPair } from "@goauthentik/elements/ak-dual-select/types"; import "@goauthentik/elements/forms/FormGroup"; @@ -79,13 +80,125 @@ export class GeoIPPolicyForm extends BasePolicyForm { )}

- - ${msg("Static rule settings")} + + ${msg("Distance settings")} +
+ + +

+ ${msg( + "When this option enabled, the GeoIP data of the policy request is compared to the specified number of historical logins.", + )} +

+
+ + +

+ ${msg("Tolerance in checking for distances in kilometers.")} +

+
+ + +

+ ${msg("Amount of previous login events to check against.")} +

+
+ + +

+ ${msg( + "Maximum distance a login attempt is allowed from in kilometers.", + )} +

+
+
+
+ + ${msg("Distance settings (Impossible travel)")} +
+ + +

+ ${msg( + "When this option enabled, the GeoIP data of the policy request is compared to the specified number of historical logins and if the travel would have been possible in the amount of time since the previous event.", + )} +

+
+ + +

+ ${msg("Tolerance in checking for distances in kilometers.")} +

+
+
+
+ + ${msg("Static rule settings")}

@@ -120,25 +233,6 @@ export class GeoIPPolicyForm extends BasePolicyForm {

-
- - ${msg("Dynamic rule settings")} -
- - -

- ${msg("Amount of previous login events to check against.")} -

-
-
`; } }