import json import logging import urllib.parse from django.views.generic import View from django.http.response import HttpResponse, HttpResponseRedirect from django.contrib.auth import logout from django.utils.http import is_safe_url from .models import SingleSignOnRecord from .settings import sso_settings logger = logging.getLogger(__name__) class SyncSsoUserEndpoint(View): def dispatch(self, request, *args, **kwargs): auth = request.META.get('HTTP_AUTHORIZATION', b'').split() if len(auth) != 2 or auth[0].lower() != 'bearer': return HttpResponse(status=401) if auth[1] != sso_settings.PU_SSO_SYNC_API_TOKEN: return HttpResponse(status=401) return super(SyncSsoUserEndpoint, self).dispatch(request, *args, **kwargs) def post(self, request, *args, **kwargs): """ Example input: { "event": "login", "user": { "external_id": "1231-123", "username": "my-username", "email": "my@email.com", "phone": "13600000000" } } """ try: data = json.loads(request.body.decode('utf-8')) user_external_id = data['user']['external_id'] username = data['user']['username'] user_email = data['user']['email'] user_phone = data['user']['phone'] except Exception: import traceback logger.error(traceback.format_exc()) return HttpResponse(status=400) # Do nothing if user not exists try: user = SingleSignOnRecord.objects.get(external_id=user_external_id).user except SingleSignOnRecord.DoesNotExist: return HttpResponse(status=200) user.username = username user.email = user_email or None user.phone = user_phone or None user.save() return HttpResponse(status=200) def clear_session(request, *args, **kwargs): logout(request) return HttpResponse(status=200) def logout_view(request, *args, **kwargs): logout(request) redirect_to = request.GET.get('redirect_to') redirect_to_url_prefix = '{}://{}'.format(request.scheme, request.get_host()) if redirect_to and is_safe_url(redirect_to, None): _parse = urllib.parse.urlparse(redirect_to) redirect_to = '{}{}'.format(redirect_to_url_prefix, _parse.path) if _parse.query: redirect_to += '?{}'.format(_parse.query) else: redirect_to = redirect_to_url_prefix sso_url_parse = urllib.parse.urlparse(sso_settings.IDP_API_ENDPOINT) sso_logout_url = '{}://{}/logout?{}'.format( sso_url_parse.scheme, sso_url_parse.netloc, urllib.parse.urlencode({'redirect_to': redirect_to})) return HttpResponseRedirect(sso_logout_url)