sources/oauth2: add API For UserSourceConnection
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
3698c6431c
commit
17f7a97ef3
|
@ -57,7 +57,10 @@ from authentik.providers.proxy.api import (
|
||||||
)
|
)
|
||||||
from authentik.providers.saml.api import SAMLPropertyMappingViewSet, SAMLProviderViewSet
|
from authentik.providers.saml.api import SAMLPropertyMappingViewSet, SAMLProviderViewSet
|
||||||
from authentik.sources.ldap.api import LDAPPropertyMappingViewSet, LDAPSourceViewSet
|
from authentik.sources.ldap.api import LDAPPropertyMappingViewSet, LDAPSourceViewSet
|
||||||
from authentik.sources.oauth.api import OAuthSourceViewSet
|
from authentik.sources.oauth.api.source import OAuthSourceViewSet
|
||||||
|
from authentik.sources.oauth.api.source_connection import (
|
||||||
|
UserOAuthSourceConnectionViewSet,
|
||||||
|
)
|
||||||
from authentik.sources.saml.api import SAMLSourceViewSet
|
from authentik.sources.saml.api import SAMLSourceViewSet
|
||||||
from authentik.stages.authenticator_static.api import (
|
from authentik.stages.authenticator_static.api import (
|
||||||
AuthenticatorStaticStageViewSet,
|
AuthenticatorStaticStageViewSet,
|
||||||
|
@ -104,6 +107,7 @@ router.register("core/applications", ApplicationViewSet)
|
||||||
router.register("core/groups", GroupViewSet)
|
router.register("core/groups", GroupViewSet)
|
||||||
router.register("core/users", UserViewSet)
|
router.register("core/users", UserViewSet)
|
||||||
router.register("core/user_consent", UserConsentViewSet)
|
router.register("core/user_consent", UserConsentViewSet)
|
||||||
|
router.register("core/source_user_connections_oauth", UserOAuthSourceConnectionViewSet)
|
||||||
router.register("core/tokens", TokenViewSet)
|
router.register("core/tokens", TokenViewSet)
|
||||||
|
|
||||||
router.register("outposts/outposts", OutpostViewSet)
|
router.register("outposts/outposts", OutpostViewSet)
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
"""OAuth Source Serializer"""
|
||||||
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.sources import SourceSerializer
|
||||||
|
from authentik.sources.oauth.models import UserOAuthSourceConnection
|
||||||
|
|
||||||
|
|
||||||
|
class UserOAuthSourceConnectionSerializer(SourceSerializer):
|
||||||
|
"""OAuth Source Serializer"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = UserOAuthSourceConnection
|
||||||
|
fields = [
|
||||||
|
"user",
|
||||||
|
"source",
|
||||||
|
"identifier",
|
||||||
|
"access_token",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class UserOAuthSourceConnectionViewSet(ModelViewSet):
|
||||||
|
"""Source Viewset"""
|
||||||
|
|
||||||
|
queryset = UserOAuthSourceConnection.objects.all()
|
||||||
|
serializer_class = UserOAuthSourceConnectionSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
if not self.request:
|
||||||
|
return super().get_queryset()
|
||||||
|
if self.request.user.is_superuser:
|
||||||
|
return super().get_queryset()
|
||||||
|
return super().get_queryset().filter(user=self.request.user)
|
|
@ -51,7 +51,7 @@ class OAuthSource(Source):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def serializer(self) -> Type[Serializer]:
|
def serializer(self) -> Type[Serializer]:
|
||||||
from authentik.sources.oauth.api import OAuthSourceSerializer
|
from authentik.sources.oauth.api.source import OAuthSourceSerializer
|
||||||
|
|
||||||
return OAuthSourceSerializer
|
return OAuthSourceSerializer
|
||||||
|
|
||||||
|
|
164
swagger.yaml
164
swagger.yaml
|
@ -1188,6 +1188,147 @@ paths:
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
|
/core/source_user_connections_oauth/:
|
||||||
|
get:
|
||||||
|
operationId: core_source_user_connections_oauth_list
|
||||||
|
description: Source Viewset
|
||||||
|
parameters:
|
||||||
|
- name: ordering
|
||||||
|
in: query
|
||||||
|
description: Which field to use when ordering the results.
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: search
|
||||||
|
in: query
|
||||||
|
description: A search term.
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: page
|
||||||
|
in: query
|
||||||
|
description: Page Index
|
||||||
|
required: false
|
||||||
|
type: integer
|
||||||
|
- name: page_size
|
||||||
|
in: query
|
||||||
|
description: Page Size
|
||||||
|
required: false
|
||||||
|
type: integer
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: ''
|
||||||
|
schema:
|
||||||
|
required:
|
||||||
|
- results
|
||||||
|
- pagination
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
pagination:
|
||||||
|
required:
|
||||||
|
- next
|
||||||
|
- previous
|
||||||
|
- count
|
||||||
|
- current
|
||||||
|
- total_pages
|
||||||
|
- start_index
|
||||||
|
- end_index
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
next:
|
||||||
|
type: number
|
||||||
|
previous:
|
||||||
|
type: number
|
||||||
|
count:
|
||||||
|
type: number
|
||||||
|
current:
|
||||||
|
type: number
|
||||||
|
total_pages:
|
||||||
|
type: number
|
||||||
|
start_index:
|
||||||
|
type: number
|
||||||
|
end_index:
|
||||||
|
type: number
|
||||||
|
results:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/UserOAuthSourceConnection'
|
||||||
|
tags:
|
||||||
|
- core
|
||||||
|
post:
|
||||||
|
operationId: core_source_user_connections_oauth_create
|
||||||
|
description: Source Viewset
|
||||||
|
parameters:
|
||||||
|
- name: data
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/UserOAuthSourceConnection'
|
||||||
|
responses:
|
||||||
|
'201':
|
||||||
|
description: ''
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/UserOAuthSourceConnection'
|
||||||
|
tags:
|
||||||
|
- core
|
||||||
|
parameters: []
|
||||||
|
/core/source_user_connections_oauth/{id}/:
|
||||||
|
get:
|
||||||
|
operationId: core_source_user_connections_oauth_read
|
||||||
|
description: Source Viewset
|
||||||
|
parameters: []
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: ''
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/UserOAuthSourceConnection'
|
||||||
|
tags:
|
||||||
|
- core
|
||||||
|
put:
|
||||||
|
operationId: core_source_user_connections_oauth_update
|
||||||
|
description: Source Viewset
|
||||||
|
parameters:
|
||||||
|
- name: data
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/UserOAuthSourceConnection'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: ''
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/UserOAuthSourceConnection'
|
||||||
|
tags:
|
||||||
|
- core
|
||||||
|
patch:
|
||||||
|
operationId: core_source_user_connections_oauth_partial_update
|
||||||
|
description: Source Viewset
|
||||||
|
parameters:
|
||||||
|
- name: data
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/UserOAuthSourceConnection'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: ''
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/UserOAuthSourceConnection'
|
||||||
|
tags:
|
||||||
|
- core
|
||||||
|
delete:
|
||||||
|
operationId: core_source_user_connections_oauth_delete
|
||||||
|
description: Source Viewset
|
||||||
|
parameters: []
|
||||||
|
responses:
|
||||||
|
'204':
|
||||||
|
description: ''
|
||||||
|
tags:
|
||||||
|
- core
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
description: A unique integer value identifying this User OAuth Source Connection.
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
/core/tokens/:
|
/core/tokens/:
|
||||||
get:
|
get:
|
||||||
operationId: core_tokens_list
|
operationId: core_tokens_list
|
||||||
|
@ -10807,6 +10948,29 @@ definitions:
|
||||||
attributes:
|
attributes:
|
||||||
title: Attributes
|
title: Attributes
|
||||||
type: object
|
type: object
|
||||||
|
UserOAuthSourceConnection:
|
||||||
|
description: OAuth Source Serializer
|
||||||
|
required:
|
||||||
|
- user
|
||||||
|
- source
|
||||||
|
- identifier
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
user:
|
||||||
|
title: User
|
||||||
|
type: integer
|
||||||
|
source:
|
||||||
|
title: Source
|
||||||
|
type: string
|
||||||
|
identifier:
|
||||||
|
title: Identifier
|
||||||
|
type: string
|
||||||
|
maxLength: 255
|
||||||
|
minLength: 1
|
||||||
|
access_token:
|
||||||
|
title: Access token
|
||||||
|
type: string
|
||||||
|
x-nullable: true
|
||||||
User:
|
User:
|
||||||
title: User
|
title: User
|
||||||
description: User Serializer
|
description: User Serializer
|
||||||
|
|
|
@ -152,6 +152,7 @@ class TestProviderOAuth2OIDCImplicit(SeleniumTestCase):
|
||||||
self.container = self.setup_client()
|
self.container = self.setup_client()
|
||||||
|
|
||||||
self.driver.get("http://localhost:9009/implicit/")
|
self.driver.get("http://localhost:9009/implicit/")
|
||||||
|
sleep(2)
|
||||||
self.login()
|
self.login()
|
||||||
self.wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "pre")))
|
self.wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "pre")))
|
||||||
sleep(1)
|
sleep(1)
|
||||||
|
@ -264,6 +265,7 @@ class TestProviderOAuth2OIDCImplicit(SeleniumTestCase):
|
||||||
|
|
||||||
self.container = self.setup_client()
|
self.container = self.setup_client()
|
||||||
self.driver.get("http://localhost:9009/implicit/")
|
self.driver.get("http://localhost:9009/implicit/")
|
||||||
|
sleep(2)
|
||||||
self.login()
|
self.login()
|
||||||
self.wait.until(
|
self.wait.until(
|
||||||
ec.presence_of_element_located((By.CSS_SELECTOR, "header > h1"))
|
ec.presence_of_element_located((By.CSS_SELECTOR, "header > h1"))
|
||||||
|
|
|
@ -32,6 +32,7 @@ from authentik.core.api.users import UserSerializer
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.managed.manager import ObjectManager
|
from authentik.managed.manager import ObjectManager
|
||||||
|
|
||||||
|
RETRIES = int(environ.get("RETRIES", "3"))
|
||||||
|
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
def USER() -> User: # noqa
|
def USER() -> User: # noqa
|
||||||
|
@ -205,7 +206,7 @@ def object_manager(func: Callable):
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def retry(max_retires=3, exceptions=None):
|
def retry(max_retires=RETRIES, exceptions=None):
|
||||||
"""Retry test multiple times. Default to catching Selenium Timeout Exception"""
|
"""Retry test multiple times. Default to catching Selenium Timeout Exception"""
|
||||||
|
|
||||||
if not exceptions:
|
if not exceptions:
|
||||||
|
|
Reference in New Issue