Compare commits

...

10 Commits

Author SHA1 Message Date
2fb097061d release: 2024.8.0 2024-09-02 14:14:03 +02:00
8962d17e03 web: fix dual-select with dynamic selection (cherry-pick #11133) (#11134)
web: fix dual-select with dynamic selection (#11133)

* web: fix dual-select with dynamic selection

For dynamic selection, the property name is `.selector` to message that it's a function the
API layer uses to select the elements.

A few bits of lint picked.

* web: added comment to clarify what the fallback selector does

Co-authored-by: Ken Sternberg <133134217+kensternberg-authentik@users.noreply.github.com>
2024-08-30 19:07:36 +02:00
8326e1490c ci: fix failing release attestation (cherry-pick #11107) (#11120)
ci: fix failing release attestation (#11107)

* ci: fix failing release attestation



* fix



---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-08-29 13:29:47 +02:00
091e4d3e4c enterprise: fix incorrect comparison for latest validity date (cherry-pick #11109) (#11110)
enterprise: fix incorrect comparison for latest validity date (#11109)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-08-29 01:58:56 +02:00
6ee77edcbb website/docs: 2024.8 release notes: reword group sync disable and fix typo (cherry-pick #11103) (#11108)
website/docs: 2024.8 release notes: reword group sync disable and fix… (#11103)

Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2024-08-29 01:34:33 +02:00
763e2288bf release: 2024.8.0-rc2 2024-08-28 20:22:52 +02:00
9cdb177ca7 website/docs: a couple of minor rewrite things (#11099)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
# Conflicts:
#	website/docs/releases/2024/v2024.8.md
2024-08-28 20:22:21 +02:00
6070508058 providers/oauth2: audit_ignore last_login change for generated service account (cherry-pick #11085) (#11086)
providers/oauth2: audit_ignore last_login change for generated service account (#11085)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2024-08-27 14:32:17 +02:00
ec13a5d84d release: 2024.8.0-rc1 2024-08-26 16:34:53 +02:00
057de82b01 schemas: fix XML Schema loading...for some reason?
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-08-26 16:34:47 +02:00
27 changed files with 4099 additions and 69 deletions

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 2024.6.4
current_version = 2024.8.0
tag = True
commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<rc_t>[a-zA-Z-]+)(?P<rc_n>[1-9]\\d*))?

View File

@ -29,9 +29,9 @@ outputs:
imageTags:
description: "Docker image tags"
value: ${{ steps.ev.outputs.imageTags }}
imageNames:
description: "Docker image names"
value: ${{ steps.ev.outputs.imageNames }}
attestImageNames:
description: "Docker image names used for attestation"
value: ${{ steps.ev.outputs.attestImageNames }}
imageMainTag:
description: "Docker image main tag"
value: ${{ steps.ev.outputs.imageMainTag }}

View File

@ -51,15 +51,24 @@ else:
]
image_main_tag = image_tags[0].split(":")[-1]
image_tags_rendered = ",".join(image_tags)
image_names_rendered = ",".join(set(name.split(":")[0] for name in image_tags))
def get_attest_image_names(image_with_tags: list[str]):
"""Attestation only for GHCR"""
image_tags = []
for image_name in set(name.split(":")[0] for name in image_with_tags):
if not image_name.startswith("ghcr.io"):
continue
image_tags.append(image_name)
return ",".join(set(image_tags))
with open(os.environ["GITHUB_OUTPUT"], "a+", encoding="utf-8") as _output:
print(f"shouldBuild={should_build}", file=_output)
print(f"sha={sha}", file=_output)
print(f"version={version}", file=_output)
print(f"prerelease={prerelease}", file=_output)
print(f"imageTags={image_tags_rendered}", file=_output)
print(f"imageNames={image_names_rendered}", file=_output)
print(f"imageTags={','.join(image_tags)}", file=_output)
print(f"attestImageNames={get_attest_image_names(image_tags)}", file=_output)
print(f"imageMainTag={image_main_tag}", file=_output)
print(f"imageMainName={image_tags[0]}", file=_output)

View File

@ -261,7 +261,7 @@ jobs:
id: attest
if: ${{ steps.ev.outputs.shouldBuild == 'true' }}
with:
subject-name: ${{ steps.ev.outputs.imageNames }}
subject-name: ${{ steps.ev.outputs.attestImageNames }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
pr-comment:

View File

@ -115,7 +115,7 @@ jobs:
id: attest
if: ${{ steps.ev.outputs.shouldBuild == 'true' }}
with:
subject-name: ${{ steps.ev.outputs.imageNames }}
subject-name: ${{ steps.ev.outputs.attestImageNames }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
build-binary:

View File

@ -58,7 +58,7 @@ jobs:
- uses: actions/attest-build-provenance@v1
id: attest
with:
subject-name: ${{ steps.ev.outputs.imageNames }}
subject-name: ${{ steps.ev.outputs.attestImageNames }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
build-outpost:
@ -122,7 +122,7 @@ jobs:
- uses: actions/attest-build-provenance@v1
id: attest
with:
subject-name: ${{ steps.ev.outputs.imageNames }}
subject-name: ${{ steps.ev.outputs.attestImageNames }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
build-outpost-binary:

View File

@ -2,7 +2,7 @@
from os import environ
__version__ = "2024.6.4"
__version__ = "2024.8.0"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"

View File

@ -25,4 +25,4 @@ class AuthentikEnterpriseConfig(EnterpriseConfig):
"""Actual enterprise check, cached"""
from authentik.enterprise.license import LicenseKey
return LicenseKey.cached_summary().status
return LicenseKey.cached_summary().status.is_valid

View File

@ -117,7 +117,7 @@ class LicenseKey:
our_cert.public_key(),
algorithms=["ES512"],
audience=get_license_aud(),
options={"verify_exp": check_expiry},
options={"verify_exp": check_expiry, "verify_signature": check_expiry},
),
)
except PyJWTError:
@ -134,7 +134,7 @@ class LicenseKey:
exp_ts = int(mktime(lic.expiry.timetuple()))
if total.exp == 0:
total.exp = exp_ts
total.exp = min(total.exp, exp_ts)
total.exp = max(total.exp, exp_ts)
total.license_flags.extend(lic.status.license_flags)
return total

View File

@ -433,20 +433,21 @@ class TokenParams:
app = Application.objects.filter(provider=self.provider).first()
if not app or not app.provider:
raise TokenError("invalid_grant")
self.user, _ = User.objects.update_or_create(
# trim username to ensure the entire username is max 150 chars
# (22 chars being the length of the "template")
username=f"ak-{self.provider.name[:150-22]}-client_credentials",
defaults={
"attributes": {
USER_ATTRIBUTE_GENERATED: True,
with audit_ignore():
self.user, _ = User.objects.update_or_create(
# trim username to ensure the entire username is max 150 chars
# (22 chars being the length of the "template")
username=f"ak-{self.provider.name[:150-22]}-client_credentials",
defaults={
"attributes": {
USER_ATTRIBUTE_GENERATED: True,
},
"last_login": timezone.now(),
"name": f"Autogenerated user from application {app.name} (client credentials)",
"path": f"{USER_PATH_SYSTEM_PREFIX}/apps/{app.slug}",
"type": UserTypes.SERVICE_ACCOUNT,
},
"last_login": timezone.now(),
"name": f"Autogenerated user from application {app.name} (client credentials)",
"path": f"{USER_PATH_SYSTEM_PREFIX}/apps/{app.slug}",
"type": UserTypes.SERVICE_ACCOUNT,
},
)
)
self.__check_policy_access(app, request)
Event.new(

View File

@ -164,7 +164,7 @@ class SAMLProvider(Provider):
)
sign_assertion = models.BooleanField(default=True)
sign_response = models.BooleanField(default=True)
sign_response = models.BooleanField(default=False)
@property
def launch_url(self) -> str | None:

View File

@ -54,7 +54,11 @@ class TestServiceProviderMetadataParser(TestCase):
request = self.factory.get("/")
metadata = lxml_from_string(MetadataProcessor(provider, request).build_entity_descriptor())
schema = etree.XMLSchema(etree.parse("schemas/saml-schema-metadata-2.0.xsd")) # nosec
schema = etree.XMLSchema(
etree.parse(
source="schemas/saml-schema-metadata-2.0.xsd", parser=etree.XMLParser()
) # nosec
)
self.assertTrue(schema.validate(metadata))
def test_schema_want_authn_requests_signed(self):

View File

@ -47,7 +47,9 @@ class TestSchema(TestCase):
metadata = lxml_from_string(request)
schema = etree.XMLSchema(etree.parse("schemas/saml-schema-protocol-2.0.xsd")) # nosec
schema = etree.XMLSchema(
etree.parse("schemas/saml-schema-protocol-2.0.xsd", parser=etree.XMLParser()) # nosec
)
self.assertTrue(schema.validate(metadata))
def test_response_schema(self):
@ -68,5 +70,7 @@ class TestSchema(TestCase):
metadata = lxml_from_string(response)
schema = etree.XMLSchema(etree.parse("schemas/saml-schema-protocol-2.0.xsd")) # nosec
schema = etree.XMLSchema(
etree.parse("schemas/saml-schema-protocol-2.0.xsd", parser=etree.XMLParser()) # nosec
)
self.assertTrue(schema.validate(metadata))

View File

@ -30,7 +30,9 @@ class TestMetadataProcessor(TestCase):
xml = MetadataProcessor(self.source, request).build_entity_descriptor()
metadata = lxml_from_string(xml)
schema = etree.XMLSchema(etree.parse("schemas/saml-schema-metadata-2.0.xsd")) # nosec
schema = etree.XMLSchema(
etree.parse("schemas/saml-schema-metadata-2.0.xsd", parser=etree.XMLParser()) # nosec
)
self.assertTrue(schema.validate(metadata))
def test_metadata_consistent(self):

View File

@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://goauthentik.io/blueprints/schema.json",
"type": "object",
"title": "authentik 2024.6.4 Blueprint schema",
"title": "authentik 2024.8.0 Blueprint schema",
"required": [
"version",
"entries"

View File

@ -31,7 +31,7 @@ services:
volumes:
- redis:/data
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.6.4}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.8.0}
restart: unless-stopped
command: server
environment:
@ -52,7 +52,7 @@ services:
- postgresql
- redis
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.6.4}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.8.0}
restart: unless-stopped
command: worker
environment:

View File

@ -29,4 +29,4 @@ func UserAgent() string {
return fmt.Sprintf("authentik@%s", FullVersion())
}
const VERSION = "2024.6.4"
const VERSION = "2024.8.0"

View File

@ -1,5 +1,5 @@
{
"name": "@goauthentik/authentik",
"version": "2024.6.4",
"version": "2024.8.0",
"private": true
}

View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "authentik"
version = "2024.6.4"
version = "2024.8.0"
description = ""
authors = ["authentik Team <hello@goauthentik.io>"]

View File

@ -1,7 +1,7 @@
openapi: 3.0.3
info:
title: authentik
version: 2024.6.4
version: 2024.8.0
description: Making authentication simple.
contact:
email: hello@goauthentik.io

View File

@ -46,7 +46,8 @@ async function makeSourcesSelector(instanceSources: string[] | undefined) {
return localSources
? ([pk, _]: DualSelectPair) => localSources.has(pk)
: ([_0, _1, _2, source]: DualSelectPair<Source>) =>
: // Creating a new instance, auto-select built-in source only when no other sources exist
([_0, _1, _2, source]: DualSelectPair<Source>) =>
source !== undefined && source.component === "";
}
@ -75,11 +76,11 @@ export class IdentificationStageForm extends BaseStageForm<IdentificationStage>
stageUuid: this.instance.pk || "",
identificationStageRequest: data,
});
} else {
return new StagesApi(DEFAULT_CONFIG).stagesIdentificationCreate({
identificationStageRequest: data,
});
}
return new StagesApi(DEFAULT_CONFIG).stagesIdentificationCreate({
identificationStageRequest: data,
});
}
isUserFieldSelected(field: UserFieldsEnum): boolean {
@ -232,12 +233,12 @@ export class IdentificationStageForm extends BaseStageForm<IdentificationStage>
?required=${true}
name="sources"
>
<ak-dual-select-provider-dynamic-selected
<ak-dual-select-dynamic-selected
.provider=${sourcesProvider}
.selected=${makeSourcesSelector(this.instance?.sources)}
.selector=${makeSourcesSelector(this.instance?.sources)}
available-label="${msg("Available Stages")}"
selected-label="${msg("Selected Stages")}"
></ak-dual-select-provider-dynamic-selected>
></ak-dual-select-dynamic-selected>
<p class="pf-c-form__helper-text">
${msg(
"Select sources should be shown for users to authenticate with. This only affects web-based sources, not LDAP.",

View File

@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success";
export const ERROR_CLASS = "pf-m-danger";
export const PROGRESS_CLASS = "pf-m-in-progress";
export const CURRENT_CLASS = "pf-m-current";
export const VERSION = "2024.6.4";
export const VERSION = "2024.8.0";
export const TITLE_DEFAULT = "authentik";
export const ROUTE_SEPARATOR = ";";

View File

@ -50,3 +50,9 @@ export class AkDualSelectDynamic extends AkDualSelectProvider {
></ak-dual-select>`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ak-dual-select-dynamic-selected": AkDualSelectDynamic;
}
}

View File

@ -36,11 +36,11 @@ To disable existing blueprints, an empty file can be mounted over the existing b
File-based blueprints are automatically removed once they become unavailable, however none of the objects created by those blueprints afre affected by this.
:::info
Please note that, by default, blueprint discovery and evaluation is not guaranteed to follow any specific order.
:::info
Please note that, by default, blueprint discovery and evaluation is not guaranteed to follow any specific order.
If you have dependencies between blueprints, you should use [meta models](/developer-docs/blueprints/v1/meta#authentik_blueprintsmetaapplyblueprint) to make sure that objects are created in the correct order.
:::
If you have dependencies between blueprints, you should use [meta models](./v1/meta#authentik_blueprintsmetaapplyblueprint) to make sure that objects are created in the correct order.
:::
## Storage - OCI

View File

@ -105,11 +105,7 @@ The following events occur when a license expeires and is not renewed within two
### About users and licenses
License usage is calculated based on total user counts and log-in data data that authentik regularly captures. This data is checked against all valid licenses, and the sum total of all users.
- The **_internal user_** count is calculated based on actual users assigned to the organization.
- The **_external user_** count is calculated based on how many external users were active (i.e. logged in) since the start of the current month.
License usage is calculated based on total user counts that authentik regularly captures. This data is checked against all valid licenses, and the sum total of all users. Internal and external users are counted based on the number of active users of the respective type saved in authentik. Service account users are not counted towards the license.
:::info
An **internal** user is typically a team member, such as company employees, who has access to the full Enterprise feature set. An **external** user might be an external consultant, a volunteer in a charitable site, or a B2C customer who logged onto your website to shop. These users don't get access to Enterprise features.

View File

@ -18,7 +18,8 @@ Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&
client_id=application_client_id&
username=my-service-account&
password=my-token
password=my-token&
scope=profile
```
This will return a JSON response with an `access_token`, which is a signed JWT token. This token can be sent along requests to other hosts, which can then validate the JWT based on the signing key configured in authentik.

File diff suppressed because it is too large Load Diff