Compare commits
	
		
			6 Commits
		
	
	
		
			version/20
			...
			version/20
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f059b998cc | |||
| 3f48202dfe | |||
| 2a3ebb616b | |||
| ceab1f732d | |||
| 01d2cce9ca | |||
| 72f85defb8 | 
@ -1,5 +1,5 @@
 | 
			
		||||
[bumpversion]
 | 
			
		||||
current_version = 2023.3.0
 | 
			
		||||
current_version = 2023.3.1
 | 
			
		||||
tag = True
 | 
			
		||||
commit = True
 | 
			
		||||
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)
 | 
			
		||||
 | 
			
		||||
@ -12,3 +12,6 @@ indent_size = 2
 | 
			
		||||
 | 
			
		||||
[*.{yaml,yml}]
 | 
			
		||||
indent_size = 2
 | 
			
		||||
 | 
			
		||||
[*.go]
 | 
			
		||||
indent_style = tab
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
from os import environ
 | 
			
		||||
from typing import Optional
 | 
			
		||||
 | 
			
		||||
__version__ = "2023.3.0"
 | 
			
		||||
__version__ = "2023.3.1"
 | 
			
		||||
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -355,6 +355,62 @@ class TestAuthorize(OAuthTestCase):
 | 
			
		||||
                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):
 | 
			
		||||
        """Test full authorization (form_post response)"""
 | 
			
		||||
        flow = create_test_flow()
 | 
			
		||||
 | 
			
		||||
@ -514,7 +514,12 @@ class OAuthFulfillmentStage(StageView):
 | 
			
		||||
                return urlunsplit(uri)
 | 
			
		||||
 | 
			
		||||
            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(
 | 
			
		||||
                    fragment=uri.fragment + urlencode(query_fragment, doseq=True),
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,7 @@ services:
 | 
			
		||||
    volumes:
 | 
			
		||||
      - redis:/data
 | 
			
		||||
  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
 | 
			
		||||
    command: server
 | 
			
		||||
    environment:
 | 
			
		||||
@ -50,7 +50,7 @@ services:
 | 
			
		||||
      - "${AUTHENTIK_PORT_HTTP:-9000}:9000"
 | 
			
		||||
      - "${AUTHENTIK_PORT_HTTPS:-9443}:9443"
 | 
			
		||||
  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
 | 
			
		||||
    command: worker
 | 
			
		||||
    environment:
 | 
			
		||||
 | 
			
		||||
@ -29,4 +29,4 @@ func UserAgent() string {
 | 
			
		||||
	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
 | 
			
		||||
	// TODO: Remove in 2023.3
 | 
			
		||||
	for _, rawAttr := range rawAttrs {
 | 
			
		||||
		exists := false
 | 
			
		||||
		for _, attr := range attrs {
 | 
			
		||||
			if !strings.EqualFold(attr.Name, rawAttr.Name) {
 | 
			
		||||
				attrs = append(attrs, rawAttr)
 | 
			
		||||
			if strings.EqualFold(attr.Name, rawAttr.Name) {
 | 
			
		||||
				exists = true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if !exists {
 | 
			
		||||
			attrs = append(attrs, rawAttr)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if u.IsActive == nil {
 | 
			
		||||
 | 
			
		||||
@ -36,11 +36,15 @@ func (lg *LDAPGroup) Entry() *ldap.Entry {
 | 
			
		||||
	// Only append attributes that don't already exist
 | 
			
		||||
	// TODO: Remove in 2023.3
 | 
			
		||||
	for _, rawAttr := range rawAttrs {
 | 
			
		||||
		exists := false
 | 
			
		||||
		for _, attr := range attrs {
 | 
			
		||||
			if !strings.EqualFold(attr.Name, rawAttr.Name) {
 | 
			
		||||
				attrs = append(attrs, rawAttr)
 | 
			
		||||
			if strings.EqualFold(attr.Name, rawAttr.Name) {
 | 
			
		||||
				exists = true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if !exists {
 | 
			
		||||
			attrs = append(attrs, rawAttr)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	objectClass := []string{constants.OCGroup, constants.OCGroupOfUniqueNames, constants.OCGroupOfNames, constants.OCAKGroup, constants.OCPosixGroup}
 | 
			
		||||
 | 
			
		||||
@ -105,7 +105,7 @@ filterwarnings = [
 | 
			
		||||
 | 
			
		||||
[tool.poetry]
 | 
			
		||||
name = "authentik"
 | 
			
		||||
version = "2023.3.0"
 | 
			
		||||
version = "2023.3.1"
 | 
			
		||||
description = ""
 | 
			
		||||
authors = ["authentik Team <hello@goauthentik.io>"]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
openapi: 3.0.3
 | 
			
		||||
info:
 | 
			
		||||
  title: authentik
 | 
			
		||||
  version: 2023.3.0
 | 
			
		||||
  version: 2023.3.1
 | 
			
		||||
  description: Making authentication simple.
 | 
			
		||||
  contact:
 | 
			
		||||
    email: hello@goauthentik.io
 | 
			
		||||
 | 
			
		||||
@ -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 = "2023.3.0";
 | 
			
		||||
export const VERSION = "2023.3.1";
 | 
			
		||||
export const TITLE_DEFAULT = "authentik";
 | 
			
		||||
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 PFLogin from "@patternfly/patternfly/components/Login/login.css";
 | 
			
		||||
import PFTitle from "@patternfly/patternfly/components/Title/title.css";
 | 
			
		||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
    ChallengeChoices,
 | 
			
		||||
@ -120,7 +119,7 @@ export class FlowExecutor extends Interface implements StageHost {
 | 
			
		||||
    ws: WebsocketClient;
 | 
			
		||||
 | 
			
		||||
    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--BackgroundImage: 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 PFLogin from "@patternfly/patternfly/components/Login/login.css";
 | 
			
		||||
import PFTitle from "@patternfly/patternfly/components/Title/title.css";
 | 
			
		||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
    AuthenticatorValidationChallenge,
 | 
			
		||||
@ -77,7 +76,7 @@ export class AuthenticatorValidateStage
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static get styles(): CSSResult[] {
 | 
			
		||||
        return [PFBase, PFLogin, PFForm, PFFormControl, PFTitle, PFButton].concat(css`
 | 
			
		||||
        return [PFLogin, PFForm, PFFormControl, PFTitle, PFButton].concat(css`
 | 
			
		||||
            ul {
 | 
			
		||||
                padding-top: 1rem;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user