sources/oauth2: add API For UserSourceConnection

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-03-24 14:43:46 +01:00
parent 3698c6431c
commit 17f7a97ef3
8 changed files with 206 additions and 3 deletions

View file

@ -57,7 +57,10 @@ from authentik.providers.proxy.api import (
)
from authentik.providers.saml.api import SAMLPropertyMappingViewSet, SAMLProviderViewSet
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.stages.authenticator_static.api import (
AuthenticatorStaticStageViewSet,
@ -104,6 +107,7 @@ router.register("core/applications", ApplicationViewSet)
router.register("core/groups", GroupViewSet)
router.register("core/users", UserViewSet)
router.register("core/user_consent", UserConsentViewSet)
router.register("core/source_user_connections_oauth", UserOAuthSourceConnectionViewSet)
router.register("core/tokens", TokenViewSet)
router.register("outposts/outposts", OutpostViewSet)

View file

View file

@ -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)

View file

@ -51,7 +51,7 @@ class OAuthSource(Source):
@property
def serializer(self) -> Type[Serializer]:
from authentik.sources.oauth.api import OAuthSourceSerializer
from authentik.sources.oauth.api.source import OAuthSourceSerializer
return OAuthSourceSerializer

View file

@ -1188,6 +1188,147 @@ paths:
required: true
type: string
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/:
get:
operationId: core_tokens_list
@ -10807,6 +10948,29 @@ definitions:
attributes:
title: Attributes
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:
title: User
description: User Serializer

View file

@ -152,6 +152,7 @@ class TestProviderOAuth2OIDCImplicit(SeleniumTestCase):
self.container = self.setup_client()
self.driver.get("http://localhost:9009/implicit/")
sleep(2)
self.login()
self.wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "pre")))
sleep(1)
@ -264,6 +265,7 @@ class TestProviderOAuth2OIDCImplicit(SeleniumTestCase):
self.container = self.setup_client()
self.driver.get("http://localhost:9009/implicit/")
sleep(2)
self.login()
self.wait.until(
ec.presence_of_element_located((By.CSS_SELECTOR, "header > h1"))

View file

@ -32,6 +32,7 @@ from authentik.core.api.users import UserSerializer
from authentik.core.models import User
from authentik.managed.manager import ObjectManager
RETRIES = int(environ.get("RETRIES", "3"))
# pylint: disable=invalid-name
def USER() -> User: # noqa
@ -205,7 +206,7 @@ def object_manager(func: Callable):
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"""
if not exceptions: