providers/oauth2: add API for auth codes and refresh tokens

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-03-18 15:59:38 +01:00
parent 14f2522c3e
commit 9ad10863de
7 changed files with 456 additions and 145 deletions

View file

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

View 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

View 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

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

View file

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

View file

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