-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #48 from groovecoder/get-email-from-github-21
fix #21 - Get email from github
- Loading branch information
Showing
7 changed files
with
208 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
from django.forms import ValidationError | ||
|
||
from allauth.account.adapter import DefaultAccountAdapter | ||
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter | ||
|
||
|
||
REMOVE_MESSAGE = 'You must keep at least one connected account.' | ||
|
||
|
||
class CodesyAccountAdapter(DefaultAccountAdapter): | ||
|
||
def is_open_for_signup(self, request): | ||
""" | ||
Disable regular signup to require social signup. | ||
See https://github.com/pennersr/django-allauth/issues/345 | ||
""" | ||
return False | ||
|
||
|
||
class CodesySocialAccountAdapter(DefaultSocialAccountAdapter): | ||
|
||
def is_open_for_signup(self, request, sociallogin): | ||
""" | ||
Enable social signup. | ||
""" | ||
return True | ||
|
||
def validate_disconnect(self, account, accounts): | ||
""" | ||
Don't let users disconnect their last social account. | ||
""" | ||
if len(accounts) == 1: | ||
raise ValidationError(REMOVE_MESSAGE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,32 @@ | ||
import requests | ||
|
||
from django.contrib.auth.models import AbstractUser | ||
from django.db import models | ||
from django.dispatch import receiver | ||
|
||
from allauth.account.signals import user_signed_up | ||
|
||
|
||
EMAIL_URL = 'https://api.github.com/user/emails' | ||
|
||
|
||
class User(AbstractUser): | ||
balanced_card_href = models.CharField(max_length=100, blank=True) | ||
balanced_bank_account_href = models.CharField(max_length=100, blank=True) | ||
|
||
USERNAME_FIELD = 'username' | ||
|
||
|
||
@receiver(user_signed_up) | ||
def add_email_from_signup(sender, request, user, **kwargs): | ||
params = {'access_token': kwargs['sociallogin'].token} | ||
email_data = requests.get(EMAIL_URL, params=params).json() | ||
if email_data: | ||
verified_emails = [e for e in email_data if e['verified']] | ||
if not verified_emails: | ||
return None | ||
sorted_emails = sorted(verified_emails, | ||
key=lambda e: (e['primary'], e['verified']), | ||
reverse=True) | ||
user.email = sorted_emails[0]['email'] | ||
user.save(update_fields=['email']) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import fudge | ||
|
||
from django.forms import ValidationError | ||
|
||
from django.test import TestCase | ||
from django.test.client import RequestFactory | ||
|
||
from codesy.adapters import CodesyAccountAdapter, CodesySocialAccountAdapter | ||
|
||
|
||
class AdaptersTest(TestCase): | ||
""" | ||
Verify our adapters are wired correctly. | ||
""" | ||
def setUp(self): | ||
self.csaa = CodesySocialAccountAdapter() | ||
self.request = RequestFactory() | ||
self.sociallogin = fudge.Fake() | ||
|
||
def test_account_adapter_disabled(self): | ||
caa = CodesyAccountAdapter() | ||
self.assertEquals(False, caa.is_open_for_signup(self.request)) | ||
|
||
def test_social_adapter_enabled(self): | ||
self.assertEquals(True, self.csaa.is_open_for_signup(self.request, | ||
self.sociallogin)) | ||
|
||
def test_social_adapter_prohibits_disconnecting_last_account(self): | ||
account = fudge.Fake() | ||
account2 = fudge.Fake() | ||
single_account_list = [account, ] | ||
multi_account_list = [account, account2] | ||
self.csaa.validate_disconnect(account, multi_account_list) | ||
|
||
with self.assertRaises(ValidationError): | ||
self.csaa.validate_disconnect(account, single_account_list) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
from django.test import TestCase | ||
from django.test.client import RequestFactory | ||
|
||
import fudge | ||
|
||
from ..base.models import EMAIL_URL, User, add_email_from_signup | ||
|
||
|
||
VERIFIED_PRIMARY_EMAIL = "verified+primary@test.com" | ||
VERIFIED_EMAIL = "verified@test.com" | ||
UNVERIFIED_EMAIL = "unverified@test.com" | ||
|
||
GITHUB_DATA_WITH_VERIFIED_PRIMARY_EMAIL = [ | ||
{u'verified': True, | ||
u'email': u'%s' % VERIFIED_PRIMARY_EMAIL, | ||
u'primary': True} | ||
] | ||
GITHUB_DATA_WITH_VERIFIED_EMAIL = [ | ||
{u'verified': True, | ||
u'email': u'%s' % VERIFIED_EMAIL, | ||
u'primary': False} | ||
] | ||
GITHUB_DATA_WITH_UNVERIFIED_EMAIL = [ | ||
{u'verified': False, | ||
u'email': u'%s' % UNVERIFIED_EMAIL, | ||
u'primary': False} | ||
] | ||
GITHUB_DATA_WITH_MANY_EMAILS = (GITHUB_DATA_WITH_UNVERIFIED_EMAIL + | ||
GITHUB_DATA_WITH_VERIFIED_PRIMARY_EMAIL + | ||
GITHUB_DATA_WITH_VERIFIED_EMAIL) | ||
|
||
|
||
class SignUpReceiverTest(TestCase): | ||
def setUp(self): | ||
self.sociallogin = fudge.Fake().has_attr(token='12345') | ||
self.params = {'access_token': self.sociallogin.token} | ||
self.sender = User | ||
self.request = RequestFactory() | ||
self.user = (fudge.Fake('User') | ||
.has_attr(email=None) | ||
.expects('save')) | ||
self.kwargs = {'sociallogin': self.sociallogin} | ||
self.fake_get = fudge.Fake('requests.get') | ||
|
||
@fudge.patch('requests.get') | ||
def test_verified_primary_email_from_github_api(self, fake_get): | ||
(fake_get.expects_call() | ||
.with_args(EMAIL_URL, params=self.params) | ||
.returns_fake() | ||
.expects('json') | ||
.returns( | ||
GITHUB_DATA_WITH_VERIFIED_PRIMARY_EMAIL)) | ||
|
||
add_email_from_signup(self.sender, | ||
self.request, | ||
self.user, | ||
**self.kwargs) | ||
self.assertEquals(VERIFIED_PRIMARY_EMAIL, self.user.email) | ||
|
||
@fudge.patch('requests.get') | ||
def test_verified_email_from_github_api(self, fake_get): | ||
(fake_get.expects_call() | ||
.with_args(EMAIL_URL, params=self.params) | ||
.returns_fake() | ||
.expects('json') | ||
.returns( | ||
GITHUB_DATA_WITH_VERIFIED_EMAIL)) | ||
|
||
add_email_from_signup(self.sender, | ||
self.request, | ||
self.user, | ||
**self.kwargs) | ||
self.assertEquals(VERIFIED_EMAIL, self.user.email) | ||
|
||
@fudge.patch('requests.get') | ||
def test_unverified_email_from_github_api(self, fake_get): | ||
(fake_get.expects_call() | ||
.with_args(EMAIL_URL, params=self.params) | ||
.returns_fake() | ||
.expects('json') | ||
.returns( | ||
GITHUB_DATA_WITH_UNVERIFIED_EMAIL)) | ||
|
||
add_email_from_signup(self.sender, | ||
self.request, | ||
self.user, | ||
**self.kwargs) | ||
self.assertEquals(None, self.user.email) | ||
|
||
@fudge.patch('requests.get') | ||
def test_many_emails_from_github_api(self, fake_get): | ||
(fake_get.expects_call() | ||
.with_args(EMAIL_URL, params=self.params) | ||
.returns_fake() | ||
.expects('json') | ||
.returns( | ||
GITHUB_DATA_WITH_MANY_EMAILS)) | ||
|
||
add_email_from_signup(self.sender, | ||
self.request, | ||
self.user, | ||
**self.kwargs) | ||
self.assertEquals(VERIFIED_PRIMARY_EMAIL, self.user.email) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters