providers/oauth2: add API for auth codes and refresh tokens
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
14f2522c3e
commit
9ad10863de
|
@ -46,7 +46,12 @@ from authentik.policies.reputation.api import (
|
|||
ReputationPolicyViewSet,
|
||||
UserReputationViewSet,
|
||||
)
|
||||
from authentik.providers.oauth2.api import OAuth2ProviderViewSet, ScopeMappingViewSet
|
||||
from authentik.providers.oauth2.api.provider import OAuth2ProviderViewSet
|
||||
from authentik.providers.oauth2.api.scope import ScopeMappingViewSet
|
||||
from authentik.providers.oauth2.api.tokens import (
|
||||
AuthorizationCodeViewSet,
|
||||
RefreshTokenViewSet,
|
||||
)
|
||||
from authentik.providers.proxy.api import (
|
||||
ProxyOutpostConfigViewSet,
|
||||
ProxyProviderViewSet,
|
||||
|
@ -141,6 +146,9 @@ router.register("providers/proxy", ProxyProviderViewSet)
|
|||
router.register("providers/oauth2", OAuth2ProviderViewSet)
|
||||
router.register("providers/saml", SAMLProviderViewSet)
|
||||
|
||||
router.register("oauth2/authorization_codes", AuthorizationCodeViewSet)
|
||||
router.register("oauth2/refresh_tokens", RefreshTokenViewSet)
|
||||
|
||||
router.register("propertymappings/all", PropertyMappingViewSet)
|
||||
router.register("propertymappings/ldap", LDAPPropertyMappingViewSet)
|
||||
router.register("propertymappings/saml", SAMLPropertyMappingViewSet)
|
||||
|
|
0
authentik/providers/oauth2/api/__init__.py
Normal file
0
authentik/providers/oauth2/api/__init__.py
Normal file
|
@ -6,13 +6,12 @@ from rest_framework.fields import ReadOnlyField
|
|||
from rest_framework.generics import get_object_or_404
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.serializers import ModelSerializer, Serializer
|
||||
from rest_framework.serializers import Serializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from authentik.core.api.providers import ProviderSerializer
|
||||
from authentik.core.api.utils import MetaNameSerializer
|
||||
from authentik.core.models import Provider
|
||||
from authentik.providers.oauth2.models import OAuth2Provider, ScopeMapping
|
||||
from authentik.providers.oauth2.models import OAuth2Provider
|
||||
|
||||
|
||||
class OAuth2ProviderSerializer(ProviderSerializer):
|
||||
|
@ -102,27 +101,3 @@ class OAuth2ProviderViewSet(ModelViewSet):
|
|||
except Provider.application.RelatedObjectDoesNotExist: # pylint: disable=no-member
|
||||
pass
|
||||
return Response(data)
|
||||
|
||||
|
||||
class ScopeMappingSerializer(ModelSerializer, MetaNameSerializer):
|
||||
"""ScopeMapping Serializer"""
|
||||
|
||||
class Meta:
|
||||
|
||||
model = ScopeMapping
|
||||
fields = [
|
||||
"pk",
|
||||
"name",
|
||||
"scope_name",
|
||||
"description",
|
||||
"expression",
|
||||
"verbose_name",
|
||||
"verbose_name_plural",
|
||||
]
|
||||
|
||||
|
||||
class ScopeMappingViewSet(ModelViewSet):
|
||||
"""ScopeMapping Viewset"""
|
||||
|
||||
queryset = ScopeMapping.objects.all()
|
||||
serializer_class = ScopeMappingSerializer
|
30
authentik/providers/oauth2/api/scope.py
Normal file
30
authentik/providers/oauth2/api/scope.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
"""OAuth2Provider API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from authentik.core.api.utils import MetaNameSerializer
|
||||
from authentik.providers.oauth2.models import ScopeMapping
|
||||
|
||||
|
||||
class ScopeMappingSerializer(ModelSerializer, MetaNameSerializer):
|
||||
"""ScopeMapping Serializer"""
|
||||
|
||||
class Meta:
|
||||
|
||||
model = ScopeMapping
|
||||
fields = [
|
||||
"pk",
|
||||
"name",
|
||||
"scope_name",
|
||||
"description",
|
||||
"expression",
|
||||
"verbose_name",
|
||||
"verbose_name_plural",
|
||||
]
|
||||
|
||||
|
||||
class ScopeMappingViewSet(ModelViewSet):
|
||||
"""ScopeMapping Viewset"""
|
||||
|
||||
queryset = ScopeMapping.objects.all()
|
||||
serializer_class = ScopeMappingSerializer
|
64
authentik/providers/oauth2/api/tokens.py
Normal file
64
authentik/providers/oauth2/api/tokens.py
Normal file
|
@ -0,0 +1,64 @@
|
|||
"""OAuth2Provider API Views"""
|
||||
from rest_framework import mixins
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import GenericViewSet
|
||||
|
||||
from authentik.core.api.users import UserSerializer
|
||||
from authentik.core.api.utils import MetaNameSerializer
|
||||
from authentik.providers.oauth2.api.provider import OAuth2ProviderSerializer
|
||||
from authentik.providers.oauth2.models import AuthorizationCode, RefreshToken
|
||||
|
||||
|
||||
class ExpiringBaseGrantModelSerializer(ModelSerializer, MetaNameSerializer):
|
||||
"""Serializer for BaseGrantModel and ExpiringBaseGrant"""
|
||||
|
||||
user = UserSerializer()
|
||||
provider = OAuth2ProviderSerializer()
|
||||
|
||||
class Meta:
|
||||
|
||||
model = AuthorizationCode
|
||||
fields = ["pk", "provider", "user", "is_expired", "expires", "scope"]
|
||||
depth = 2
|
||||
|
||||
|
||||
class AuthorizationCodeViewSet(
|
||||
mixins.RetrieveModelMixin,
|
||||
mixins.DestroyModelMixin,
|
||||
mixins.ListModelMixin,
|
||||
GenericViewSet,
|
||||
):
|
||||
"""AuthorizationCode Viewset"""
|
||||
|
||||
queryset = AuthorizationCode.objects.all()
|
||||
serializer_class = ExpiringBaseGrantModelSerializer
|
||||
filterset_fields = ["user", "provider"]
|
||||
ordering = ["provider", "expires"]
|
||||
|
||||
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)
|
||||
|
||||
|
||||
class RefreshTokenViewSet(
|
||||
mixins.RetrieveModelMixin,
|
||||
mixins.DestroyModelMixin,
|
||||
mixins.ListModelMixin,
|
||||
GenericViewSet,
|
||||
):
|
||||
"""RefreshToken Viewset"""
|
||||
|
||||
queryset = RefreshToken.objects.all()
|
||||
serializer_class = ExpiringBaseGrantModelSerializer
|
||||
filterset_fields = ["user", "provider"]
|
||||
ordering = ["provider", "expires"]
|
||||
|
||||
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)
|
|
@ -119,7 +119,7 @@ class ScopeMapping(PropertyMapping):
|
|||
|
||||
@property
|
||||
def serializer(self) -> Type[Serializer]:
|
||||
from authentik.providers.oauth2.api import ScopeMappingSerializer
|
||||
from authentik.providers.oauth2.api.scope import ScopeMappingSerializer
|
||||
|
||||
return ScopeMappingSerializer
|
||||
|
||||
|
@ -287,7 +287,7 @@ class OAuth2Provider(Provider):
|
|||
|
||||
@property
|
||||
def serializer(self) -> Type[Serializer]:
|
||||
from authentik.providers.oauth2.api import OAuth2ProviderSerializer
|
||||
from authentik.providers.oauth2.api.provider import OAuth2ProviderSerializer
|
||||
|
||||
return OAuth2ProviderSerializer
|
||||
|
||||
|
|
464
swagger.yaml
464
swagger.yaml
|
@ -2820,6 +2820,212 @@ paths:
|
|||
type: string
|
||||
format: slug
|
||||
pattern: ^[-a-zA-Z0-9_]+$
|
||||
/oauth2/authorization_codes/:
|
||||
get:
|
||||
operationId: oauth2_authorization_codes_list
|
||||
description: AuthorizationCode Viewset
|
||||
parameters:
|
||||
- name: user
|
||||
in: query
|
||||
description: ''
|
||||
required: false
|
||||
type: string
|
||||
- name: provider
|
||||
in: query
|
||||
description: ''
|
||||
required: false
|
||||
type: string
|
||||
- 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/ExpiringBaseGrantModel'
|
||||
tags:
|
||||
- oauth2
|
||||
parameters: []
|
||||
/oauth2/authorization_codes/{id}/:
|
||||
get:
|
||||
operationId: oauth2_authorization_codes_read
|
||||
description: AuthorizationCode Viewset
|
||||
parameters: []
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
schema:
|
||||
$ref: '#/definitions/ExpiringBaseGrantModel'
|
||||
tags:
|
||||
- oauth2
|
||||
delete:
|
||||
operationId: oauth2_authorization_codes_delete
|
||||
description: AuthorizationCode Viewset
|
||||
parameters: []
|
||||
responses:
|
||||
'204':
|
||||
description: ''
|
||||
tags:
|
||||
- oauth2
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: A unique integer value identifying this Authorization Code.
|
||||
required: true
|
||||
type: integer
|
||||
/oauth2/refresh_tokens/:
|
||||
get:
|
||||
operationId: oauth2_refresh_tokens_list
|
||||
description: RefreshToken Viewset
|
||||
parameters:
|
||||
- name: user
|
||||
in: query
|
||||
description: ''
|
||||
required: false
|
||||
type: string
|
||||
- name: provider
|
||||
in: query
|
||||
description: ''
|
||||
required: false
|
||||
type: string
|
||||
- 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/ExpiringBaseGrantModel'
|
||||
tags:
|
||||
- oauth2
|
||||
parameters: []
|
||||
/oauth2/refresh_tokens/{id}/:
|
||||
get:
|
||||
operationId: oauth2_refresh_tokens_read
|
||||
description: RefreshToken Viewset
|
||||
parameters: []
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
schema:
|
||||
$ref: '#/definitions/ExpiringBaseGrantModel'
|
||||
tags:
|
||||
- oauth2
|
||||
delete:
|
||||
operationId: oauth2_refresh_tokens_delete
|
||||
description: RefreshToken Viewset
|
||||
parameters: []
|
||||
responses:
|
||||
'204':
|
||||
description: ''
|
||||
tags:
|
||||
- oauth2
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: A unique integer value identifying this OAuth2 Token.
|
||||
required: true
|
||||
type: integer
|
||||
/outposts/outposts/:
|
||||
get:
|
||||
operationId: outposts_outposts_list
|
||||
|
@ -11123,6 +11329,149 @@ definitions:
|
|||
type: string
|
||||
readOnly: true
|
||||
minLength: 1
|
||||
OAuth2Provider:
|
||||
title: Provider
|
||||
description: OAuth2Provider Serializer
|
||||
required:
|
||||
- name
|
||||
- application
|
||||
- authorization_flow
|
||||
type: object
|
||||
properties:
|
||||
pk:
|
||||
title: ID
|
||||
type: integer
|
||||
readOnly: true
|
||||
name:
|
||||
title: Name
|
||||
type: string
|
||||
minLength: 1
|
||||
application:
|
||||
title: Application
|
||||
type: string
|
||||
authorization_flow:
|
||||
title: Authorization flow
|
||||
description: Flow used when authorizing this provider.
|
||||
type: string
|
||||
format: uuid
|
||||
property_mappings:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
uniqueItems: true
|
||||
object_type:
|
||||
title: Object type
|
||||
type: string
|
||||
readOnly: true
|
||||
assigned_application_slug:
|
||||
title: Assigned application slug
|
||||
type: string
|
||||
readOnly: true
|
||||
assigned_application_name:
|
||||
title: Assigned application name
|
||||
type: string
|
||||
readOnly: true
|
||||
verbose_name:
|
||||
title: Verbose name
|
||||
type: string
|
||||
readOnly: true
|
||||
verbose_name_plural:
|
||||
title: Verbose name plural
|
||||
type: string
|
||||
readOnly: true
|
||||
client_type:
|
||||
title: Client Type
|
||||
description: |-
|
||||
Confidential clients are capable of maintaining the confidentiality
|
||||
of their credentials. Public clients are incapable.
|
||||
type: string
|
||||
enum:
|
||||
- confidential
|
||||
- public
|
||||
client_id:
|
||||
title: Client ID
|
||||
type: string
|
||||
maxLength: 255
|
||||
minLength: 1
|
||||
client_secret:
|
||||
title: Client Secret
|
||||
type: string
|
||||
maxLength: 255
|
||||
token_validity:
|
||||
title: Token validity
|
||||
description: 'Tokens not valid on or after current time + this value (Format:
|
||||
hours=1;minutes=2;seconds=3).'
|
||||
type: string
|
||||
minLength: 1
|
||||
include_claims_in_id_token:
|
||||
title: Include claims in id_token
|
||||
description: Include User claims from scopes in the id_token, for applications
|
||||
that don't access the userinfo endpoint.
|
||||
type: boolean
|
||||
jwt_alg:
|
||||
title: JWT Algorithm
|
||||
description: Algorithm used to sign the JWT Token
|
||||
type: string
|
||||
enum:
|
||||
- HS256
|
||||
- RS256
|
||||
rsa_key:
|
||||
title: RSA Key
|
||||
description: Key used to sign the tokens. Only required when JWT Algorithm
|
||||
is set to RS256.
|
||||
type: string
|
||||
format: uuid
|
||||
x-nullable: true
|
||||
redirect_uris:
|
||||
title: Redirect URIs
|
||||
description: Enter each URI on a new line.
|
||||
type: string
|
||||
minLength: 1
|
||||
sub_mode:
|
||||
title: Sub mode
|
||||
description: Configure what data should be used as unique User Identifier.
|
||||
For most cases, the default should be fine.
|
||||
type: string
|
||||
enum:
|
||||
- hashed_user_id
|
||||
- user_username
|
||||
- user_email
|
||||
- user_upn
|
||||
issuer_mode:
|
||||
title: Issuer mode
|
||||
description: Configure how the issuer field of the ID Token should be filled.
|
||||
type: string
|
||||
enum:
|
||||
- global
|
||||
- per_provider
|
||||
ExpiringBaseGrantModel:
|
||||
description: Serializer for BaseGrantModel and ExpiringBaseGrant
|
||||
required:
|
||||
- provider
|
||||
- user
|
||||
type: object
|
||||
properties:
|
||||
pk:
|
||||
title: ID
|
||||
type: integer
|
||||
readOnly: true
|
||||
provider:
|
||||
$ref: '#/definitions/OAuth2Provider'
|
||||
user:
|
||||
$ref: '#/definitions/User'
|
||||
is_expired:
|
||||
title: Is expired
|
||||
type: string
|
||||
readOnly: true
|
||||
expires:
|
||||
title: Expires
|
||||
type: string
|
||||
format: date-time
|
||||
scope:
|
||||
title: Scope
|
||||
type: string
|
||||
readOnly: true
|
||||
Outpost:
|
||||
description: Outpost Serializer
|
||||
required:
|
||||
|
@ -12499,121 +12848,6 @@ definitions:
|
|||
title: Verbose name plural
|
||||
type: string
|
||||
readOnly: true
|
||||
OAuth2Provider:
|
||||
description: OAuth2Provider Serializer
|
||||
required:
|
||||
- name
|
||||
- application
|
||||
- authorization_flow
|
||||
type: object
|
||||
properties:
|
||||
pk:
|
||||
title: ID
|
||||
type: integer
|
||||
readOnly: true
|
||||
name:
|
||||
title: Name
|
||||
type: string
|
||||
minLength: 1
|
||||
application:
|
||||
title: Application
|
||||
type: string
|
||||
authorization_flow:
|
||||
title: Authorization flow
|
||||
description: Flow used when authorizing this provider.
|
||||
type: string
|
||||
format: uuid
|
||||
property_mappings:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
uniqueItems: true
|
||||
object_type:
|
||||
title: Object type
|
||||
type: string
|
||||
readOnly: true
|
||||
assigned_application_slug:
|
||||
title: Assigned application slug
|
||||
type: string
|
||||
readOnly: true
|
||||
assigned_application_name:
|
||||
title: Assigned application name
|
||||
type: string
|
||||
readOnly: true
|
||||
verbose_name:
|
||||
title: Verbose name
|
||||
type: string
|
||||
readOnly: true
|
||||
verbose_name_plural:
|
||||
title: Verbose name plural
|
||||
type: string
|
||||
readOnly: true
|
||||
client_type:
|
||||
title: Client Type
|
||||
description: |-
|
||||
Confidential clients are capable of maintaining the confidentiality
|
||||
of their credentials. Public clients are incapable.
|
||||
type: string
|
||||
enum:
|
||||
- confidential
|
||||
- public
|
||||
client_id:
|
||||
title: Client ID
|
||||
type: string
|
||||
maxLength: 255
|
||||
minLength: 1
|
||||
client_secret:
|
||||
title: Client Secret
|
||||
type: string
|
||||
maxLength: 255
|
||||
token_validity:
|
||||
title: Token validity
|
||||
description: 'Tokens not valid on or after current time + this value (Format:
|
||||
hours=1;minutes=2;seconds=3).'
|
||||
type: string
|
||||
minLength: 1
|
||||
include_claims_in_id_token:
|
||||
title: Include claims in id_token
|
||||
description: Include User claims from scopes in the id_token, for applications
|
||||
that don't access the userinfo endpoint.
|
||||
type: boolean
|
||||
jwt_alg:
|
||||
title: JWT Algorithm
|
||||
description: Algorithm used to sign the JWT Token
|
||||
type: string
|
||||
enum:
|
||||
- HS256
|
||||
- RS256
|
||||
rsa_key:
|
||||
title: RSA Key
|
||||
description: Key used to sign the tokens. Only required when JWT Algorithm
|
||||
is set to RS256.
|
||||
type: string
|
||||
format: uuid
|
||||
x-nullable: true
|
||||
redirect_uris:
|
||||
title: Redirect URIs
|
||||
description: Enter each URI on a new line.
|
||||
type: string
|
||||
minLength: 1
|
||||
sub_mode:
|
||||
title: Sub mode
|
||||
description: Configure what data should be used as unique User Identifier.
|
||||
For most cases, the default should be fine.
|
||||
type: string
|
||||
enum:
|
||||
- hashed_user_id
|
||||
- user_username
|
||||
- user_email
|
||||
- user_upn
|
||||
issuer_mode:
|
||||
title: Issuer mode
|
||||
description: Configure how the issuer field of the ID Token should be filled.
|
||||
type: string
|
||||
enum:
|
||||
- global
|
||||
- per_provider
|
||||
OAuth2ProviderSetupURLs:
|
||||
description: OAuth2 Provider Metadata serializer
|
||||
type: object
|
||||
|
|
Reference in a new issue