From ffdf6047dc7e225d7b3f8a4745a1f420a05321b9 Mon Sep 17 00:00:00 2001 From: Josue Kouka Date: Thu, 13 Apr 2017 17:13:51 +0200 Subject: [PATCH] allow fc unlinking through api (#15297) --- src/authentic2_auth_fc/__init__.py | 15 +++++++ src/authentic2_auth_fc/api_views.py | 15 +++++++ tests/conftest.py | 66 +++++++++++++++++++++++++++++ tests/test_api.py | 14 ++++++ 4 files changed, 110 insertions(+) create mode 100644 src/authentic2_auth_fc/api_views.py create mode 100644 tests/test_api.py diff --git a/src/authentic2_auth_fc/__init__.py b/src/authentic2_auth_fc/__init__.py index 6e1b3b5e5..2eb687521 100644 --- a/src/authentic2_auth_fc/__init__.py +++ b/src/authentic2_auth_fc/__init__.py @@ -1,6 +1,8 @@ from . import utils from . import app_settings +import django.apps + class Plugin(object): def get_before_urls(self): @@ -29,3 +31,16 @@ class Plugin(object): if app_settings.enable_registration_form_prefill: return [utils.get_mapped_attributes(request)] return [] + + +class AppConfig(django.apps.AppConfig): + + name = __name__ + + def ready(self): + from .api_views import fc_unlink + from authentic2.api_views import UsersAPI + UsersAPI.fc_unlink = fc_unlink + + +default_app_config = '%s.%s' % (__name__, 'AppConfig') diff --git a/src/authentic2_auth_fc/api_views.py b/src/authentic2_auth_fc/api_views.py new file mode 100644 index 000000000..f7e0e04dc --- /dev/null +++ b/src/authentic2_auth_fc/api_views.py @@ -0,0 +1,15 @@ +from django.shortcuts import get_object_or_404 +from django.contrib.auth import get_user_model + +from rest_framework.response import Response +from rest_framework import status +from rest_framework.decorators import detail_route + +from authentic2.api_views import DjangoPermission + + +@detail_route(methods=['delete'], url_path='fc-unlink', permission_classes=(DjangoPermission('custom_user.view_user'),)) +def fc_unlink(self, request, uuid): + user = get_object_or_404(get_user_model(), uuid=uuid) + user.fc_accounts.all().delete() + return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/tests/conftest.py b/tests/conftest.py index c5d8db138..aca8c8134 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,57 @@ +import json import pytest import django_webtest +from django.contrib.auth import get_user_model +from django_rbac.utils import get_ou_model +from authentic2_auth_fc.models import FcAccount + + +CARTMAN_FC_INFO = { + "token": { + "access_token": "cartmane_access_token", + "token_type": "Bearer", + "expires_in": 1200, + "id_token": "cartman_token_id" + }, + "sub": "c11661ed00014db58149c8a886c8180d", + "user_info": { + "birthcountry": "99404", + "birthdate": "2006-06-06", + "birthplace": "southpark", + "email": "ecartman@ou_southpark.org", + "family_name": "CARTMAN", + "gender": "male", + "given_name": "Eric", + "preferred_username": "CARTMAN", + "sub": "c11661ed00014db58149c8a886c8180d" + } +} + + +def create_user(**kwargs): + User = get_user_model() + password = kwargs.pop('password', None) or kwargs['username'] + federation = kwargs.pop('federation', None) + user, created = User.objects.get_or_create(**kwargs) + if password: + user.set_password(password) + user.save() + + if federation: + create_fc_federation(user, federation) + return user + + +def create_fc_federation(user, info): + kwargs = { + 'user': user, + 'token': json.dumps(info['token']), + 'user_info': json.dumps(info['user_info']), + 'sub': info['sub'] + } + return FcAccount.objects.create(**kwargs) + @pytest.fixture def app(request, db): @@ -18,3 +69,18 @@ def fc_settings(settings): return settings +@pytest.fixture +def ou_southpark(db): + OU = get_ou_model() + return OU.objects.create(name='southpark', slug='southpark') + + +@pytest.fixture +def admin(db): + return create_user(username='admin', is_superuser=True, is_staff=True) + + +@pytest.fixture +def user_cartman(db, ou_southpark): + return create_user(username='ecartman', first_name='eric', last_name='cartman', + email='ecartman@southpark.org', ou=ou_southpark, federation=CARTMAN_FC_INFO) diff --git a/tests/test_api.py b/tests/test_api.py new file mode 100644 index 000000000..355fe16c7 --- /dev/null +++ b/tests/test_api.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +from authentic2_auth_fc.models import FcAccount + + +def test_api_fc_unlink(app, admin, user_cartman): + url = '/api/users/%s/fc-unlink/' % user_cartman.uuid + # test unauthorized caller + app.delete(url, status=401) + # test unauthorized method + app.authorization = ('Basic', (admin.username, admin.username)) + app.get(url, status=405) + # test success + app.delete(url, status=204) + assert FcAccount.objects.filter(user=user_cartman).exists() is False