def test_fetch_avatar_does_not_overwrite_in_aws(mock_save, db, settings): responses.add(responses.GET, re.compile(r'http://1x1px\.me/.+'), body=open('tests/fixtures/1x1.png', 'rb').read()) mock_save.side_effect = lambda name, *args, **kwargs: name # identity save user1, user2 = UserFactory(), UserFactory() account1 = SocialAccount( provider='google', user=user1, uid='1', extra_data={'picture': 'http://1x1px.me/yszgHjRfq24/photo.jpg'}) account2 = SocialAccount( provider='google', user=user1, uid='1', extra_data={'picture': 'http://1x1px.me/sLbe8rOXpaQ/photo.jpg'}) fetch_avatar(request=None, user=user1, account=account1) fetch_avatar(request=None, user=user2, account=account2) user1.refresh_from_db() user2.refresh_from_db() assert user1.avatar assert user1.avatar != user2.avatar
def sociallogin_from_response(self, request, response): """ Instantiates and populates a `SocialLogin` model based on the data retrieved in `response`. The method does NOT save the model to the DB. Data for `SocialLogin` will be extracted from `response` with the help of the `.extract_uid()`, `.extract_extra_data()`, `.extract_common_fields()`, and `.extract_email_addresses()` methods. :param request: a Django `HttpRequest` object. :param response: object retrieved via the callback response of the social auth provider. :return: A populated instance of the `SocialLogin` model (unsaved). """ # NOTE: Avoid loading models at top due to registry boot... from allauth.socialaccount.models import SocialLogin, SocialAccount adapter = get_adapter(request) uid = self.extract_uid(response) extra_data = self.extract_extra_data(response) common_fields = self.extract_common_fields(response) socialaccount = SocialAccount(extra_data=extra_data, uid=uid, provider=self.id) email_addresses = self.extract_email_addresses(response) self.cleanup_email_addresses(common_fields.get('email'), email_addresses) sociallogin = SocialLogin(account=socialaccount, email_addresses=email_addresses) user = sociallogin.user = adapter.new_user(request, sociallogin) user.set_unusable_password() adapter.populate_user(request, sociallogin, common_fields) return sociallogin
def complete_login(self, request, app, token, **kwargs): resp = requests.get(self.profile_url, params={ 'access_token': token.token, 'alt': 'json' }) extra_data = resp.json() # extra_data is something of the form: # # {u'family_name': u'Penners', u'name': u'Raymond Penners', # u'picture': u'https://lh5.googleusercontent.com/-GOFYGBVOdBQ/AAAAAAAAAAI/AAAAAAAAAGM/WzRfPkv4xbo/photo.jpg', # u'locale': u'nl', u'gender': u'male', # u'email': u'*****@*****.**', # u'link': u'https://plus.google.com/108204268033311374519', # u'given_name': u'Raymond', u'id': u'108204268033311374519', # u'verified_email': True} # # TODO: We could use verified_email to bypass allauth email verification uid = str(extra_data['id']) user = get_adapter() \ .populate_new_user(email=extra_data.get('email'), last_name=extra_data.get('family_name'), first_name=extra_data.get('given_name')) email_addresses = [] email = user_email(user) if email and extra_data.get('verified_email'): email_addresses.append(EmailAddress(email=email, verified=True, primary=True)) account = SocialAccount(extra_data=extra_data, uid=uid, provider=self.provider_id, user=user) return SocialLogin(account, email_addresses=email_addresses)
def sociallogin_from_response(self, request, response, **kwargs): """Custom sociallogin from user for person and company models.""" from allauth.socialaccount.models import SocialLogin, SocialAccount adapter = SocialAccountAdapter() uid = self.extract_uid(response) extra_data = self.extract_extra_data(response) common_fields = self.extract_common_fields(response) socialaccount = SocialAccount(extra_data=extra_data, uid=uid, provider=self.id) email_addresses = self.extract_email_addresses(response) self.cleanup_email_addresses(common_fields.get('email'), email_addresses) sociallogin = SocialLogin(account=socialaccount, email_addresses=email_addresses) # user = sociallogin.user = adapter.new_user(request, sociallogin) from .serializers import RegisterSerializer data = RegisterSerializer().validate_account_type(account_type=extra_data['account_type']) if 'C' in data.keys(): user = sociallogin.user = Company() user.user_type = User.COMPANY else: user = sociallogin.user = Person() user.set_unusable_password() adapter.populate_user(request, sociallogin, common_fields) return sociallogin, response
def test_get_avatar_url_no_picture_setting(self): extra_data = ''' { "profilePicture": { "displayImage": "urn:li:digitalmediaAsset:12345abcdefgh-12abcd" }, "id": "1234567", "lastName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Penners" } }, "firstName": { "preferredLocale": { "language": "en", "country": "US" }, "localized": { "en_US": "Raymond" } } } ''' acc = SocialAccount( extra_data=loads(extra_data), provider='linkedin_oauth2', ) self.assertIsNone(acc.get_avatar_url())
def complete_login(self, request, app, token): resp = requests.get(self.profile_url, { 'access_token': token.token, 'alt': 'json' }) extra_data = resp.json # extra_data is something of the form: # # {u'family_name': u'Penners', u'name': u'Raymond Penners', # u'picture': u'https://lh5.googleusercontent.com/-GOFYGBVOdBQ/AAAAAAAAAAI/AAAAAAAAAGM/WzRfPkv4xbo/photo.jpg', # u'locale': u'nl', u'gender': u'male', # u'email': u'*****@*****.**', # u'link': u'https://plus.google.com/108204268033311374519', # u'given_name': u'Raymond', u'id': u'108204268033311374519', # u'verified_email': True} # # TODO: We could use verified_email to bypass allauth email verification uid = str(extra_data['id']) user = User(email=extra_data.get('email', ''), last_name=extra_data.get('family_name', ''), first_name=extra_data.get('given_name', '')) account = SocialAccount(extra_data=extra_data, uid=uid, provider=self.provider_id, user=user) return SocialLogin(account)
def complete_login(self, request, app, token, **kwargs): resp = requests.get( self.profile_url, headers={'Authorization': 'Bearer %s' % token.token}) resp.raise_for_status() extra_data = resp.json() oauth2_client = self.get_oauth2_client() extra_data.update({ 'sso_client_identifier': oauth2_client.identifier, 'sso_client_name': oauth2_client.name, 'sso_client_domain': oauth2_client.domain, }) # We trust the email address; therefore, we will add this login method to any existing user with that email address. # We do so by creating a SocialAccount if it does not exist. email = extra_data[oauth2_client.email_key] try: user = User.objects.get(email=email) except User.DoesNotExist: pass else: object_identifier = {'provider': self.provider_id, 'uid': email} if not SocialAccount.objects.filter(**object_identifier).exists(): social_account = SocialAccount(user_id=user.id, extra_data=extra_data, **object_identifier) social_account.save() login = self.get_provider() \ .sociallogin_from_response(request, extra_data) return login
def persona_login(request): assertion = request.POST.get('assertion', '') audience = request.build_absolute_uri('/') resp = requests.post('https://verifier.login.persona.org/verify', { 'assertion': assertion, 'audience': audience }) if resp.json['status'] != 'okay': return render_authentication_error(request) email = resp.json['email'] user = User(email=email) extra_data = resp.json account = SocialAccount(uid=email, provider=PersonaProvider.id, extra_data=extra_data, user=user) # TBD: Persona e-mail addresses are verified, so we could check if # a matching local user account already exists with an identical # verified e-mail address and short-circuit the social login. Then # again, this holds for all social providers that guarantee # verified e-mail addresses, so if at all, short-circuiting should # probably not be handled here... login = SocialLogin(account) login.state = SocialLogin.state_from_request(request) return complete_social_login(request, login)
def complete_login(self, request, app, token, **kwargs): userob = kwargs["user"] extra = kwargs["extra"] extra_info = [] for item in extra: item_serial = item.__dict__['display_name'] extra_info.append(item_serial) #extra = serializers.serialize("json", extra) logging.debug(extra_info) #extra = json.dumps(extra) # auth = ('bearer', token.token) # resp = requests.get(self.profile_url, # params={ 'oauth_token': token.token }) #extra_data = resp.json() # uid = str(extra_data['id']) user = get_adapter() \ .populate_new_user(name=userob.name, username=userob.name, email=userob.name) account = SocialAccount(user=user, uid=userob.id, extra_data=extra_info, provider=self.provider_id) return SocialLogin(account)
def test_get_social_account_image_linkedin(): account = SocialAccount( extra_data={ 'profilePicture': { 'displayImage~': { 'paging': { 'count': 10, 'start': 0, 'links': [] }, 'elements': [ { 'identifiers': [{ 'identifier': 'https://image.com/image.png', }] }, ], } }, 'id': 's27gBbCPyF', }, provider='linkedin_oauth2', ) assert utils.get_social_account_image( account) == 'https://image.com/image.png'
def test_get_social_account_image_linkedin_no_profile_pic(): account = SocialAccount( extra_data={'id': 's27gBbCPyF'}, provider='linkedin_oauth2', ) assert utils.get_social_account_image(account) is None
def test_pre_social_login_error_for_unmatched_login(self): """ https://bugzil.la/1063830 """ # Set up a GitHub SocialLogin in the session github_account = SocialAccount.objects.get(user__username='******') github_login = SocialLogin(account=github_account) request = self.rf.get('/') session = self.client.session session['socialaccount_sociallogin'] = github_login.serialize() session.save() request.session = session messages = self.get_messages(request) # Set up an un-matching Persona SocialLogin for request persona_account = SocialAccount(user=User(), provider='persona', uid='*****@*****.**') persona_login = SocialLogin(account=persona_account) self.assertRaises(ImmediateHttpResponse, self.adapter.pre_social_login, request, persona_login) queued_messages = list(messages) eq_(len(queued_messages), 1) eq_(django_messages.ERROR, queued_messages[0].level)
def sociallogin_from_response(self, request, response): """ COPIED FROM https://github.com/pennersr/django-allauth/blob/5b1cbf485fa363ccb87513545e3b98f3c3bd81fa/allauth/socialaccount/providers/base.py#L52 TO PASS SocialApp TO EXTRACT METHODS PER https://github.com/pennersr/django-allauth/issues/1297 """ # NOTE: Avoid loading models at top due to registry boot... from allauth.socialaccount.models import SocialLogin, SocialAccount adapter = get_adapter() app = self.get_app(request) uid = self.extract_uid(response, app) extra_data = self.extract_extra_data(response, app) common_fields = self.extract_common_fields(response, app) socialaccount = SocialAccount(extra_data=extra_data, uid=uid, provider=self.id) email_addresses = self.extract_email_addresses(response, app) self.cleanup_email_addresses(common_fields.get('email'), email_addresses) sociallogin = SocialLogin(account=socialaccount, email_addresses=email_addresses) user = sociallogin.user = adapter.new_user(request, sociallogin) user.set_unusable_password() adapter.populate_user(request, sociallogin, common_fields) return sociallogin
def _create_social_user(self, emails, provider, uid, token=None): factory = RequestFactory() request = factory.get("/me/login/callback/") request.user = AnonymousUser() SessionMiddleware().process_request(request) MessageMiddleware().process_request(request) user = User( username=emails[0].email.split("@")[0], first_name=emails[0].email.split("@")[0], last_name=emails[0].email.split("@")[1], email=emails[0].email, ) account = SocialAccount(provider=provider, uid=uid) if token is not None: token = SocialToken( token=token, account=account, app=SocialApp.objects.get(provider=provider), ) sociallogin = SocialLogin(account=account, user=user, email_addresses=emails, token=token) complete_social_login(request, sociallogin)
def test_pre_social_login_same_provider(self): """ pre_social_login passes if existing provider is the same. I'm not sure what the real-world counterpart of this is. Logging in with a different GitHub account? Needed for branch coverage. """ # Set up a GitHub SocialLogin in the session github_account = SocialAccount.objects.get(user__username='******') github_login = SocialLogin(account=github_account, user=github_account.user) request = self.rf.get('/') session = self.client.session session['sociallogin_provider'] = 'github' session['socialaccount_sociallogin'] = github_login.serialize() session.save() request.session = session # Set up an un-matching GitHub SocialLogin for request github2_account = SocialAccount(user=self.user_model(), provider='github', uid=github_account.uid + '2') github2_login = SocialLogin(account=github2_account) self.adapter.pre_social_login(request, github2_login) eq_(request.session['sociallogin_provider'], 'github')
def test_pre_social_login_error_for_unmatched_login(self): """ When we suspect the signup form is used as a connection form, abort. https://bugzil.la/1063830 """ # Set up a GitHub SocialLogin in the session github_account = SocialAccount.objects.get(user__username='******') github_login = SocialLogin(account=github_account, user=github_account.user) request = self.rf.get('/') session = self.client.session session['socialaccount_sociallogin'] = github_login.serialize() session.save() request.session = session messages = self.get_messages(request) # Set up an un-matching alternate SocialLogin for request other_account = SocialAccount(user=self.user_model(), provider='other', uid='*****@*****.**') other_login = SocialLogin(account=other_account) self.assertRaises(ImmediateHttpResponse, self.adapter.pre_social_login, request, other_login) queued_messages = list(messages) eq_(len(queued_messages), 1) eq_(django_messages.ERROR, queued_messages[0].level)
def login(request): ret = None if request.method == 'POST': form = FacebookConnectForm(request.POST) if form.is_valid(): try: token = form.cleaned_data['access_token'] g = GraphAPI(token) facebook_me = g.get_object("me") email = valid_email_or_none(facebook_me.get('email')) social_id = facebook_me['id'] try: account = SocialAccount.objects.get( uid=social_id, provider=FacebookProvider.id) except SocialAccount.DoesNotExist: account = SocialAccount(uid=social_id, provider=FacebookProvider.id) data = dict(email=email, facebook_access_token=token, facebook_me=facebook_me) # some facebook accounts don't have this data data.update((k, v) for (k, v) in facebook_me.items() if k in ['username', 'first_name', 'last_name']) # Don't save partial/temporary accounts that haven't # gone through the full signup yet, as there is no # User attached yet. if account.pk: account.sync(data) ret = complete_social_login(request, data, account) except (GraphAPIError, IOError): pass if not ret: ret = render_authentication_error(request) return ret
def test_pre_social_login_error_for_unmatched_login(self): """ https://bugzil.la/1063830 """ # Set up a GitHub SocialLogin in the session github_account = SocialAccount.objects.get(user__username='******') github_login = SocialLogin(account=github_account) request = RequestFactory().get('/') session = self.client.session session['socialaccount_sociallogin'] = github_login.serialize() session.save() request.session = session # django 1.4 RequestFactory requests can't be used to test views that # call messages.add (https://code.djangoproject.com/ticket/17971) # FIXME: HACK from http://stackoverflow.com/q/11938164/571420 messages = FallbackStorage(request) request._messages = messages # Set up an un-matching Persona SocialLogin for request persona_account = SocialAccount(user=User(), provider='persona', uid='*****@*****.**') persona_login = SocialLogin(account=persona_account) assert_raises(ImmediateHttpResponse, self.adapter.pre_social_login, request, persona_login) for m in messages: eq_(django_messages.ERROR, m.level)
def test_get_redir_user_demo(self): payload = {"user": {"username": self.demo["username"]}} self.client.login(username=payload["user"]["username"], password="******") sapp = SocialApp(provider='github', name='Github', client_id='<test>', secret='<test>') sapp.save() sacc = SocialAccount(uid=1001, user=self.test_user, provider="github") sacc.save() stoken = SocialToken(app=sapp, account=sacc, token="test_token") stoken.save() response = self.client.post('/accounts/profile', follow=True) first_url, first_response = response.redirect_chain[0] self.assertEqual( first_url, "/login?status=passed&token=test_token&username=testname&user_id=1001" ) self.client.login(username=payload["user"]["username"], password="******") stoken = SocialToken(app=sapp, account=sacc, token="test_token") stoken.save() response = self.client.post('/accounts/profile', follow=True) first_url, first_response = response.redirect_chain[0] self.assertEqual( first_url, "/login?status=passed&token=test_token&username=testname&user_id=1001" )
def _create_social_user(self): u = User.objects.create(username='******', email='*****@*****.**') u.set_unusable_password() u.save() sa = SocialAccount(user=u, provider='facebook', uid='12345', extra_data='{}') sa.full_clean() sa.save() return u
def test_get_social_account_image_linkedin_no_display_image(): account = SocialAccount( extra_data={ 'profilePicture': {}, 'id': 's27gBbCPyF' }, provider='linkedin_oauth2', ) assert utils.get_social_account_image(account) is None
def _get_sociallogin(user, provider): """ Returns an ready sociallogin object for the given auth provider. """ socialaccount = SocialAccount(user=user, uid='1234', provider=provider) socialaccount.extra_data = {'email': user.email} sociallogin = SocialLogin() sociallogin.account = socialaccount return sociallogin
def join(request): current_user = request.session.get('current_user', None) socialaccount_sociallogin = request.session.get('socialaccount_sociallogin', None) if not current_user and not socialaccount_sociallogin: raise Http404 if request.method == 'POST': form = UserForm(request.POST) if form.is_valid(): password = '******'+str(uuid.uuid4()).replace("-", "") # 유저 생성 user = User.objects.create(email=request.POST.get('email'), password=password) mailing_agree = request.POST.get('mailing_agree', None) # 소셜 정보 생성 social_auth = SocialAccount() if current_user: social_user = request.session['current_user']['obj'] social_auth.provider = 'soundcloud' social_auth.uid = social_user['id'] user.username = social_user['username'] user.soundcloud_url = social_user['permalink_url'] user.profile_picture = social_user['avatar_url'] social_auth.user_id = user.id if socialaccount_sociallogin: social_user = request.session['socialaccount_sociallogin']['account'] social_auth.provider = social_user['provider'] social_auth.uid = social_user['uid'] social_auth.user_id = user.id if 'naver' in social_user['provider']: user.username = social_user['extra_data'].get('name', social_user['extra_data']['nickname']) user.profile_picture = social_user['extra_data'].get('profile_image', '') else: user.username = social_user['extra_data'].get('name', '') social_auth.save() if mailing_agree and 'on' in mailing_agree: user.mailing_agree = True user.last_login = datetime.now() user.save() auth_login(request, user, backend='django.contrib.auth.backends.ModelBackend') # 콜백 # msg = settings.SOCIAL_AUTH_LOGIN_REDIRECT_URL+"#status=success&access_token="+get_user_token(user.id) return auth_redirect(request, "#status=success&access_token="+get_user_token(user.id)) # return redirect('//dopehotz.com'+msg) else: form = UserForm() return render(request, 'accounts/join_form.html', {'form': form, 'main_site' : settings.MAIN_URL})
def get_or_create_user(payload, oidc=False): user_id = payload.get('sub') if not user_id: msg = _('Invalid payload. sub missing') raise ValueError(msg) # django-helusers uses UUID as the primary key for the user # If the incoming token does not have UUID in the sub field, # we must synthesize one if not is_valid_uuid(user_id): # Maybe we have an Azure pairwise ID? Check for Azure tenant ID # in token and use that as UUID namespace if available namespace = payload.get('tid') user_id = convert_to_uuid(user_id, namespace) try_again = False try: user = _try_create_or_update(user_id, payload, oidc) except IntegrityError: # If we get an integrity error, it probably meant a race # condition with another process. Another attempt should # succeed. try_again = True if try_again: # We try again without catching exceptions this time. user = _try_create_or_update(user_id, payload, oidc) # If allauth.socialaccount is installed, create the SocialAcount # that corresponds to this user. Otherwise logins through # allauth will not work for the user later on. if 'allauth.socialaccount' in settings.INSTALLED_APPS: from allauth.socialaccount.models import SocialAccount, EmailAddress if oidc: provider_name = 'helsinki_oidc' else: provider_name = 'helsinki' args = {'provider': provider_name, 'uid': user_id} try: account = SocialAccount.objects.get(**args) assert account.user_id == user.id except SocialAccount.DoesNotExist: account = SocialAccount(**args) account.extra_data = payload account.user = user account.save() try: email = EmailAddress.objects.get(email__iexact=user.email) assert email.user == user except EmailAddress.DoesNotExist: email = EmailAddress(email=user.email.lower(), primary=True, user=user, verified=True) email.save() return user
def twitter_complete_login(extra_data): uid = extra_data['id'] user = get_adapter() \ .populate_new_user(username=extra_data.get('screen_name'), name=extra_data.get('name')) account = SocialAccount(user=user, uid=uid, provider=TwitterProvider.id, extra_data=extra_data) return SocialLogin(account)
def sociallogin(client, user_model): account = SocialAccount(provider="google") sociallogin = SocialLogin( account=account, user=user_model(), ) session = client.session session["socialaccount_sociallogin"] = sociallogin.serialize() session.save() return sociallogin
class SocialInteractionFactory(factory.django.DjangoModelFactory): class Meta: model = SocialInteractionPost creator = factory.SubFactory(UserFactory) text_to_post = 'Text to post including $link$' link = 'www.link.com' project = factory.SubFactory(ProjectFactory) status = 'active' socialaccount = SocialAccount()
class SocialInteractionPullFactory(factory.django.DjangoModelFactory): class Meta: model = SocialInteractionPull creator = factory.SubFactory(UserFactory) text_to_pull = '#Project2' project = factory.SubFactory(ProjectFactory) status = 'active' socialaccount = SocialAccount() frequency = '5min'
def test_is_auto_signup_allowed_override_for_helsinki_adfs( settings, provider_id, expected): settings.SOCIALACCOUNT_AUTO_SIGNUP = False request = RequestFactory().get('/accounts/signup/') account = SocialAccount(provider=provider_id) sociallogin = SocialLogin(account=account) assert get_adapter(request).is_auto_signup_allowed(request, sociallogin) == expected
def complete_login(self, request, app, token): client = TwitterAPI(request, app.key, app.secret, self.request_token_url) extra_data = client.get_user_info() uid = extra_data['id'] user = User(username=extra_data['screen_name'], first_name=extra_data['name']) account = SocialAccount(user=user, uid=uid, provider=TwitterProvider.id, extra_data=extra_data) return SocialLogin(account)