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("Distance settings (Impossible travel)")}
+
+
+
+ ${msg("Static rule settings")}
-
-
- ${msg("Dynamic rule settings")}
-
`;
}
}