policies/geoip: distance + impossible travel (#12541)

* add history distance checks

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* start impossible travel

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* optimise

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* ui start

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix and add tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix ui, fix missing api

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L.
2025-02-17 18:47:25 +01:00
committed by GitHub
parent 67c22c1313
commit ab8f5a2ac4
9 changed files with 684 additions and 18 deletions

View File

@ -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";
@ -46,7 +47,7 @@ export class GeoIPPolicyForm extends BasePolicyForm<GeoIPPolicy> {
}
renderForm(): TemplateResult {
return html` <span>
return html`<span>
${msg(
"Ensure the user satisfies requirements of geography or network topology, based on IP address. If any of the configured values match, the policy passes.",
)}
@ -79,13 +80,125 @@ export class GeoIPPolicyForm extends BasePolicyForm<GeoIPPolicy> {
)}
</p>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header"> ${msg("Policy-specific settings")} </span>
<ak-form-group>
<span slot="header"> ${msg("Distance settings")} </span>
<div slot="body" class="pf-c-form">
<ak-form-element-horizontal name="checkHistoryDistance">
<label class="pf-c-switch">
<input
class="pf-c-switch__input"
type="checkbox"
?checked=${this.instance?.checkHistoryDistance ?? false}
/>
<span class="pf-c-switch__toggle">
<span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label"
>${msg("Check historical distance of logins")}</span
>
</label>
<p class="pf-c-form__helper-text">
${msg(
"When this option enabled, the GeoIP data of the policy request is compared to the specified number of historical logins.",
)}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("Distance tolerance")}
name="distanceToleranceKm"
>
<input
type="number"
min="1"
value="${first(this.instance?.distanceToleranceKm, 50)}"
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">
${msg("Tolerance in checking for distances in kilometers.")}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("Historical Login Count")}
name="historyLoginCount"
>
<input
type="number"
min="1"
value="${first(this.instance?.historyLoginCount, 5)}"
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">
${msg("Amount of previous login events to check against.")}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("Maximum distance")}
name="historyMaxDistanceKm"
>
<input
type="number"
min="1"
value="${first(this.instance?.historyMaxDistanceKm, 100)}"
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">
${msg(
"Maximum distance a login attempt is allowed from in kilometers.",
)}
</p>
</ak-form-element-horizontal>
</div>
</ak-form-group>
<ak-form-group>
<span slot="header"> ${msg("Distance settings (Impossible travel)")} </span>
<div slot="body" class="pf-c-form">
<ak-form-element-horizontal name="checkImpossibleTravel">
<label class="pf-c-switch">
<input
class="pf-c-switch__input"
type="checkbox"
?checked=${this.instance?.checkImpossibleTravel ?? true}
/>
<span class="pf-c-switch__toggle">
<span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label"
>${msg("Check impossible travel")}</span
>
</label>
<p class="pf-c-form__helper-text">
${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.",
)}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("Impossible travel tolerance")}
name="impossibleToleranceKm"
>
<input
type="number"
min="1"
value="${first(this.instance?.impossibleToleranceKm, 50)}"
class="pf-c-form-control"
/>
<p class="pf-c-form__helper-text">
${msg("Tolerance in checking for distances in kilometers.")}
</p>
</ak-form-element-horizontal>
</div>
</ak-form-group>
<ak-form-group>
<span slot="header">${msg("Static rule settings")}</span>
<div slot="body" class="pf-c-form">
<ak-form-element-horizontal label=${msg("ASNs")} name="asns">
<input
type="text"
value="${this.instance?.asns ?? ""}"
value="${this.instance?.asns?.join(",") ?? ""}"
class="pf-c-form-control pf-m-monospace"
autocomplete="off"
spellcheck="false"