authentic/src/authentic2/authentication.py

75 lines
2.6 KiB
Python

# authentic2 - versatile identity manager
# Copyright (C) 2010-2019 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import inspect
try:
from django.utils.deprecation import CallableTrue
except ImportError:
CallableTrue = True
from rest_framework.authentication import BasicAuthentication
from rest_framework.exceptions import AuthenticationFailed
from authentic2_idp_oidc.models import OIDCClient
class OIDCUser:
"""Fake user class to return in case OIDC authentication"""
def __init__(self, oidc_client):
self.oidc_client = oidc_client
self.authenticated = False
def has_perm(self, *args, **kwargs):
return True
def has_perm_any(self, *args, **kwargs):
return True
def has_ou_perm(self, *args, **kwargs):
return True
def filter_by_perm(self, perms, queryset):
return queryset
@property
def is_authenticated(self):
return CallableTrue
class Authentic2Authentication(BasicAuthentication):
def authenticate_credentials(self, userid, password, request=None):
# try Simple OIDC Authentication
try:
client = OIDCClient.objects.get(client_id=userid, client_secret=password)
if not client.has_api_access:
raise AuthenticationFailed('OIDC client does not have access to the API')
if client.identifier_policy not in (client.POLICY_UUID, client.POLICY_PAIRWISE_REVERSIBLE):
raise AuthenticationFailed(
'OIDC Client identifier policy does not allow access to ' 'the API'
)
user = OIDCUser(client)
user.authenticated = True
return (user, True)
except OIDCClient.DoesNotExist:
pass
# try BasicAuthentication
if 'request' in inspect.signature(super().authenticate_credentials).parameters:
# compatibility with DRF 3.4
return super().authenticate_credentials(userid, password, request=request)
return super().authenticate_credentials(userid, password)