Skip to content

Commit 985838c

Browse files
committed
Merge pull request #247 from taigaio/refactor/auth-modules
Refactor/auth modules
2 parents dd5cff3 + c517a85 commit 985838c

File tree

11 files changed

+163
-304
lines changed

11 files changed

+163
-304
lines changed

requirements-devel.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ pytest-pythonpath==0.3
99
coverage==3.7.1
1010
coveralls==0.4.2
1111
django-slowdown==0.0.1
12+
taiga-contrib-github-auth==0.0.2

settings/testing.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424
MEDIA_ROOT = "/tmp"
2525

2626
EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
27-
INSTALLED_APPS = INSTALLED_APPS + ["tests"]
27+
INSTALLED_APPS = INSTALLED_APPS + [
28+
"tests",
29+
"taiga_contrib_github_auth",
30+
]
2831

2932
REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"] = {
3033
"anon": None,

taiga/auth/api.py

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
from taiga.base.api import viewsets
2828
from taiga.base.decorators import list_route
2929
from taiga.base import exceptions as exc
30-
from taiga.base.connectors import github
3130
from taiga.users.services import get_and_validate_user
3231

3332
from .serializers import PublicRegisterSerializer
@@ -37,8 +36,8 @@
3736
from .services import private_register_for_existing_user
3837
from .services import private_register_for_new_user
3938
from .services import public_register
40-
from .services import github_register
4139
from .services import make_auth_response_data
40+
from .services import get_auth_plugins
4241

4342
from .permissions import AuthPermission
4443

@@ -135,36 +134,15 @@ def register(self, request, **kwargs):
135134
return self._private_register(request)
136135
raise exc.BadRequest(_("invalid register type"))
137136

138-
def _login(self, request):
139-
username = request.DATA.get('username', None)
140-
password = request.DATA.get('password', None)
141-
142-
user = get_and_validate_user(username=username, password=password)
143-
data = make_auth_response_data(user)
144-
return Response(data, status=status.HTTP_200_OK)
145-
146-
def _github_login(self, request):
147-
code = request.DATA.get('code', None)
148-
token = request.DATA.get('token', None)
149-
150-
email, user_info = github.me(code)
151-
152-
user = github_register(username=user_info.username,
153-
email=email,
154-
full_name=user_info.full_name,
155-
github_id=user_info.id,
156-
bio=user_info.bio,
157-
token=token)
158-
data = make_auth_response_data(user)
159-
return Response(data, status=status.HTTP_200_OK)
160137

161138
# Login view: /api/v1/auth
162139
def create(self, request, **kwargs):
163140
self.check_permissions(request, 'create', None)
141+
auth_plugins = get_auth_plugins()
142+
143+
login_type = request.DATA.get("type", None)
144+
145+
if login_type in auth_plugins:
146+
return auth_plugins[login_type]['login_func'](request)
164147

165-
type = request.DATA.get("type", None)
166-
if type == "normal":
167-
return self._login(request)
168-
elif type == "github":
169-
return self._github_login(request)
170148
raise exc.BadRequest(_("invalid login type"))

taiga/auth/services.py

Lines changed: 28 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
from django.db import IntegrityError
3030
from django.utils.translation import ugettext as _
3131

32+
from rest_framework.response import Response
33+
from rest_framework import status
34+
3235
from djmail.template_mail import MagicMailBuilder, InlineCSSTemplateMail
3336

3437
from taiga.base import exceptions as exc
@@ -39,6 +42,19 @@
3942
from .tokens import get_token_for_user
4043
from .signals import user_registered as user_registered_signal
4144

45+
auth_plugins = {}
46+
47+
48+
def register_auth_plugin(name, login_func):
49+
auth_plugins[name] = {
50+
"login_func": login_func,
51+
}
52+
53+
54+
def get_auth_plugins():
55+
return auth_plugins
56+
57+
4258
def send_register_email(user) -> bool:
4359
"""
4460
Given a user, send register welcome email
@@ -169,47 +185,6 @@ def private_register_for_new_user(token:str, username:str, email:str,
169185
return user
170186

171187

172-
@tx.atomic
173-
def github_register(username:str, email:str, full_name:str, github_id:int, bio:str, token:str=None):
174-
"""
175-
Register a new user from github.
176-
177-
This can raise `exc.IntegrityError` exceptions in
178-
case of conflics found.
179-
180-
:returns: User
181-
"""
182-
user_model = apps.get_model("users", "User")
183-
184-
try:
185-
# Github user association exist?
186-
user = user_model.objects.get(github_id=github_id)
187-
except user_model.DoesNotExist:
188-
try:
189-
# Is a user with the same email as the github user?
190-
user = user_model.objects.get(email=email)
191-
user.github_id = github_id
192-
user.save(update_fields=["github_id"])
193-
except user_model.DoesNotExist:
194-
# Create a new user
195-
username_unique = slugify_uniquely(username, user_model, slugfield="username")
196-
user = user_model.objects.create(email=email,
197-
username=username_unique,
198-
github_id=github_id,
199-
full_name=full_name,
200-
bio=bio)
201-
202-
send_register_email(user)
203-
user_registered_signal.send(sender=user.__class__, user=user)
204-
205-
if token:
206-
membership = get_membership_by_token(token)
207-
membership.user = user
208-
membership.save(update_fields=["user"])
209-
210-
return user
211-
212-
213188
def make_auth_response_data(user) -> dict:
214189
"""
215190
Given a domain and user, creates data structure
@@ -220,3 +195,15 @@ def make_auth_response_data(user) -> dict:
220195
data = dict(serializer.data)
221196
data["auth_token"] = get_token_for_user(user, "authentication")
222197
return data
198+
199+
200+
def normal_login_func(request):
201+
username = request.DATA.get('username', None)
202+
password = request.DATA.get('password', None)
203+
204+
user = get_and_validate_user(username=username, password=password)
205+
data = make_auth_response_data(user)
206+
return Response(data, status=status.HTTP_200_OK)
207+
208+
209+
register_auth_plugin("normal", normal_login_func);

taiga/base/connectors/exceptions.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,3 @@
2121
class ConnectorBaseException(BaseException):
2222
status_code = 400
2323
default_detail = _("Connection error.")
24-
25-
26-
class GitHubApiError(ConnectorBaseException):
27-
pass

taiga/base/connectors/github.py

Lines changed: 0 additions & 166 deletions
This file was deleted.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django.db import models, migrations
5+
from django.conf import settings
6+
import django_pgjson.fields
7+
8+
9+
def migrate_github_id(apps, schema_editor):
10+
AuthData = apps.get_model("users", "AuthData")
11+
User = apps.get_model("users", "User")
12+
for user in User.objects.all():
13+
if user.github_id:
14+
AuthData.objects.create(user=user, key="github", value=user.github_id, extra={})
15+
16+
17+
class Migration(migrations.Migration):
18+
19+
dependencies = [
20+
('users', '0006_auto_20141030_1132'),
21+
]
22+
23+
operations = [
24+
migrations.CreateModel(
25+
name='AuthData',
26+
fields=[
27+
('id', models.AutoField(primary_key=True, verbose_name='ID', serialize=False, auto_created=True)),
28+
('key', models.SlugField()),
29+
('value', models.CharField(max_length=300)),
30+
('extra', django_pgjson.fields.JsonField()),
31+
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
32+
],
33+
options={
34+
},
35+
bases=(models.Model,),
36+
),
37+
migrations.AlterUniqueTogether(
38+
name='authdata',
39+
unique_together=set([('key', 'value')]),
40+
),
41+
migrations.RunPython(migrate_github_id),
42+
migrations.RemoveField(
43+
model_name='user',
44+
name='github_id',
45+
),
46+
]

0 commit comments

Comments
 (0)