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, ReputationPolicyViewSet,
UserReputationViewSet, 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 ( from authentik.providers.proxy.api import (
ProxyOutpostConfigViewSet, ProxyOutpostConfigViewSet,
ProxyProviderViewSet, ProxyProviderViewSet,
@ -141,6 +146,9 @@ router.register("providers/proxy", ProxyProviderViewSet)
router.register("providers/oauth2", OAuth2ProviderViewSet) router.register("providers/oauth2", OAuth2ProviderViewSet)
router.register("providers/saml", SAMLProviderViewSet) 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/all", PropertyMappingViewSet)
router.register("propertymappings/ldap", LDAPPropertyMappingViewSet) router.register("propertymappings/ldap", LDAPPropertyMappingViewSet)
router.register("propertymappings/saml", SAMLPropertyMappingViewSet) 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.generics import get_object_or_404
from rest_framework.request import Request from rest_framework.request import Request
from rest_framework.response import Response 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 rest_framework.viewsets import ModelViewSet
from authentik.core.api.providers import ProviderSerializer from authentik.core.api.providers import ProviderSerializer
from authentik.core.api.utils import MetaNameSerializer
from authentik.core.models import Provider from authentik.core.models import Provider
from authentik.providers.oauth2.models import OAuth2Provider, ScopeMapping from authentik.providers.oauth2.models import OAuth2Provider
class OAuth2ProviderSerializer(ProviderSerializer): class OAuth2ProviderSerializer(ProviderSerializer):
@ -102,27 +101,3 @@ class OAuth2ProviderViewSet(ModelViewSet):
except Provider.application.RelatedObjectDoesNotExist: # pylint: disable=no-member except Provider.application.RelatedObjectDoesNotExist: # pylint: disable=no-member
pass pass
return Response(data) 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 @property
def serializer(self) -> Type[Serializer]: def serializer(self) -> Type[Serializer]:
from authentik.providers.oauth2.api import ScopeMappingSerializer from authentik.providers.oauth2.api.scope import ScopeMappingSerializer
return ScopeMappingSerializer return ScopeMappingSerializer
@ -287,7 +287,7 @@ class OAuth2Provider(Provider):
@property @property
def serializer(self) -> Type[Serializer]: def serializer(self) -> Type[Serializer]:
from authentik.providers.oauth2.api import OAuth2ProviderSerializer from authentik.providers.oauth2.api.provider import OAuth2ProviderSerializer
return OAuth2ProviderSerializer return OAuth2ProviderSerializer

View file

@ -2820,6 +2820,212 @@ paths:
type: string type: string
format: slug format: slug
pattern: ^[-a-zA-Z0-9_]+$ 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/: /outposts/outposts/:
get: get:
operationId: outposts_outposts_list operationId: outposts_outposts_list
@ -11123,6 +11329,149 @@ definitions:
type: string type: string
readOnly: true readOnly: true
minLength: 1 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: Outpost:
description: Outpost Serializer description: Outpost Serializer
required: required:
@ -12499,121 +12848,6 @@ definitions:
title: Verbose name plural title: Verbose name plural
type: string type: string
readOnly: true 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: OAuth2ProviderSetupURLs:
description: OAuth2 Provider Metadata serializer description: OAuth2 Provider Metadata serializer
type: object type: object