mirror of
https://github.com/ansible/awx.git
synced 2026-05-17 22:37:41 -02:30
Implement session-based and OAuth 2 authentications
Relates #21. Please see acceptance docs for feature details. Signed-off-by: Aaron Tan <jangsutsr@gmail.com>
This commit is contained in:
@@ -8,18 +8,14 @@ import urllib
|
||||
import six
|
||||
|
||||
# Django
|
||||
from django.contrib.auth import login, logout
|
||||
from django.utils.functional import LazyObject
|
||||
from django.shortcuts import redirect
|
||||
from django.utils.timezone import now
|
||||
|
||||
# Python Social Auth
|
||||
from social_core.exceptions import SocialAuthBaseException
|
||||
from social_core.utils import social_logger
|
||||
from social_django.middleware import SocialAuthExceptionMiddleware
|
||||
|
||||
# Ansible Tower
|
||||
from awx.main.models import AuthToken
|
||||
|
||||
|
||||
class SocialAuthMiddleware(SocialAuthExceptionMiddleware):
|
||||
|
||||
@@ -35,33 +31,14 @@ class SocialAuthMiddleware(SocialAuthExceptionMiddleware):
|
||||
request.successful_authenticator = None
|
||||
|
||||
if not request.path.startswith('/sso/') and 'migrations_notran' not in request.path:
|
||||
|
||||
# If token isn't present but we still have a user logged in via Django
|
||||
# sessions, log them out.
|
||||
if not token_key and request.user and request.user.is_authenticated():
|
||||
logout(request)
|
||||
|
||||
# If a token is present, make sure it matches a valid one in the
|
||||
# database, and log the user via Django session if necessary.
|
||||
# Otherwise, log the user out via Django sessions.
|
||||
elif token_key:
|
||||
|
||||
try:
|
||||
auth_token = AuthToken.objects.filter(key=token_key, expires__gt=now())[0]
|
||||
except IndexError:
|
||||
auth_token = None
|
||||
|
||||
if not auth_token and request.user and request.user.is_authenticated():
|
||||
logout(request)
|
||||
elif auth_token and request.user.is_anonymous is False and request.user != auth_token.user:
|
||||
logout(request)
|
||||
auth_token.user.backend = ''
|
||||
login(request, auth_token.user)
|
||||
auth_token.refresh()
|
||||
|
||||
if auth_token and request.user and request.user.is_authenticated():
|
||||
request.session.pop('social_auth_error', None)
|
||||
request.session.pop('social_auth_last_backend', None)
|
||||
if request.user and request.user.is_authenticated():
|
||||
# The rest of the code base rely hevily on type/inheritance checks,
|
||||
# LazyObject sent from Django auth middleware can be buggy if not
|
||||
# converted back to its original object.
|
||||
if isinstance(request.user, LazyObject) and request.user._wrapped:
|
||||
request.user = request.user._wrapped
|
||||
request.session.pop('social_auth_error', None)
|
||||
request.session.pop('social_auth_last_backend', None)
|
||||
|
||||
def process_exception(self, request, exception):
|
||||
strategy = getattr(request, 'social_strategy', None)
|
||||
|
||||
@@ -8,16 +8,15 @@ import logging
|
||||
# Django
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import HttpResponse
|
||||
from django.utils.timezone import now, utc
|
||||
from django.views.generic import View
|
||||
from django.views.generic.base import RedirectView
|
||||
from django.utils.encoding import smart_text
|
||||
from django.contrib import auth
|
||||
|
||||
# Django REST Framework
|
||||
from rest_framework.renderers import JSONRenderer
|
||||
|
||||
# AWX
|
||||
from awx.main.models import AuthToken
|
||||
from awx.api.serializers import UserSerializer
|
||||
|
||||
logger = logging.getLogger('awx.sso.views')
|
||||
@@ -46,25 +45,9 @@ class CompleteView(BaseRedirectView):
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
response = super(CompleteView, self).dispatch(request, *args, **kwargs)
|
||||
if self.request.user and self.request.user.is_authenticated():
|
||||
request_hash = AuthToken.get_request_hash(self.request)
|
||||
try:
|
||||
token = AuthToken.objects.filter(user=request.user,
|
||||
request_hash=request_hash,
|
||||
reason='',
|
||||
expires__gt=now())[0]
|
||||
token.refresh()
|
||||
logger.info(smart_text(u"User {} logged in".format(self.request.user.username)))
|
||||
except IndexError:
|
||||
token = AuthToken.objects.create(user=request.user,
|
||||
request_hash=request_hash)
|
||||
logger.info(smart_text(u"User {} logged in".format(self.request.user.username)))
|
||||
request.session['auth_token_key'] = token.key
|
||||
token_key = urllib.quote('"%s"' % token.key)
|
||||
response.set_cookie('token', token_key)
|
||||
token_expires = token.expires.astimezone(utc).strftime('%Y-%m-%dT%H:%M:%S')
|
||||
token_expires = '%s.%03dZ' % (token_expires, token.expires.microsecond / 1000)
|
||||
token_expires = urllib.quote('"%s"' % token_expires)
|
||||
response.set_cookie('token_expires', token_expires)
|
||||
auth.login(self.request, self.request.user)
|
||||
logger.info(smart_text(u"User {} logged in".format(self.request.user.username)))
|
||||
# TODO: remove these 2 cookie-sets after UI removes them
|
||||
response.set_cookie('userLoggedIn', 'true')
|
||||
current_user = UserSerializer(self.request.user)
|
||||
current_user = JSONRenderer().render(current_user.data)
|
||||
|
||||
Reference in New Issue
Block a user