Compare commits
6 Commits
imports-fo
...
version/20
Author | SHA1 | Date | |
---|---|---|---|
f059b998cc | |||
3f48202dfe | |||
2a3ebb616b | |||
ceab1f732d | |||
01d2cce9ca | |||
72f85defb8 |
@ -1,5 +1,5 @@
|
|||||||
[bumpversion]
|
[bumpversion]
|
||||||
current_version = 2023.3.0
|
current_version = 2023.3.1
|
||||||
tag = True
|
tag = True
|
||||||
commit = True
|
commit = True
|
||||||
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)
|
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)
|
||||||
|
@ -12,3 +12,6 @@ indent_size = 2
|
|||||||
|
|
||||||
[*.{yaml,yml}]
|
[*.{yaml,yml}]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.go]
|
||||||
|
indent_style = tab
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
from os import environ
|
from os import environ
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
__version__ = "2023.3.0"
|
__version__ = "2023.3.1"
|
||||||
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"
|
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"
|
||||||
|
|
||||||
|
|
||||||
|
@ -355,6 +355,62 @@ class TestAuthorize(OAuthTestCase):
|
|||||||
delta=5,
|
delta=5,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_full_fragment_code(self):
|
||||||
|
"""Test full authorization"""
|
||||||
|
flow = create_test_flow()
|
||||||
|
provider: OAuth2Provider = OAuth2Provider.objects.create(
|
||||||
|
name=generate_id(),
|
||||||
|
client_id="test",
|
||||||
|
client_secret=generate_key(),
|
||||||
|
authorization_flow=flow,
|
||||||
|
redirect_uris="http://localhost",
|
||||||
|
signing_key=self.keypair,
|
||||||
|
)
|
||||||
|
Application.objects.create(name="app", slug="app", provider=provider)
|
||||||
|
state = generate_id()
|
||||||
|
user = create_test_admin_user()
|
||||||
|
self.client.force_login(user)
|
||||||
|
with patch(
|
||||||
|
"authentik.providers.oauth2.id_token.get_login_event",
|
||||||
|
MagicMock(
|
||||||
|
return_value=Event(
|
||||||
|
action=EventAction.LOGIN,
|
||||||
|
context={PLAN_CONTEXT_METHOD: "password"},
|
||||||
|
created=now(),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
):
|
||||||
|
# Step 1, initiate params and get redirect to flow
|
||||||
|
self.client.get(
|
||||||
|
reverse("authentik_providers_oauth2:authorize"),
|
||||||
|
data={
|
||||||
|
"response_type": "code",
|
||||||
|
"response_mode": "fragment",
|
||||||
|
"client_id": "test",
|
||||||
|
"state": state,
|
||||||
|
"scope": "openid",
|
||||||
|
"redirect_uri": "http://localhost",
|
||||||
|
"nonce": generate_id(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
response = self.client.get(
|
||||||
|
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
|
||||||
|
)
|
||||||
|
code: AuthorizationCode = AuthorizationCode.objects.filter(user=user).first()
|
||||||
|
self.assertJSONEqual(
|
||||||
|
response.content.decode(),
|
||||||
|
{
|
||||||
|
"component": "xak-flow-redirect",
|
||||||
|
"type": ChallengeTypes.REDIRECT.value,
|
||||||
|
"to": (f"http://localhost#code={code.code}" f"&state={state}"),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
self.assertAlmostEqual(
|
||||||
|
code.expires.timestamp() - now().timestamp(),
|
||||||
|
timedelta_from_string(provider.access_code_validity).total_seconds(),
|
||||||
|
delta=5,
|
||||||
|
)
|
||||||
|
|
||||||
def test_full_form_post_id_token(self):
|
def test_full_form_post_id_token(self):
|
||||||
"""Test full authorization (form_post response)"""
|
"""Test full authorization (form_post response)"""
|
||||||
flow = create_test_flow()
|
flow = create_test_flow()
|
||||||
|
@ -514,7 +514,12 @@ class OAuthFulfillmentStage(StageView):
|
|||||||
return urlunsplit(uri)
|
return urlunsplit(uri)
|
||||||
|
|
||||||
if self.params.response_mode == ResponseMode.FRAGMENT:
|
if self.params.response_mode == ResponseMode.FRAGMENT:
|
||||||
query_fragment = self.create_implicit_response(code)
|
query_fragment = {}
|
||||||
|
if self.params.grant_type in [GrantTypes.AUTHORIZATION_CODE]:
|
||||||
|
query_fragment["code"] = code.code
|
||||||
|
query_fragment["state"] = [str(self.params.state) if self.params.state else ""]
|
||||||
|
else:
|
||||||
|
query_fragment = self.create_implicit_response(code)
|
||||||
|
|
||||||
uri = uri._replace(
|
uri = uri._replace(
|
||||||
fragment=uri.fragment + urlencode(query_fragment, doseq=True),
|
fragment=uri.fragment + urlencode(query_fragment, doseq=True),
|
||||||
|
@ -32,7 +32,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- redis:/data
|
- redis:/data
|
||||||
server:
|
server:
|
||||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.3.0}
|
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.3.1}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: server
|
command: server
|
||||||
environment:
|
environment:
|
||||||
@ -50,7 +50,7 @@ services:
|
|||||||
- "${AUTHENTIK_PORT_HTTP:-9000}:9000"
|
- "${AUTHENTIK_PORT_HTTP:-9000}:9000"
|
||||||
- "${AUTHENTIK_PORT_HTTPS:-9443}:9443"
|
- "${AUTHENTIK_PORT_HTTPS:-9443}:9443"
|
||||||
worker:
|
worker:
|
||||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.3.0}
|
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.3.1}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: worker
|
command: worker
|
||||||
environment:
|
environment:
|
||||||
|
@ -29,4 +29,4 @@ func UserAgent() string {
|
|||||||
return fmt.Sprintf("authentik@%s", FullVersion())
|
return fmt.Sprintf("authentik@%s", FullVersion())
|
||||||
}
|
}
|
||||||
|
|
||||||
const VERSION = "2023.3.0"
|
const VERSION = "2023.3.1"
|
||||||
|
@ -30,11 +30,15 @@ func (pi *ProviderInstance) UserEntry(u api.User) *ldap.Entry {
|
|||||||
// Only append attributes that don't already exist
|
// Only append attributes that don't already exist
|
||||||
// TODO: Remove in 2023.3
|
// TODO: Remove in 2023.3
|
||||||
for _, rawAttr := range rawAttrs {
|
for _, rawAttr := range rawAttrs {
|
||||||
|
exists := false
|
||||||
for _, attr := range attrs {
|
for _, attr := range attrs {
|
||||||
if !strings.EqualFold(attr.Name, rawAttr.Name) {
|
if strings.EqualFold(attr.Name, rawAttr.Name) {
|
||||||
attrs = append(attrs, rawAttr)
|
exists = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !exists {
|
||||||
|
attrs = append(attrs, rawAttr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if u.IsActive == nil {
|
if u.IsActive == nil {
|
||||||
|
@ -36,11 +36,15 @@ func (lg *LDAPGroup) Entry() *ldap.Entry {
|
|||||||
// Only append attributes that don't already exist
|
// Only append attributes that don't already exist
|
||||||
// TODO: Remove in 2023.3
|
// TODO: Remove in 2023.3
|
||||||
for _, rawAttr := range rawAttrs {
|
for _, rawAttr := range rawAttrs {
|
||||||
|
exists := false
|
||||||
for _, attr := range attrs {
|
for _, attr := range attrs {
|
||||||
if !strings.EqualFold(attr.Name, rawAttr.Name) {
|
if strings.EqualFold(attr.Name, rawAttr.Name) {
|
||||||
attrs = append(attrs, rawAttr)
|
exists = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !exists {
|
||||||
|
attrs = append(attrs, rawAttr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
objectClass := []string{constants.OCGroup, constants.OCGroupOfUniqueNames, constants.OCGroupOfNames, constants.OCAKGroup, constants.OCPosixGroup}
|
objectClass := []string{constants.OCGroup, constants.OCGroupOfUniqueNames, constants.OCGroupOfNames, constants.OCAKGroup, constants.OCPosixGroup}
|
||||||
|
@ -105,7 +105,7 @@ filterwarnings = [
|
|||||||
|
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "authentik"
|
name = "authentik"
|
||||||
version = "2023.3.0"
|
version = "2023.3.1"
|
||||||
description = ""
|
description = ""
|
||||||
authors = ["authentik Team <hello@goauthentik.io>"]
|
authors = ["authentik Team <hello@goauthentik.io>"]
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
openapi: 3.0.3
|
openapi: 3.0.3
|
||||||
info:
|
info:
|
||||||
title: authentik
|
title: authentik
|
||||||
version: 2023.3.0
|
version: 2023.3.1
|
||||||
description: Making authentication simple.
|
description: Making authentication simple.
|
||||||
contact:
|
contact:
|
||||||
email: hello@goauthentik.io
|
email: hello@goauthentik.io
|
||||||
|
@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success";
|
|||||||
export const ERROR_CLASS = "pf-m-danger";
|
export const ERROR_CLASS = "pf-m-danger";
|
||||||
export const PROGRESS_CLASS = "pf-m-in-progress";
|
export const PROGRESS_CLASS = "pf-m-in-progress";
|
||||||
export const CURRENT_CLASS = "pf-m-current";
|
export const CURRENT_CLASS = "pf-m-current";
|
||||||
export const VERSION = "2023.3.0";
|
export const VERSION = "2023.3.1";
|
||||||
export const TITLE_DEFAULT = "authentik";
|
export const TITLE_DEFAULT = "authentik";
|
||||||
export const ROUTE_SEPARATOR = ";";
|
export const ROUTE_SEPARATOR = ";";
|
||||||
|
|
||||||
|
@ -37,7 +37,6 @@ import PFDrawer from "@patternfly/patternfly/components/Drawer/drawer.css";
|
|||||||
import PFList from "@patternfly/patternfly/components/List/list.css";
|
import PFList from "@patternfly/patternfly/components/List/list.css";
|
||||||
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
|
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
|
||||||
import PFTitle from "@patternfly/patternfly/components/Title/title.css";
|
import PFTitle from "@patternfly/patternfly/components/Title/title.css";
|
||||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ChallengeChoices,
|
ChallengeChoices,
|
||||||
@ -120,7 +119,7 @@ export class FlowExecutor extends Interface implements StageHost {
|
|||||||
ws: WebsocketClient;
|
ws: WebsocketClient;
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResult[] {
|
||||||
return [PFBase, PFLogin, PFDrawer, PFButton, PFTitle, PFList, PFBackgroundImage].concat(css`
|
return [PFLogin, PFDrawer, PFButton, PFTitle, PFList, PFBackgroundImage].concat(css`
|
||||||
.pf-c-background-image::before {
|
.pf-c-background-image::before {
|
||||||
--pf-c-background-image--BackgroundImage: var(--ak-flow-background);
|
--pf-c-background-image--BackgroundImage: var(--ak-flow-background);
|
||||||
--pf-c-background-image--BackgroundImage-2x: var(--ak-flow-background);
|
--pf-c-background-image--BackgroundImage-2x: var(--ak-flow-background);
|
||||||
|
@ -16,7 +16,6 @@ import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
|||||||
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
|
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
|
||||||
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
|
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
|
||||||
import PFTitle from "@patternfly/patternfly/components/Title/title.css";
|
import PFTitle from "@patternfly/patternfly/components/Title/title.css";
|
||||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
AuthenticatorValidationChallenge,
|
AuthenticatorValidationChallenge,
|
||||||
@ -77,7 +76,7 @@ export class AuthenticatorValidateStage
|
|||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResult[] {
|
||||||
return [PFBase, PFLogin, PFForm, PFFormControl, PFTitle, PFButton].concat(css`
|
return [PFLogin, PFForm, PFFormControl, PFTitle, PFButton].concat(css`
|
||||||
ul {
|
ul {
|
||||||
padding-top: 1rem;
|
padding-top: 1rem;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user