Skip to content

policies: add GeoIP policy#10454

Merged
BeryJu merged 23 commits intogoauthentik:mainfrom
gergosimonyi:policies/add-geoip-policy
Aug 6, 2024
Merged

policies: add GeoIP policy#10454
BeryJu merged 23 commits intogoauthentik:mainfrom
gergosimonyi:policies/add-geoip-policy

Conversation

@gergosimonyi
Copy link
Copy Markdown
Collaborator

@gergosimonyi gergosimonyi commented Jul 11, 2024

Closes #4433

Introduces the new GeoIP policy with the functionality to match client ASN or country (for now).

Opening a draft of this for a high-level overview. There are still many details to iron out like

  • Back-end tests
  • Handle disabled geoip
  • Handle IP missing in geoip database
  • Handle empty lists of ASNs and countries
  • Translations
  • Types on web
  • Multiselect on web

Checklist

  • Local tests pass (ak test authentik/)
  • The code has been formatted (make lint-fix)

If an API change has been made

  • The API schema has been updated (make gen-build)

If changes to the frontend have been made

  • The code has been formatted (make web)

If applicable

  • The documentation has been updated
  • The documentation has been formatted (make website)

@netlify
Copy link
Copy Markdown

netlify bot commented Jul 11, 2024

Deploy Preview for authentik-docs ready!

Name Link
🔨 Latest commit 063a55a
🔍 Latest deploy log https://app.netlify.com/sites/authentik-docs/deploys/66b0ebb1691e850008eaefb3
😎 Deploy Preview https://deploy-preview-10454--authentik-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@netlify
Copy link
Copy Markdown

netlify bot commented Jul 11, 2024

Deploy Preview for authentik-storybook ready!

Name Link
🔨 Latest commit 063a55a
🔍 Latest deploy log https://app.netlify.com/sites/authentik-storybook/deploys/66b0ebb1c0088900088ddefb
😎 Deploy Preview https://deploy-preview-10454--authentik-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@@ -0,0 +1,253 @@
"""List of all ISO-3166-1 alpha-2 country codes"""
Copy link
Copy Markdown
Collaborator Author

@gergosimonyi gergosimonyi Jul 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative to this is adding a dependency like iso3166 or django-countries.

Since ISO 3166 changes infrequently, I erred on the side of fewer dependencies.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind adding a dependency for this, especially since we should add gettext calls to all these humanized names, and some dependency might have full translation for all the country names already

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added django-countries. I'm unfamiliar with drf-spectacular and needed a bit of dark magic to make it work. If there's an easier way, let me know.

Comment on lines +95 to +100
.fetchObjects=${async () => {
return [
{ name: "allow", label: "Allow" },
{ name: "block", label: "Block" },
];
}}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of an async function here for a static list of 2 is probably the worst part of this PR. I'll look to improve this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, search select is specifically for complex objects that have subtitles and complex interactions. Consider using a Switch for a boolean choice, or if the ergonomics are bad (it's sometimes hard to word), a Radio.

Comment on lines +24 to +42
if (data.asnMode?.toString() === "") {
data.asnMode = "block";
}

if (data.asnList?.toString() === "") {
data.asnList = [];
} else {
data.asnList = data.asnList.split(",").map(Number);
}

if (data.countryMode?.toString() === "") {
data.countryMode = "block";
}

if (data.countryList?.toString() === "") {
data.countryList = [];
} else {
data.countryList = data.countryList.split(",");
}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defaults should be part of the back-end. Also some botched types here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm looking at this and thinking that I'm seeing a lot of mixed messages compared to the types generated from the schema. You shouldn't have to be splitting anything; the API should be giving those to you, and the TypeScript definitions in GeoIPPolicy.ts say getting strings where arrays are expected shouldn't be possible). This function is probably the wrong place to be doing this.

If you're crafting a blob to send, start with a default and overwrite it with what you get from the form instead.

@codecov
Copy link
Copy Markdown

codecov bot commented Jul 11, 2024

Codecov Report

Attention: Patch coverage is 99.39024% with 1 line in your changes missing coverage. Please review.

Project coverage is 92.56%. Comparing base (3824815) to head (2300a7b).
Report is 21 commits behind head on main.

Files Patch % Lines
authentik/policies/geoip/models.py 98.03% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #10454      +/-   ##
==========================================
+ Coverage   92.51%   92.56%   +0.04%     
==========================================
  Files         720      727       +7     
  Lines       35254    35418     +164     
==========================================
+ Hits        32615    32784     +169     
+ Misses       2639     2634       -5     
Flag Coverage Δ
e2e 49.58% <40.85%> (-0.05%) ⬇️
integration 25.29% <14.02%> (-0.06%) ⬇️
unit 90.07% <99.39%> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Copy Markdown
Contributor

@kensternberg-authentik kensternberg-authentik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, the Typescript is really promising! Good work. There's a bit of rough edges, and it's obviously not done, but it's getting there.

Comment on lines +24 to +42
if (data.asnMode?.toString() === "") {
data.asnMode = "block";
}

if (data.asnList?.toString() === "") {
data.asnList = [];
} else {
data.asnList = data.asnList.split(",").map(Number);
}

if (data.countryMode?.toString() === "") {
data.countryMode = "block";
}

if (data.countryList?.toString() === "") {
data.countryList = [];
} else {
data.countryList = data.countryList.split(",");
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm looking at this and thinking that I'm seeing a lot of mixed messages compared to the types generated from the schema. You shouldn't have to be splitting anything; the API should be giving those to you, and the TypeScript definitions in GeoIPPolicy.ts say getting strings where arrays are expected shouldn't be possible). This function is probably the wrong place to be doing this.

If you're crafting a blob to send, start with a default and overwrite it with what you get from the form instead.

)}
</span>
<ak-form-element-horizontal label=${msg("Name")} ?required=${true} name="name">
<input
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?required=${true} isn't needed here (and I really need to break @BeryJu of the habit). required is all that's needed. You only need the ? syntax for boolean attributes if the attribute can be changed by client code, for example:
?hidden=${!this.open}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we should probably just rip off the bandaid and change all of those wrong attributes to the correct ones

<input
class="pf-c-switch__input"
type="checkbox"
?checked=${first(this.instance?.executionLogging, false)}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

first is a leftover from earlier iterations of TypeScript. Please use the idiom:
${this.instance?.executionLogging ?? false}

Although in this case I suspect you could just use the boolean forcing expression: ${!!this.instance?.executionLogging}

Comment on lines +95 to +100
.fetchObjects=${async () => {
return [
{ name: "allow", label: "Allow" },
{ name: "block", label: "Block" },
];
}}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, search select is specifically for complex objects that have subtitles and complex interactions. Consider using a Switch for a boolean choice, or if the ergonomics are bad (it's sometimes hard to word), a Radio.

</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${msg("Country Mode")} name="countryMode">
<ak-search-select
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... and given that you've done it twice, break it out into a variable or something so you'll only have to change it once if the rules change. :-)

<ak-form-element-horizontal label=${msg("Country List")} name="countryList">
<input
type="text"
value="${ifDefined(this.instance?.countryList || "")}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you've provided a not-undefined value for falsity, ifDefined(this.instance?.countryList || "") will always be defined. You can replace that whole expression with this.instance?.countryList ?? ""

The exceptions raised here are `PolicyException`s to let admins bypass
an execution failure.
asn = asn_data.get("asn") if asn_data else None
country = geoip_data.get("country") if geoip_data else None

if not asn:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both of these cases can also happen if ASN/GeoIP is not configured (pretty rare since we include the DB by default, but it is possible to disable)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(We've had a bit of an offline discussion, but no resolution to this.) I kept the behavior for now, this way we don't leak information on whether a GeoIP database is available.

Let me know if you don't agree.

from authentik.policies.types import PolicyRequest, PolicyResult


class GeoIPPolicyMode(models.TextChoices):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually we don't have this as a setting directly on the policy but instead use the negate flag on the policy binding to inverse the effects. For this case I'm a bit on the fence as you can do two different things in the same policy with it

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I didn't notice that flag! That makes everything so much simpler. I'm not on the fence about it at all 😄

Then there's no need for *_mode and this model will just have 2 fields: asn_list and country_list. Same as Event Matcher Policy for least astonishment:

If any of the configured values match, the policy passes.

}

async send(data: GeoIPPolicy): Promise<GeoIPPolicy> {
if (data.asnMode?.toString() === "") {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is somewhat of a downside of the generated API client, but this value here should never be undefined so this if shouldn't be required

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Combined with the check below (which is still needed because "".split(",") is non-empty)

@@ -0,0 +1,253 @@
"""List of all ISO-3166-1 alpha-2 country codes"""
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind adding a dependency for this, especially since we should add gettext calls to all these humanized names, and some dependency might have full translation for all the country names already

@gergosimonyi gergosimonyi force-pushed the policies/add-geoip-policy branch from 1ea7057 to b4bb967 Compare July 17, 2024 10:52
Use the policy binding's `negate` option instead
`ak-dual-select-provider` can handle unpaginated data
@gergosimonyi gergosimonyi force-pushed the policies/add-geoip-policy branch from b4bb967 to d76003b Compare July 17, 2024 10:54
@gergosimonyi gergosimonyi force-pushed the policies/add-geoip-policy branch from d76003b to 9078588 Compare July 17, 2024 10:55
Comment on lines +12 to +15
COUNTRY_SCHEMA = {
"code": CountryField(),
"name": serializers.CharField(),
}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an exact copy of authentik/policies/geoip/views:11-14. Weirdly, importing it from there results in gen-build silently failing to generate this part of the schema. I'm out of my depth here, so I just duplicated these 4 lines.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is very odd but also doesn't surprise me


api_urlpatterns = [
("policies/geoip", GeoIPPolicyViewSet),
path("iso-3166/", ISO3166View.as_view(), name="iso-3166-view"),
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There may or may not be a better place for this.

@BeryJu?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd usually prefer to do it as policies/geoip/iso3166/, but obviously that could potentially cause errors due to that path also having the primary key...as a fallback I'd go with policies/geoip_iso3166/ I guess?

Comment on lines +24 to +28
if (data.asns?.toString() === "") {
data.asns = [];
} else {
data.asns = (data.asns as unknown as string).split(",").map(Number);
}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actual type of data slightly differs from GeoIPPolicy.

I haven't found an easy way to reconcile them (the "proper" way is probably building a component on top of <input> to run a transforming function when its value is read), so I opted for the type assertion.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could just write:

data.asns = (data.asns?.toString() ?? "") === "" ? [] : (data.asns as unknown as string).split(",").map(Number);

... but it feels like the toString() thing is a crutch you're using, and I'm not sure why.

Comment on lines +93 to +112
.provider=${(page: number, search?: string): Promise<DataProvision> => {
return new Iso3166Api(DEFAULT_CONFIG)
.iso3166List()
.then((results) => {
if (!search) return results;
return results.filter((result) =>
result.name
.toLowerCase()
.includes(search.toLowerCase()),
);
})
.then((results) => {
return {
options: results.map((country) => [
country.code,
country.name,
]),
};
});
}}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This currently hits the API for no reason every time there's a change in search. I'll add an optimization.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this is due to the assumption that the search filtering is done in the backend and not that the endpoint will return everything

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can write a provider that caches the result, and then provides the (locally reduces) results locally. Or you could look at ak-dual-select, which doesn't use the API; you could fetch the results once and then use the Web Component directly without having to go through the Element's API layer.

Copy link
Copy Markdown
Member

@BeryJu BeryJu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mostly LGTM

Comment on lines +93 to +112
.provider=${(page: number, search?: string): Promise<DataProvision> => {
return new Iso3166Api(DEFAULT_CONFIG)
.iso3166List()
.then((results) => {
if (!search) return results;
return results.filter((result) =>
result.name
.toLowerCase()
.includes(search.toLowerCase()),
);
})
.then((results) => {
return {
options: results.map((country) => [
country.code,
country.name,
]),
};
});
}}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this is due to the assumption that the search filtering is done in the backend and not that the endpoint will return everything

)}
</span>
<ak-form-element-horizontal label=${msg("Name")} ?required=${true} name="name">
<input
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we should probably just rip off the bandaid and change all of those wrong attributes to the correct ones

Comment on lines +12 to +15
COUNTRY_SCHEMA = {
"code": CountryField(),
"name": serializers.CharField(),
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is very odd but also doesn't surprise me


api_urlpatterns = [
("policies/geoip", GeoIPPolicyViewSet),
path("iso-3166/", ISO3166View.as_view(), name="iso-3166-view"),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd usually prefer to do it as policies/geoip/iso3166/, but obviously that could potentially cause errors due to that path also having the primary key...as a fallback I'd go with policies/geoip_iso3166/ I guess?

@BeryJu BeryJu marked this pull request as ready for review July 19, 2024 14:50
@BeryJu BeryJu requested review from a team as code owners July 19, 2024 14:50
The automatically generated APIs can't seem to handle `CountryField`,
so I'll have to do this by hand too.
@gergosimonyi gergosimonyi requested a review from a team as a code owner July 22, 2024 15:24
Copy link
Copy Markdown
Contributor

@tanberry tanberry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay we have a GeoIP policy! Thanks so much for updating the docs. A few nits, mostly about capitalization... I see that this whole page does not follow our Style Guide about using sentence-case capitalization for headers/titles. ("GeoIP policy" not "GeoIP Policy".)

# GeoIP

authentik supports GeoIP to add additional information to login/authorization/enrollment requests, and make policy decisions based on the lookup result.
authentik supports GeoIP to add additional information to login/authorization/enrollment requests. Additionally, a [GeoIP Policy](../policies/#geoip-policy) may be used to make policy decisions based on the lookup result.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
authentik supports GeoIP to add additional information to login/authorization/enrollment requests. Additionally, a [GeoIP Policy](../policies/#geoip-policy) may be used to make policy decisions based on the lookup result.
authentik supports GeoIP to add additional information to login/authorization/enrollment requests. Additionally, a [GeoIP policy](../policies/#geoip-policy) can be used to make policy decisions based on the lookup result.


```python
return context["geoip"]["country"] == "US"
return context["geoip"]["continent"] == "EU"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an example where we can use both "country" and "continent"? Will most people know the parms? (I wouldn't have know that continent was an option.)

Copy link
Copy Markdown
Collaborator Author

@gergosimonyi gergosimonyi Jul 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible, e.g. countries in Eurovision famously include Australia 🙂

    return context["geoip"]["continent"] == "EU" or context["geoip"]["country"] == "AU"

but I believe this might be more confusing than just keeping it simple. The params are listed right above, so I don't think "new confusion" arises from changing this.

(I changed this just to suggest something other that what could be done with a GeoIP policy.)

- `asn`: ASN dictionary. The follow fields are available:

:::info
For basic ASN matching, consider using a [GeoIP Policy](index.md#geoip-policy).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For basic ASN matching, consider using a [GeoIP Policy](index.md#geoip-policy).
For basic ASN matching, consider using a [GeoIP policy](index.md#geoip-policy).

- `geoip`: GeoIP dictionary. The following fields are available:

:::info
For basic country matching, consider using a [GeoIP Policy](index.md#geoip-policy).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For basic country matching, consider using a [GeoIP Policy](index.md#geoip-policy).
For basic country matching, consider using a [GeoIP policy](index.md#geoip-policy).


See [Expression Policy](expression.mdx).

## GeoIP Policy
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## GeoIP Policy
## GeoIP policy

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm I see that all of the other headers/titles for policies also capitalize "Policy". Our style is to use sentence style capitalization for headings... do you mind also changing all of the other headings to on this age to use a lower-case "p" on "policies"? :-)


## GeoIP Policy

Use this policy for simple GeoIP lookups, such as country or ASN matching. (For a more advanced GeoIP lookup, use an [Expression Policy](expression.mdx).)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Use this policy for simple GeoIP lookups, such as country or ASN matching. (For a more advanced GeoIP lookup, use an [Expression Policy](expression.mdx).)
Use this policy for simple GeoIP lookups, such as country or ASN matching. (For a more advanced GeoIP lookup, use an [Expression policy](expression.mdx).)

Copy link
Copy Markdown
Contributor

@tanberry tanberry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for updating the Docs!

@gergosimonyi gergosimonyi force-pushed the policies/add-geoip-policy branch from 986f1bd to 18f3367 Compare July 29, 2024 12:12
@gergosimonyi gergosimonyi requested a review from BeryJu July 29, 2024 12:13
Copy link
Copy Markdown
Contributor

@kensternberg-authentik kensternberg-authentik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, this looks quite good. I have a few quibbles about syntax and idioms, but they're more of a "I wouldn't do it this way, but it works and it's not wrong, so let's go with it." If you want to tighten up a few of the wordier expressions, feel free, but otherwise I'm happy.

Comment on lines +24 to +28
if (data.asns?.toString() === "") {
data.asns = [];
} else {
data.asns = (data.asns as unknown as string).split(",").map(Number);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could just write:

data.asns = (data.asns?.toString() ?? "") === "" ? [] : (data.asns as unknown as string).split(",").map(Number);

... but it feels like the toString() thing is a crutch you're using, and I'm not sure why.

Comment on lines +93 to +112
.provider=${(page: number, search?: string): Promise<DataProvision> => {
return new Iso3166Api(DEFAULT_CONFIG)
.iso3166List()
.then((results) => {
if (!search) return results;
return results.filter((result) =>
result.name
.toLowerCase()
.includes(search.toLowerCase()),
);
})
.then((results) => {
return {
options: results.map((country) => [
country.code,
country.name,
]),
};
});
}}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can write a provider that caches the result, and then provides the (locally reduces) results locally. Or you could look at ak-dual-select, which doesn't use the API; you could fetch the results once and then use the Web Component directly without having to go through the Element's API layer.

Copy link
Copy Markdown
Member

@rissson rissson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nitpicking, but otherwise looks quite good!

@BeryJu BeryJu enabled auto-merge (squash) August 6, 2024 10:31
@BeryJu BeryJu merged commit f7b16ed into goauthentik:main Aug 6, 2024
kensternberg-authentik added a commit that referenced this pull request Aug 6, 2024
* main: (473 commits)
  blueprints: handle model referencing non-existent app/model (#10796)
  website/docs: add more content about flows (#10527)
  brands: add OIDC webfinger support (#10400)
  web/admin: fix selectable card colour in dark theme (#10794)
  web: bump API Client version (#10793)
  policies: add GeoIP policy (#10454)
  core: bump debugpy from 1.8.3 to 1.8.5 (#10781)
  web: bump @sentry/browser from 8.22.0 to 8.23.0 in /web in the sentry group across 1 directory (#10782)
  website: bump postcss from 8.4.40 to 8.4.41 in /website (#10783)
  web: bump the wdio group across 2 directories with 4 updates (#10785)
  web: bump @lit/localize from 0.12.1 to 0.12.2 in /web (#10786)
  web: bump @floating-ui/dom from 1.6.8 to 1.6.9 in /web (#10787)
  web: bump @lit/localize-tools from 0.7.2 to 0.8.0 in /web (#10788)
  web: bump lit from 3.1.4 to 3.2.0 in /web (#10789)
  core: bump goauthentik.io/api/v3 from 3.2024062.2 to 3.2024063.1 (#10790)
  web: bump API Client version (#10779)
  release: 2024.6.3
  website/docs: prepare 2024.6.3 release notes (#10775)
  website/scripts: updated readme, added docsmg.env file  (#10710)
  web: bump API Client version (#10777)
  ...
kensternberg-authentik added a commit that referenced this pull request Aug 6, 2024
* main: (702 commits)
  blueprints: handle model referencing non-existent app/model (#10796)
  website/docs: add more content about flows (#10527)
  brands: add OIDC webfinger support (#10400)
  web/admin: fix selectable card colour in dark theme (#10794)
  web: bump API Client version (#10793)
  policies: add GeoIP policy (#10454)
  core: bump debugpy from 1.8.3 to 1.8.5 (#10781)
  web: bump @sentry/browser from 8.22.0 to 8.23.0 in /web in the sentry group across 1 directory (#10782)
  website: bump postcss from 8.4.40 to 8.4.41 in /website (#10783)
  web: bump the wdio group across 2 directories with 4 updates (#10785)
  web: bump @lit/localize from 0.12.1 to 0.12.2 in /web (#10786)
  web: bump @floating-ui/dom from 1.6.8 to 1.6.9 in /web (#10787)
  web: bump @lit/localize-tools from 0.7.2 to 0.8.0 in /web (#10788)
  web: bump lit from 3.1.4 to 3.2.0 in /web (#10789)
  core: bump goauthentik.io/api/v3 from 3.2024062.2 to 3.2024063.1 (#10790)
  web: bump API Client version (#10779)
  release: 2024.6.3
  website/docs: prepare 2024.6.3 release notes (#10775)
  website/scripts: updated readme, added docsmg.env file  (#10710)
  web: bump API Client version (#10777)
  ...
kensternberg-authentik added a commit that referenced this pull request Aug 6, 2024
* main: (690 commits)
  blueprints: handle model referencing non-existent app/model (#10796)
  website/docs: add more content about flows (#10527)
  brands: add OIDC webfinger support (#10400)
  web/admin: fix selectable card colour in dark theme (#10794)
  web: bump API Client version (#10793)
  policies: add GeoIP policy (#10454)
  core: bump debugpy from 1.8.3 to 1.8.5 (#10781)
  web: bump @sentry/browser from 8.22.0 to 8.23.0 in /web in the sentry group across 1 directory (#10782)
  website: bump postcss from 8.4.40 to 8.4.41 in /website (#10783)
  web: bump the wdio group across 2 directories with 4 updates (#10785)
  web: bump @lit/localize from 0.12.1 to 0.12.2 in /web (#10786)
  web: bump @floating-ui/dom from 1.6.8 to 1.6.9 in /web (#10787)
  web: bump @lit/localize-tools from 0.7.2 to 0.8.0 in /web (#10788)
  web: bump lit from 3.1.4 to 3.2.0 in /web (#10789)
  core: bump goauthentik.io/api/v3 from 3.2024062.2 to 3.2024063.1 (#10790)
  web: bump API Client version (#10779)
  release: 2024.6.3
  website/docs: prepare 2024.6.3 release notes (#10775)
  website/scripts: updated readme, added docsmg.env file  (#10710)
  web: bump API Client version (#10777)
  ...
kensternberg-authentik added a commit that referenced this pull request Aug 6, 2024
* main: (229 commits)
  blueprints: handle model referencing non-existent app/model (#10796)
  website/docs: add more content about flows (#10527)
  brands: add OIDC webfinger support (#10400)
  web/admin: fix selectable card colour in dark theme (#10794)
  web: bump API Client version (#10793)
  policies: add GeoIP policy (#10454)
  core: bump debugpy from 1.8.3 to 1.8.5 (#10781)
  web: bump @sentry/browser from 8.22.0 to 8.23.0 in /web in the sentry group across 1 directory (#10782)
  website: bump postcss from 8.4.40 to 8.4.41 in /website (#10783)
  web: bump the wdio group across 2 directories with 4 updates (#10785)
  web: bump @lit/localize from 0.12.1 to 0.12.2 in /web (#10786)
  web: bump @floating-ui/dom from 1.6.8 to 1.6.9 in /web (#10787)
  web: bump @lit/localize-tools from 0.7.2 to 0.8.0 in /web (#10788)
  web: bump lit from 3.1.4 to 3.2.0 in /web (#10789)
  core: bump goauthentik.io/api/v3 from 3.2024062.2 to 3.2024063.1 (#10790)
  web: bump API Client version (#10779)
  release: 2024.6.3
  website/docs: prepare 2024.6.3 release notes (#10775)
  website/scripts: updated readme, added docsmg.env file  (#10710)
  web: bump API Client version (#10777)
  ...
kensternberg-authentik added a commit that referenced this pull request Aug 12, 2024
* main:
  blueprints: handle model referencing non-existent app/model (#10796)
  website/docs: add more content about flows (#10527)
  brands: add OIDC webfinger support (#10400)
  web/admin: fix selectable card colour in dark theme (#10794)
  web: bump API Client version (#10793)
  policies: add GeoIP policy (#10454)
  core: bump debugpy from 1.8.3 to 1.8.5 (#10781)
  web: bump @sentry/browser from 8.22.0 to 8.23.0 in /web in the sentry group across 1 directory (#10782)
  website: bump postcss from 8.4.40 to 8.4.41 in /website (#10783)
  web: bump the wdio group across 2 directories with 4 updates (#10785)
  web: bump @lit/localize from 0.12.1 to 0.12.2 in /web (#10786)
  web: bump @floating-ui/dom from 1.6.8 to 1.6.9 in /web (#10787)
  web: bump @lit/localize-tools from 0.7.2 to 0.8.0 in /web (#10788)
  web: bump lit from 3.1.4 to 3.2.0 in /web (#10789)
  core: bump goauthentik.io/api/v3 from 3.2024062.2 to 3.2024063.1 (#10790)
  web: bump API Client version (#10779)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dedicated GeoIP/ASN policy

5 participants