99 lines
3.2 KiB
Python
99 lines
3.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
|
|
# Copyright (C) 2014-2017 Jesús Espino <jespinog@gmail.com>
|
|
# Copyright (C) 2014-2017 David Barragán <bameda@dbarragan.com>
|
|
# Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
|
|
# 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/>.
|
|
|
|
"""
|
|
Authentication backends for rest framework.
|
|
|
|
This module exposes two backends: session and token.
|
|
|
|
The first (session) is a modified version of standard
|
|
session authentication backend of restframework with
|
|
csrf token disabled.
|
|
|
|
And the second (token) implements own version of oauth2
|
|
like authentiacation but with selfcontained tokens. Thats
|
|
makes authentication totally stateles.
|
|
|
|
It uses django signing framework for create new
|
|
selfcontained tokens. This trust tokes from external
|
|
fraudulent modifications.
|
|
"""
|
|
|
|
import re
|
|
|
|
from django.conf import settings
|
|
from django.utils import timezone
|
|
from datetime import timedelta
|
|
from taiga.base.api.authentication import BaseAuthentication
|
|
|
|
from .tokens import get_user_for_token
|
|
|
|
|
|
class Session(BaseAuthentication):
|
|
"""
|
|
Session based authentication like the standard
|
|
`taiga.base.api.authentication.SessionAuthentication`
|
|
but with csrf disabled (for obvious reasons because
|
|
it is for api.
|
|
|
|
NOTE: this is only for api web interface. Is not used
|
|
for common api usage and should be disabled on production.
|
|
"""
|
|
|
|
def authenticate(self, request):
|
|
http_request = request._request
|
|
user = getattr(http_request, 'user', None)
|
|
|
|
if not user or not user.is_active:
|
|
return None
|
|
|
|
return (user, None)
|
|
|
|
|
|
class Token(BaseAuthentication):
|
|
"""
|
|
Self-contained stateles authentication implementatrion
|
|
that work similar to oauth2.
|
|
It uses django signing framework for trust data stored
|
|
in the token.
|
|
"""
|
|
|
|
auth_rx = re.compile(r"^Bearer (.+)$")
|
|
|
|
def authenticate(self, request):
|
|
if "HTTP_AUTHORIZATION" not in request.META:
|
|
return None
|
|
|
|
token_rx_match = self.auth_rx.search(request.META["HTTP_AUTHORIZATION"])
|
|
if not token_rx_match:
|
|
return None
|
|
|
|
token = token_rx_match.group(1)
|
|
max_age_auth_token = getattr(settings, "MAX_AGE_AUTH_TOKEN", None)
|
|
user = get_user_for_token(token, "authentication",
|
|
max_age=max_age_auth_token)
|
|
|
|
if user.last_login < (timezone.now() - timedelta(minutes=1)):
|
|
user.last_login = timezone.now()
|
|
user.save(update_fields=["last_login"])
|
|
|
|
return (user, token)
|
|
|
|
def authenticate_header(self, request):
|
|
return 'Bearer realm="api"'
|