sources/oauth: ensure all UI sources return a valid source (#9401)
* web/admin: prevent selection of inbuilt source in identification stage Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix apple source Signed-off-by: Jens Langhammer <jens@goauthentik.io> * also fix plex challenge Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
37
authentik/sources/oauth/tests/test_type_apple.py
Normal file
37
authentik/sources/oauth/tests/test_type_apple.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
"""Apple Type tests"""
|
||||||
|
|
||||||
|
from django.test import RequestFactory, TestCase
|
||||||
|
from guardian.shortcuts import get_anonymous_user
|
||||||
|
|
||||||
|
from authentik.lib.generators import generate_id
|
||||||
|
from authentik.lib.tests.utils import dummy_get_response
|
||||||
|
from authentik.root.middleware import SessionMiddleware
|
||||||
|
from authentik.sources.oauth.models import OAuthSource
|
||||||
|
from authentik.sources.oauth.types.registry import registry
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeApple(TestCase):
|
||||||
|
"""OAuth Source tests"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.source = OAuthSource.objects.create(
|
||||||
|
name="test",
|
||||||
|
slug="test",
|
||||||
|
provider_type="apple",
|
||||||
|
authorization_url="",
|
||||||
|
profile_url="",
|
||||||
|
consumer_key=generate_id(),
|
||||||
|
)
|
||||||
|
self.factory = RequestFactory()
|
||||||
|
|
||||||
|
def test_login_challenge(self):
|
||||||
|
"""Test login_challenge"""
|
||||||
|
request = self.factory.get("/")
|
||||||
|
request.user = get_anonymous_user()
|
||||||
|
|
||||||
|
middleware = SessionMiddleware(dummy_get_response)
|
||||||
|
middleware.process_request(request)
|
||||||
|
request.session.save()
|
||||||
|
oauth_type = registry.find_type("apple")
|
||||||
|
challenge = oauth_type().login_challenge(self.source, request)
|
||||||
|
self.assertTrue(challenge.is_valid(raise_exception=True))
|
@ -125,7 +125,7 @@ class AppleType(SourceType):
|
|||||||
)
|
)
|
||||||
args = apple_client.get_redirect_args()
|
args = apple_client.get_redirect_args()
|
||||||
return AppleLoginChallenge(
|
return AppleLoginChallenge(
|
||||||
instance={
|
data={
|
||||||
"client_id": apple_client.get_client_id(),
|
"client_id": apple_client.get_client_id(),
|
||||||
"scope": "name email",
|
"scope": "name email",
|
||||||
"redirect_uri": args["redirect_uri"],
|
"redirect_uri": args["redirect_uri"],
|
||||||
|
@ -66,7 +66,7 @@ class PlexSource(Source):
|
|||||||
icon = static("authentik/sources/plex.svg")
|
icon = static("authentik/sources/plex.svg")
|
||||||
return UILoginButton(
|
return UILoginButton(
|
||||||
challenge=PlexAuthenticationChallenge(
|
challenge=PlexAuthenticationChallenge(
|
||||||
{
|
data={
|
||||||
"type": ChallengeTypes.NATIVE.value,
|
"type": ChallengeTypes.NATIVE.value,
|
||||||
"component": "ak-source-plex",
|
"component": "ak-source-plex",
|
||||||
"client_id": self.client_id,
|
"client_id": self.client_id,
|
||||||
|
@ -40,6 +40,11 @@ class TestPlexSource(TestCase):
|
|||||||
slug="test",
|
slug="test",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_login_challenge(self):
|
||||||
|
"""Test login_challenge"""
|
||||||
|
ui_login_button = self.source.ui_login_button(None)
|
||||||
|
self.assertTrue(ui_login_button.challenge.is_valid(raise_exception=True))
|
||||||
|
|
||||||
def test_get_user_info(self):
|
def test_get_user_info(self):
|
||||||
"""Test get_user_info"""
|
"""Test get_user_info"""
|
||||||
token = generate_key()
|
token = generate_key()
|
||||||
|
@ -237,6 +237,8 @@ class IdentificationStageView(ChallengeStageView):
|
|||||||
)
|
)
|
||||||
for source in sources:
|
for source in sources:
|
||||||
ui_login_button = source.ui_login_button(self.request)
|
ui_login_button = source.ui_login_button(self.request)
|
||||||
|
if source.component == "":
|
||||||
|
continue
|
||||||
if ui_login_button:
|
if ui_login_button:
|
||||||
button = asdict(ui_login_button)
|
button = asdict(ui_login_button)
|
||||||
source_challenge = ui_login_button.challenge
|
source_challenge = ui_login_button.challenge
|
||||||
|
@ -214,28 +214,23 @@ export class IdentificationStageForm extends BaseStageForm<IdentificationStage>
|
|||||||
name="sources"
|
name="sources"
|
||||||
>
|
>
|
||||||
<select class="pf-c-form-control" multiple>
|
<select class="pf-c-form-control" multiple>
|
||||||
${this.sources?.results.map((source) => {
|
${this.sources?.results
|
||||||
let selected = Array.from(this.instance?.sources || []).some(
|
.filter((source) => {
|
||||||
(su) => {
|
return source.component !== "";
|
||||||
return su == source.pk;
|
})
|
||||||
},
|
.map((source) => {
|
||||||
);
|
const selected = Array.from(this.instance?.sources || []).some(
|
||||||
// Creating a new instance, auto-select built-in source
|
(su) => {
|
||||||
// Only when no other sources exist
|
return su == source.pk;
|
||||||
if (
|
},
|
||||||
!this.instance &&
|
);
|
||||||
source.component === "" &&
|
return html`<option
|
||||||
(this.sources?.results || []).length < 2
|
value=${ifDefined(source.pk)}
|
||||||
) {
|
?selected=${selected}
|
||||||
selected = true;
|
>
|
||||||
}
|
${source.name}
|
||||||
return html`<option
|
</option>`;
|
||||||
value=${ifDefined(source.pk)}
|
})}
|
||||||
?selected=${selected}
|
|
||||||
>
|
|
||||||
${source.name}
|
|
||||||
</option>`;
|
|
||||||
})}
|
|
||||||
</select>
|
</select>
|
||||||
<p class="pf-c-form__helper-text">
|
<p class="pf-c-form__helper-text">
|
||||||
${msg(
|
${msg(
|
||||||
|
Reference in New Issue
Block a user