def auth_complete(self, *args, **kwargs): """Returns user, might be logged in""" if 'code' in self.data: url = GITHUB_ACCESS_TOKEN_URL + '?' + urllib.urlencode({ 'client_id': setting('GITHUB_APP_ID'), 'redirect_uri': self.redirect_uri, 'client_secret': setting('GITHUB_API_SECRET'), 'code': self.data['code'] }) response = cgi.parse_qs(urllib.urlopen(url).read()) if response.get('error'): error = self.data.get('error') or 'unknown error' raise ValueError('Authentication error: %s' % error) access_token = response['access_token'][0] data = self.user_data(access_token) if data is not None: if 'error' in data: error = self.data.get('error') or 'unknown error' raise ValueError('Authentication error: %s' % error) data['access_token'] = access_token kwargs.update({'response': data, GithubBackend.name: True}) return authenticate(*args, **kwargs) else: error = self.data.get('error') or 'unknown error' raise ValueError('Authentication error: %s' % error)
def get_username(details, user=None, user_exists=UserSocialAuth.simple_user_exists, *args, **kwargs): """Return an username for new user. Return current user username if user was given. """ if user: return {"username": user.username} if details.get(USERNAME): username = unicode(details[USERNAME]) else: username = uuid4().get_hex() uuid_length = setting("SOCIAL_AUTH_UUID_LENGTH", 16) max_length = UserSocialAuth.username_max_length() do_slugify = setting("SOCIAL_AUTH_SLUGIFY_USERNAMES", False) short_username = username[: max_length - uuid_length] final_username = UserSocialAuth.clean_username(username[:max_length]) if do_slugify: final_username = slugify(final_username) # Generate a unique username for current user using username # as base but adding a unique hash at the end. Original # username is cut to avoid any field max_length. while user_exists(username=final_username): username = short_username + uuid4().get_hex()[:uuid_length] final_username = UserSocialAuth.clean_username(username[:max_length]) if do_slugify: final_username = slugify(final_username) return {"username": final_username}
def auth_complete(self, *args, **kwargs): if 'code' not in self.data: if self.data.get('error') == 'access_denied': raise AuthCanceled(self) else: raise AuthException(self) post_data = urlencode({ 'client_id': setting(self.SETTINGS_KEY_NAME), 'redirect_uri': self.redirect_uri, 'client_secret': setting(self.SETTINGS_SECRET_NAME), 'code': self.data['code'], 'grant_type': 'authorization_code' }) try: response = simplejson.loads(urlopen(self.ACCESS_TOKEN_URL, post_data).read()) except HTTPError: raise AuthFailed(self, 'There was an error authenticating the app') access_token = response['access_token'] data = self.user_data(response) if data is not None: data['access_token'] = access_token # expires will not be part of response if offline access # premission was requested if 'expires_in' in response: data['expires_in'] = response['expires_in'] kwargs.update({'auth': self, 'response': data, self.AUTH_BACKEND.name: True}) return authenticate(*args, **kwargs)
def __init__(self, request, redirect): """Init method""" super(BaseOAuth, self).__init__(request, redirect) if setting('VAGRANT_ENABLED'): self.redirect_uri = "http://localhost:" + str(setting('VAGRANT_PORT_FORWARD')) + self.redirect else: self.redirect_uri = self.build_absolute_uri(self.redirect)
def auth_complete(self, *args, **kwargs): """Completes loging process, must return user instance""" if 'code' in self.data: url = 'https://graph.facebook.com/oauth/access_token?' + \ urlencode({'client_id': setting(self.SETTINGS_KEY_NAME), 'redirect_uri': self.redirect_uri, 'client_secret': setting(self.SETTINGS_SECRET_NAME), 'code': self.data['code']}) response = cgi.parse_qs(urlopen(url).read()) access_token = response['access_token'][0] data = self.user_data(access_token) if data is not None: if 'error' in data: error = self.data.get('error') or 'unknown error' raise ValueError('Authentication error: %s' % error) data['access_token'] = access_token # expires will not be part of response if offline access # premission was requested if 'expires' in response: data['expires'] = response['expires'][0] kwargs.update({ 'auth': self, 'response': data, self.AUTH_BACKEND.name: True }) # logger.info('%s %s' % (args, kwargs)) return authenticate(*args, **kwargs) else: error = self.data.get('error') or 'unknown error' raise ValueError('Authentication error: %s' % error)
def get_username( user_exists=UserSocialAuth.simple_user_exists, ): """Return an username for new user. Return current user username if user was given. """ uuid_length = setting('SOCIAL_AUTH_UUID_LENGTH', 16) do_slugify = setting('SOCIAL_AUTH_SLUGIFY_USERNAMES', False) username = uuid4().get_hex() max_length = UserSocialAuth.username_max_length() short_username = username[:max_length - uuid_length] final_username = UserSocialAuth.clean_username(username[:max_length]) if do_slugify: final_username = slugify(final_username) # Generate a unique username for current user using username # as base but adding a unique hash at the end. Original # username is cut to avoid any field max_length. while user_exists(username=final_username): username = short_username + uuid4().get_hex()[:uuid_length] username = username[:max_length] final_username = UserSocialAuth.clean_username(username) if do_slugify: final_username = slugify(final_username) print final_username return final_username
def wrapper(request, backend, *args, **kwargs): if redirect_name: redirect = reverse(redirect_name, args=(backend,)) else: redirect = request.path backend = get_backend(backend, request, redirect) if not backend: return HttpResponseServerError('Incorrect authentication ' + \ 'service') try: return func(request, backend, *args, **kwargs) except Exception, e: # some error ocurred if setting('DEBUG'): raise backend_name = backend.AUTH_BACKEND.name log('error', unicode(e), exc_info=True, extra=dict(request=request)) if 'django.contrib.messages' in setting('INSTALLED_APPS'): from django.contrib.messages.api import error error(request, unicode(e), extra_tags=backend_name) else: log('warn', 'Messages framework not in place, some '+ 'errors have not been shown to the user.') url = setting('SOCIAL_AUTH_BACKEND_ERROR_URL', LOGIN_ERROR_URL) return HttpResponseRedirect(url)
def vk_api(method, data, is_app=False): """Calls VK OpenAPI method https://vk.com/apiclub, https://vk.com/pages.php?o=-1&p=%C2%FB%EF%EE%EB%ED%E5%ED%E8%E5%20%E7' %E0%EF%F0%EE%F1%EE%E2%20%EA%20API """ # We need to perform server-side call if no access_token if not 'access_token' in data: if not 'v' in data: data['v'] = VK_API_VERSION if not 'api_id' in data: data['api_id'] = setting('VKAPP_APP_ID' if is_app else 'VK_APP_ID') data['method'] = method data['format'] = 'json' url = VK_SERVER_API_URL secret = setting('VKAPP_API_SECRET' if is_app else 'VK_API_SECRET') param_list = sorted(list(item + '=' + data[item] for item in data)) data['sig'] = md5(''.join(param_list) + secret).hexdigest() else: url = VK_API_URL + method params = urlencode(data) url += '?' + params try: return simplejson.load(dsa_urlopen(url)) except (TypeError, KeyError, IOError, ValueError, IndexError): log('error', 'Could not load data from vk.com', exc_info=True, extra=dict(data=data)) return None
def auth_complete(self, *args, **kwargs): """Returns user, might be logged in""" if 'code' not in self.data: error = self.data.get('error') or 'unknown error' raise AuthFailed(self, error) url = GITHUB_ACCESS_TOKEN_URL + urlencode({ 'client_id': setting('GITHUB_APP_ID'), 'redirect_uri': self.redirect_uri, 'client_secret': setting('GITHUB_API_SECRET'), 'code': self.data['code'] }) response = cgi.parse_qs(urlopen(url).read()) if response.get('error'): error = self.data.get('error') or 'unknown error' raise AuthFailed(self, error) access_token = response['access_token'][0] data = self.user_data(access_token) if data is not None: if 'error' in data: error = self.data.get('error') or 'unknown error' raise AuthFailed(self, error) data['access_token'] = access_token kwargs.update({ 'auth': self, 'response': data, self.AUTH_BACKEND.name: True }) return authenticate(*args, **kwargs)
def vk_api(method, data, is_app=False): """Calls VK OpenAPI method https://vk.com/apiclub, https://vk.com/pages.php?o=-1&p=%C2%FB%EF%EE%EB%ED%E5%ED%E8%E5%20%E7' %E0%EF%F0%EE%F1%EE%E2%20%EA%20API """ # We need to perform server-side call if no access_token if not "access_token" in data: if not "v" in data: data["v"] = VK_API_VERSION if not "api_id" in data: data["api_id"] = setting("VKAPP_APP_ID" if is_app else "VK_APP_ID") data["method"] = method data["format"] = "json" url = VK_SERVER_API_URL secret = setting("VKAPP_API_SECRET" if is_app else "VK_API_SECRET") param_list = sorted(list(item + "=" + data[item] for item in data)) data["sig"] = md5("".join(param_list) + secret).hexdigest() else: url = VK_API_URL + method params = urlencode(data) url += "?" + params try: return simplejson.load(dsa_urlopen(url)) except (TypeError, KeyError, IOError, ValueError, IndexError): log("error", "Could not load data from vk.com", exc_info=True, extra=dict(data=data)) return None
def complete_process(request, backend, *args, **kwargs): """Authentication complete process""" # pop redirect value before the session is trashed on login() redirect_value = request.session.get(REDIRECT_FIELD_NAME, '') user = auth_complete(request, backend, *args, **kwargs) if isinstance(user, HttpResponse): return user if not user and request.user.is_authenticated(): return HttpResponseRedirect(redirect_value) if user: if getattr(user, 'is_active', True): # catch is_new flag before login() might reset the instance is_new = getattr(user, 'is_new', False) login(request, user) # user.social_user is the used UserSocialAuth instance defined # in authenticate process social_user = user.social_user if redirect_value: request.session[REDIRECT_FIELD_NAME] = redirect_value or \ DEFAULT_REDIRECT if setting('SOCIAL_AUTH_SESSION_EXPIRATION', True): # Set session expiration date if present and not disabled by # setting. Use last social-auth instance for current provider, # users can associate several accounts with a same provider. if social_user.expiration_delta(): try: request.session.set_expiry(social_user.expiration_delta()) except OverflowError: # Handle django time zone overflow, set default expiry. request.session.set_expiry(None) # store last login backend name in session key = setting('SOCIAL_AUTH_LAST_LOGIN', 'social_auth_last_login_backend') request.session[key] = social_user.provider # Remove possible redirect URL from session, if this is a new # account, send him to the new-users-page if defined. new_user_redirect = backend_setting(backend, 'SOCIAL_AUTH_NEW_USER_REDIRECT_URL') if new_user_redirect and is_new: url = new_user_redirect else: url = redirect_value or \ backend_setting(backend, 'SOCIAL_AUTH_LOGIN_REDIRECT_URL') or \ DEFAULT_REDIRECT else: url = backend_setting(backend, 'SOCIAL_AUTH_INACTIVE_USER_URL', LOGIN_ERROR_URL) else: msg = setting('LOGIN_ERROR_MESSAGE', None) if msg: messages.error(request, msg) url = backend_setting(backend, 'LOGIN_ERROR_URL', LOGIN_ERROR_URL) return HttpResponseRedirect(url)
def setup_request(self, extra_params=None): """Setup request""" openid_request = self.openid_request(extra_params) # Request some user details. Use attribute exchange if provider # advertises support. if openid_request.endpoint.supportsType(ax.AXMessage.ns_uri): fetch_request = ax.FetchRequest() # Mark all attributes as required, Google ignores optional ones for attr, alias in AX_SCHEMA_ATTRS + OLD_AX_ATTRS: fetch_request.add(ax.AttrInfo(attr, alias=alias, required=True)) else: fetch_request = sreg.SRegRequest(optional=dict(SREG_ATTR).keys()) openid_request.addExtension(fetch_request) # Add PAPE Extension for if configured preferred_policies = setting("SOCIAL_AUTH_OPENID_PAPE_PREFERRED_AUTH_POLICIES") preferred_level_types = setting("SOCIAL_AUTH_OPENID_PAPE_PREFERRED_AUTH_LEVEL_TYPES") max_age = setting("SOCIAL_AUTH_OPENID_PAPE_MAX_AUTH_AGE") if max_age is not None: try: max_age = int(max_age) except (ValueError, TypeError): max_age = None if max_age is not None or preferred_policies is not None or preferred_level_types is not None: pape_request = pape.Request( preferred_auth_policies=preferred_policies, max_auth_age=max_age, preferred_auth_level_types=preferred_level_types, ) openid_request.addExtension(pape_request) return openid_request
def create_beta_user(backend, details, response, uid, username, user=None, *args, **kwargs): """Create user. Depends on get_username pipeline.""" if user: return {'user': user} if not username: return None if setting('BETA_ENABLE_BETA', True): request = kwargs['request'] invitation_code = request.COOKIES.get('invitation_code', False) if not invitation_code: return HttpResponseRedirect(setting('BETA_REDIRECT_URL')) valid, exists = InvitationCode.validate_code(invitation_code) if not valid: return HttpResponseRedirect(setting('BETA_REDIRECT_URL')) email = details.get('email') user = UserSocialAuth.objects.create_user(username=username, email=email) if setting('BETA_ENABLE_BETA', True): invite_used.send(sender=user, user=user, invitation_code=invitation_code) return { 'user': user, 'is_new': True }
def setUp(self, *args, **kwargs): super(FacebookTestCase, self).setUp(*args, **kwargs) self.user = setting('TEST_FACEBOOK_USER') self.passwd = setting('TEST_FACEBOOK_PASSWORD') # check that user and password are setup properly self.assertTrue(self.user) self.assertTrue(self.passwd)
def auth_process(request, backend): """Authenticate using social backend""" print(backend) data = request.POST if request.method == 'POST' else request.GET # Save extra data into session. for field_name in setting('SOCIAL_AUTH_FIELDS_STORED_IN_SESSION', []): if field_name in data: request.session[field_name] = data[field_name] # Save any defined next value into session if REDIRECT_FIELD_NAME in data: # Check and sanitize a user-defined GET/POST next field value redirect = data[REDIRECT_FIELD_NAME] if setting('SOCIAL_AUTH_SANITIZE_REDIRECTS', True): redirect = sanitize_redirect(request.get_host(), redirect) request.session[REDIRECT_FIELD_NAME] = redirect or DEFAULT_REDIRECT # Clean any partial pipeline info before starting the process clean_partial_pipeline(request) if backend.uses_redirect: return HttpResponseRedirect(backend.auth_url()) else: return HttpResponse(backend.auth_html(), content_type='text/html;charset=UTF-8')
def get_backends(force_load=False): """ Entry point to the BACKENDS cache. If BACKENDSCACHE hasn't been populated, each of the modules referenced in AUTHENTICATION_BACKENDS is imported and checked for a BACKENDS definition and if enabled, added to the cache. Previously all backends were attempted to be loaded at import time of this module, which meant that backends that subclass bases found in this module would not have the chance to be loaded by the time they were added to this module's BACKENDS dict. See: https://github.com/omab/django-social-auth/issues/204 This new approach ensures that backends are allowed to subclass from bases in this module and still be picked up. A force_load boolean arg is also provided so that get_backend below can retry a requested backend that may not yet be discovered. """ if not BACKENDSCACHE or force_load: for auth_backend in setting('AUTHENTICATION_BACKENDS'): module = import_module(auth_backend.rsplit(".", 1)[0]) backends = getattr(module, "BACKENDS", {}) for name, backend in backends.items(): if backend.enabled() and name in setting('SOCIAL_AUTH_ENABLED_BACKENDS'): BACKENDSCACHE[name] = backend return BACKENDSCACHE
def auth_complete(self, *args, **kwargs): """Returns user, might be logged in""" if "code" not in self.data: error = self.data.get("error") or "unknown error" raise AuthFailed(self, error) url = GITHUB_ACCESS_TOKEN_URL + urlencode( { "client_id": setting("GITHUB_APP_ID"), "redirect_uri": self.redirect_uri, "client_secret": setting("GITHUB_API_SECRET"), "code": self.data["code"], } ) response = cgi.parse_qs(urlopen(url).read()) if response.get("error"): error = self.data.get("error") or "unknown error" raise AuthFailed(self, error) access_token = response["access_token"][0] data = self.user_data(access_token) if data is not None: if "error" in data: error = self.data.get("error") or "unknown error" raise AuthFailed(self, error) data["access_token"] = access_token kwargs.update({"auth": self, "response": data, self.AUTH_BACKEND.name: True}) return authenticate(*args, **kwargs)
def auth_complete(self, *args, **kwargs): """Completes login process, must return user instance""" access_token = None if self.data.get('error'): error = self.data.get('error_description') or self.data['error'] raise AuthFailed(self, error) client_id, client_secret = self.get_key_and_secret() try: shop_url = self.request.GET.get('shop') self.shopifyAPI.Session.setup( api_key=setting('SHOPIFY_APP_API_KEY'), secret=setting('SHOPIFY_SHARED_SECRET') ) shopify_session = self.shopifyAPI.Session(shop_url, self.request.REQUEST) access_token = shopify_session.token except self.shopifyAPI.ValidationException as e: raise AuthCanceled(self) except HTTPError as e: if e.code == 400: raise AuthCanceled(self) else: raise if not access_token: raise AuthFailed(self, 'Authentication Failed') return self.do_auth(access_token, shop_url, shopify_session.url, *args, **kwargs)
def auth_url(self): """Returns redirect url""" args = {"client_id": setting("GITHUB_APP_ID"), "redirect_uri": self.redirect_uri} if setting("GITHUB_EXTENDED_PERMISSIONS"): args["scope"] = ",".join(setting("GITHUB_EXTENDED_PERMISSIONS")) args.update(self.auth_extra_arguments()) return GITHUB_AUTHORIZATION_URL + urlencode(args)
def setUp(self, *args, **kwargs): super(GoogleTestCase, self).setUp(*args, **kwargs) self.user = setting('TEST_GOOGLE_USER') self.passwd = setting('TEST_GOOGLE_PASSWORD') # check that user and password are setup properly self.assertTrue(self.user) self.assertTrue(self.passwd)
def setUp(self, *args, **kwargs): super(TwitterTestCase, self).setUp(*args, **kwargs) self.user = setting('TEST_TWITTER_USER') self.passwd = setting('TEST_TWITTER_PASSWORD') # check that user and password are setup properly self.assertTrue(self.user) self.assertTrue(self.passwd)
def auth_complete(self, *args, **kwargs): """Completes loging process, must return user instance""" if 'code' not in self.data: if self.data.get('error') == 'access_denied': raise AuthCanceled(self) else: raise AuthException(self) url = ACCESS_TOKEN + urlencode({ 'client_id': setting('FACEBOOK_APP_ID'), 'redirect_uri': self.redirect_uri, 'client_secret': setting('FACEBOOK_API_SECRET'), 'code': self.data['code'] }) try: response = cgi.parse_qs(urlopen(url).read()) except HTTPError: raise AuthFailed(self, 'There was an error authenticating the app') access_token = response['access_token'][0] data = self.user_data(access_token) if data is not None: data['access_token'] = access_token # expires will not be part of response if offline access # premission was requested if 'expires' in response: data['expires'] = response['expires'][0] kwargs.update({'auth': self, 'response': data, self.AUTH_BACKEND.name: True}) return authenticate(*args, **kwargs)
def auth_url(self): """Returns redirect url""" args = {'client_id': setting('GITHUB_APP_ID'), 'redirect_uri': self.redirect_uri} if setting('GITHUB_EXTENDED_PERMISSIONS'): args['scope'] = ','.join(setting('GITHUB_EXTENDED_PERMISSIONS')) args.update(self.auth_extra_arguments()) return GITHUB_AUTHORIZATION_URL + '?' + urllib.urlencode(args)
def __init__(self, api_host, access_token): self._api_host = api_host self._access_token = access_token self._key = setting("BODYMEDIA_CONSUMER_KEY") self._secret = setting("BODYMEDIA_CONSUMER_SECRET") self._headers = {"Content-type": "application/json"} self._default_params = {"api_key": self._key,} self._user_info = self._get_user_info()
def _get(self, url, info_key): key = setting("IHEALTH_CONSUMER_KEY") secret = setting("IHEALTH_CONSUMER_SECRET") sc = setting('IHEALTH_USER_SN') params = {"Client_id": key, "client_secret": secret, "access_token":self._access_token, "sc": sc, "sv":info_key} response = requests.get(url, params=params) return response.json()
def _signature(self, params): """ See here: http://open.taobao.com/doc/detail.htm?id=111#s6 """ parts = ["%s%s" % (n, params[n]) for n in sorted(params.keys())] parts.insert(0, setting(self.SETTINGS_SECRET_NAME)) parts.append(setting(self.SETTINGS_SECRET_NAME)) body = "".join(parts) if isinstance(body, unicode): body = body.encode("utf-8") return hashlib.md5(body).hexdigest().upper()
def oauth_request(self, token, url, extra_params=None): extra_params = extra_params or {} scope = GOOGLE_OAUTH_SCOPE + setting('GOOGLE_OAUTH_EXTRA_SCOPE', []) extra_params.update({ 'scope': ' '.join(scope), }) if not self.registered(): xoauth_displayname = setting('GOOGLE_DISPLAY_NAME', 'Social Auth') extra_params['xoauth_displayname'] = xoauth_displayname return super(GoogleOAuth, self).oauth_request(token, url, extra_params)
def auth_url(self): self.shopifyAPI.Session.setup(api_key=setting("SHOPIFY_APP_API_KEY"), secret=setting("SHOPIFY_SHARED_SECRET")) scope = self.get_scope() state = self.state_token() self.request.session[self.AUTH_BACKEND.name + "_state"] = state redirect_uri = self.get_redirect_uri(state) permission_url = self.shopifyAPI.Session.create_permission_url( self.request.GET.get("shop").strip(), scope=scope, redirect_uri=redirect_uri ) return permission_url
def build_absolute_uri(self, path=None): """Build absolute URI for given path. Replace http:// schema with https:// if SOCIAL_AUTH_REDIRECT_IS_HTTPS is defined. """ uri = self.request.build_absolute_uri(path) if setting('SOCIAL_ATUH_REDIRECT_REWRITE_FROM') and setting('SOCIAL_ATUH_REDIRECT_REWRITE_TO'): uri = re.sub(setting('SOCIAL_ATUH_REDIRECT_REWRITE_FROM'), setting('SOCIAL_ATUH_REDIRECT_REWRITE_TO'), uri) if setting('SOCIAL_AUTH_REDIRECT_IS_HTTPS'): uri = uri.replace('http://', 'https://') return uri
def validate_whitelists(email): """Validates allowed domains and emails against the GOOGLE_WHITE_LISTED_DOMAINS and GOOGLE_WHITE_LISTED_EMAILS settings. Allows all domains or emails if setting is an empty list. """ emails = setting('GOOGLE_WHITE_LISTED_EMAILS', []) domains = setting('GOOGLE_WHITE_LISTED_DOMAINS', []) if emails and email in emails: return # you're good if domains and email.split('@', 1)[1] not in domains: raise ValueError('Domain not allowed')
def get_scope(self): return setting('MAILRU_OAUTH2_EXTRA_SCOPE', [])
def enabled(cls): """Return backend enabled status by checking basic settings""" return bool(setting(cls.SETTINGS_KEY_NAME) and setting(cls.SETTINGS_SECRET_NAME))
AuthStateMissing, AuthStateForbidden, BackendError, ) from social_auth.backends.utils import build_consumer_oauth_request from oauth2 import Consumer as OAuthConsumer, Token, Request as OAuthRequest from sentry.utils import json PIPELINE = setting( "SOCIAL_AUTH_PIPELINE", ( "social_auth.backends.pipeline.social.social_auth_user", # Removed by default since it can be a dangerouse behavior that # could lead to accounts take over. # 'social_auth.backends.pipeline.associate.associate_by_email', "social_auth.backends.pipeline.user.get_username", "social_auth.backends.pipeline.user.create_user", "social_auth.backends.pipeline.social.associate_user", "social_auth.backends.pipeline.social.load_extra_data", "social_auth.backends.pipeline.user.update_user_details", ), ) logger = logging.getLogger("social_auth") class SocialAuthBackend(object): """A django.contrib.auth backend that authenticates the user based on a authentication provider response""" name = "" # provider name, it's stored in database
('http://axschema.org/namePerson/friendly', 'nickname'), ] SREG_ATTR = [('email', 'email'), ('fullname', 'fullname'), ('nickname', 'nickname')] OPENID_ID_FIELD = 'openid_identifier' SESSION_NAME = 'openid' # key for username in user details dict used around, see get_user_details # method USERNAME = '******' PIPELINE = setting('SOCIAL_AUTH_PIPELINE', ( 'social_auth.backends.pipeline.social.social_auth_user', 'social_auth.backends.pipeline.associate.associate_by_email', 'social_auth.backends.pipeline.user.get_username', 'social_auth.backends.pipeline.user.create_user', 'social_auth.backends.pipeline.social.associate_user', 'social_auth.backends.pipeline.social.load_extra_data', 'social_auth.backends.pipeline.user.update_user_details', )) class SocialAuthBackend(ModelBackend): """A django.contrib.auth backend that authenticates the user based on a authentication provider response""" name = '' # provider name, it's stored in database def authenticate(self, *args, **kwargs): """Authenticate user using social credentials Authentication is made if this is the correct backend, backend
from django.db.utils import IntegrityError from social_auth.db.base import UserSocialAuthMixin, AssociationMixin, \ NonceMixin from social_auth.fields import JSONField from social_auth.utils import setting # If User class is overridden, it *must* provide the following fields # and methods work with django-social-auth: # # username = CharField() # last_login = DateTimeField() # is_active = BooleanField() # def is_authenticated(): # ... USER_MODEL = setting('SOCIAL_AUTH_USER_MODEL') or \ setting('AUTH_USER_MODEL') or \ 'auth.User' class UserSocialAuth(models.Model, UserSocialAuthMixin): """Social Auth association model""" user = models.ForeignKey(USER_MODEL, related_name='social_auth') provider = models.CharField(max_length=32) uid = models.CharField(max_length=255) extra_data = JSONField(default='{}') class Meta: """Meta data""" unique_together = ('provider', 'uid') app_label = 'social_auth'
('http://axschema.org/namePerson/first', 'first_name'), ('http://axschema.org/namePerson/last', 'last_name'), ('http://axschema.org/namePerson/friendly', 'nickname'), ] SREG_ATTR = [('email', 'email'), ('fullname', 'fullname'), ('nickname', 'nickname')] OPENID_ID_FIELD = 'openid_identifier' SESSION_NAME = 'openid' PIPELINE = setting( 'SOCIAL_AUTH_PIPELINE', ( 'social_auth.backends.pipeline.social.social_auth_user', # Removed by default since it can be a dangerouse behavior that # could lead to accounts take over. #'social_auth.backends.pipeline.associate.associate_by_email', 'social_auth.backends.pipeline.user.get_username', 'social_auth.backends.pipeline.user.create_user', 'social_auth.backends.pipeline.social.associate_user', 'social_auth.backends.pipeline.social.load_extra_data', 'social_auth.backends.pipeline.user.update_user_details', )) class SocialAuthBackend(object): """A django.contrib.auth backend that authenticates the user based on a authentication provider response""" name = '' # provider name, it's stored in database supports_inactive_user = False def authenticate(self, *args, **kwargs):
def get_scope(self): return setting(VKOAuth2.SCOPE_VAR_NAME) or \ setting('VK_OAUTH2_EXTRA_SCOPE')
AuthCanceled, AuthFailed from social_auth.utils import setting, log, dsa_urlopen # vk configuration VK_AUTHORIZATION_URL = 'http://oauth.vk.com/authorize' VK_ACCESS_TOKEN_URL = 'https://oauth.vk.com/access_token' VK_SERVER = 'vk.com' VK_DEFAULT_DATA = [ 'first_name', 'last_name', 'screen_name', 'nickname', 'photo' ] VK_API_URL = 'https://api.vk.com/method/' VK_SERVER_API_URL = 'http://api.vk.com/api.php' VK_API_VERSION = '3.0' LOCAL_HTML = setting('VK_LOCAL_HTML', setting('VKONTAKTE_LOCAL_HTML', 'vkontakte.html')) USE_APP_AUTH = setting('VKAPP_APP_ID', False) class VKOpenAPIBackend(SocialAuthBackend): """VK OpenAPI authentication backend""" name = 'vk-openapi' def get_user_id(self, details, response): """Return user unique id provided by VK""" return response['id'] def get_user_details(self, response): """Return user details from VK request""" nickname = response.get('nickname') or response['id']
on third party providers that (if using POST) won't be sending csrf token back. """ from django.http import HttpResponseRedirect, HttpResponse from django.contrib.auth import login, REDIRECT_FIELD_NAME from django.contrib.auth.decorators import login_required from django.contrib import messages from django.views.decorators.csrf import csrf_exempt from social_auth.utils import sanitize_redirect, setting, \ backend_setting, clean_partial_pipeline, log from social_auth.decorators import dsa_view import time DEFAULT_REDIRECT = setting('SOCIAL_AUTH_LOGIN_REDIRECT_URL') or \ setting('LOGIN_REDIRECT_URL') LOGIN_ERROR_URL = setting('LOGIN_ERROR_URL', setting('LOGIN_URL')) @dsa_view(setting('SOCIAL_AUTH_COMPLETE_URL_NAME', 'socialauth_complete')) def auth(request, backend): """Start authentication process""" return auth_process(request, backend) @csrf_exempt @dsa_view() def complete(request, backend, *args, **kwargs): """Authentication complete view, override this view if transaction management doesn't suit your needs."""
def get_scope(self): return setting(VKontakteOAuth2.SCOPE_VAR_NAME) or \ setting('VKONTAKTE_OAUTH2_EXTRA_SCOPE')
def _api_get_val_fun(name, conf): if USE_APP_AUTH: return USE_APP_AUTH.get(name) else: return setting(conf)
def _ignore_field(name, is_new=False): return name in ('username', 'id', 'pk') or \ (not is_new and name in setting('SOCIAL_AUTH_PROTECTED_USER_FIELDS', []))
"""Admin settings""" from social_auth.utils import setting if setting('SOCIAL_AUTH_MODELS') in (None, 'social_auth.db.django_models'): from django.contrib import admin from social_auth.models import UserSocialAuth, Nonce, Association _User = UserSocialAuth.user_model() if isinstance(_User, str): from django.db.models.loading import get_model _User = get_model(*_User.split('.', 1)) if hasattr(_User, 'USERNAME_FIELD'): username_field = _User.USERNAME_FIELD elif hasattr(_User, 'username'): username_field = 'username' else: username_field = None fieldnames = ('first_name', 'last_name', 'email') + (username_field, ) all_names = _User._meta.get_all_field_names() user_search_fields = [ 'user__' + name for name in fieldnames if name in all_names ] class UserSocialAuthOption(admin.ModelAdmin): """Social Auth user options""" list_display = ('id', 'user', 'provider', 'uid') search_fields = user_search_fields list_filter = ('provider', )
from functools import wraps from django.conf import settings from django.http import HttpResponseRedirect, HttpResponse, \ HttpResponseServerError from django.core.urlresolvers import reverse from django.contrib.auth import login, REDIRECT_FIELD_NAME from django.contrib.auth.decorators import login_required from django.views.decorators.csrf import csrf_exempt from social_auth.backends import get_backend from social_auth.utils import sanitize_redirect, setting DEFAULT_REDIRECT = setting('SOCIAL_AUTH_LOGIN_REDIRECT_URL') or \ setting('LOGIN_REDIRECT_URL') NEW_USER_REDIRECT = setting('SOCIAL_AUTH_NEW_USER_REDIRECT_URL') NEW_ASSOCIATION_REDIRECT = setting('SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL') DISCONNECT_REDIRECT_URL = setting('SOCIAL_AUTH_DISCONNECT_REDIRECT_URL') LOGIN_ERROR_URL = setting('LOGIN_ERROR_URL', settings.LOGIN_URL) COMPLETE_URL_NAME = setting('SOCIAL_AUTH_COMPLETE_URL_NAME', 'socialauth_complete') ASSOCIATE_URL_NAME = setting('SOCIAL_AUTH_ASSOCIATE_URL_NAME', 'socialauth_associate_complete') SOCIAL_AUTH_LAST_LOGIN = setting('SOCIAL_AUTH_LAST_LOGIN', 'social_auth_last_login_backend') SESSION_EXPIRATION = setting('SOCIAL_AUTH_SESSION_EXPIRATION', True) BACKEND_ERROR_REDIRECT = setting('SOCIAL_AUTH_BACKEND_ERROR_URL', LOGIN_ERROR_URL) SANITIZE_REDIRECTS = setting('SOCIAL_AUTH_SANITIZE_REDIRECTS', True)
def get_scope(self): return setting('ODNOKLASSNIKI_OAUTH2_EXTRA_SCOPE', [])
More information on scope can be found at: http://wiki.developerforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com """ from urllib import urlencode from django.utils import simplejson from social_auth.backends import BaseOAuth2, OAuthBackend from social_auth.utils import dsa_urlopen, setting from oauth2 import Token SALESFORCE_DOMAIN = 'login.salesforce.com' SALESFORCE_TEST_DOMAIN = 'test.salesforce.com' SALESFORCE_TESTING = setting('SALESFORCE_TESTING', False) SALESFORCE_SERVER = "https://" + (SALESFORCE_TEST_DOMAIN if SALESFORCE_TESTING else SALESFORCE_DOMAIN) SALESFORCE_AUTHORIZATION_PATH = '/services/oauth2/authorize' SALESFORCE_ACCESS_TOKEN_PATH = '/services/oauth2/token' SALESFORCE_AUTHORIZATION_URL = SALESFORCE_SERVER + SALESFORCE_AUTHORIZATION_PATH SALESFORCE_ACCESS_TOKEN_URL = SALESFORCE_SERVER + SALESFORCE_ACCESS_TOKEN_PATH class SalesforceBackend(OAuthBackend): name = 'salesforce' EXTRA_DATA = [ ('user_id', 'user_id'),
return super(GoogleOAuth, cls).get_key_and_secret() except AttributeError: return 'anonymous', 'anonymous' @classmethod def enabled(cls): """Google OAuth is always enabled because of anonymous access""" return True def registered(self): """Check if Google OAuth Consumer Key and Consumer Secret are set""" return self.get_key_and_secret() != ('anonymous', 'anonymous') # TODO: Remove this setting name check, keep for backward compatibility _OAUTH2_KEY_NAME = setting('GOOGLE_OAUTH2_CLIENT_ID') and \ 'GOOGLE_OAUTH2_CLIENT_ID' or \ 'GOOGLE_OAUTH2_CLIENT_KEY' class GoogleOAuth2(BaseOAuth2): """Google OAuth2 support""" AUTH_BACKEND = GoogleOAuth2Backend AUTHORIZATION_URL = 'https://accounts.google.com/o/oauth2/auth' ACCESS_TOKEN_URL = 'https://accounts.google.com/o/oauth2/token' SETTINGS_KEY_NAME = _OAUTH2_KEY_NAME SETTINGS_SECRET_NAME = 'GOOGLE_OAUTH2_CLIENT_SECRET' SCOPE_VAR_NAME = 'GOOGLE_OAUTH_EXTRA_SCOPE' DEFAULT_SCOPE = GOOGLE_OAUTH2_SCOPE def user_data(self, access_token, *args, **kwargs):
from __future__ import absolute_import import six from uuid import uuid4 from social_auth.utils import setting, module_member from social_auth.models import UserSocialAuth from social_auth.django_compat import get_all_field_names slugify = module_member( setting("SOCIAL_AUTH_SLUGIFY_FUNCTION", "django.template.defaultfilters.slugify")) def get_username(details, user=None, user_exists=UserSocialAuth.simple_user_exists, *args, **kwargs): """Return an username for new user. Return current user username if user was given. """ if user: return {"username": UserSocialAuth.user_username(user)} email_as_username = setting("SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL", False) uuid_length = setting("SOCIAL_AUTH_UUID_LENGTH", 16) do_slugify = setting("SOCIAL_AUTH_SLUGIFY_USERNAMES", False) if email_as_username and details.get("email"):
def trust_root(self): """Return trust-root option""" return setting('OPENID_TRUST_ROOT') or \ self.request.build_absolute_uri('/')
from django.db.utils import IntegrityError from social_auth.db.base import UserSocialAuthMixin, AssociationMixin, \ NonceMixin from social_auth.fields import JSONField from social_auth.utils import setting # If User class is overridden, it *must* provide the following fields # and methods work with django-social-auth: # # username = CharField() # last_login = DateTimeField() # is_active = BooleanField() # def is_authenticated(): # ... USER_MODEL = setting('SOCIAL_AUTH_USER_MODEL') or \ setting('AUTH_USER_MODEL') or \ 'auth.User' UID_LENGTH = setting('SOCIAL_AUTH_UID_LENGTH', 255) NONCE_SERVER_URL_LENGTH = setting('SOCIAL_AUTH_NONCE_SERVER_URL_LENGTH', 255) ASSOCIATION_SERVER_URL_LENGTH = setting( 'SOCIAL_AUTH_ASSOCIATION_SERVER_URL_LENGTH', 255) ASSOCIATION_HANDLE_LENGTH = setting('SOCIAL_AUTH_ASSOCIATION_HANDLE_LENGTH', 255) class UserSocialAuth(models.Model, UserSocialAuthMixin): """Social Auth association model""" user = models.ForeignKey(USER_MODEL, related_name='social_auth') provider = models.CharField(max_length=32) uid = models.CharField(max_length=UID_LENGTH)
def get_key_and_secret(cls): """Return tuple with Consumer Key and Consumer Secret for current service provider. Must return (key, secret), order *must* be respected. """ return (setting(cls.SETTINGS_KEY_NAME), setting(cls.SETTINGS_SECRET_NAME))
def setUp(self, *args, **kwargs): super(GoogleTestCase, self).setUp(*args, **kwargs) self.user = setting('TEST_GOOGLE_USER') self.passwd = setting('TEST_GOOGLE_PASSWORD')
def get_scope(self): """Return list with needed access scope""" scope = self.DEFAULT_SCOPE or [] if self.SCOPE_VAR_NAME: scope = scope + setting(self.SCOPE_VAR_NAME, []) return scope
token back. """ from urllib2 import quote from django.http import HttpResponseRedirect, HttpResponse from django.contrib.auth import login, REDIRECT_FIELD_NAME from django.contrib.auth.decorators import login_required from django.contrib import messages from django.views.decorators.csrf import csrf_exempt # from django.contrib.auth.models import AnonymousUser from social_auth.utils import sanitize_redirect, setting, \ backend_setting, clean_partial_pipeline from social_auth.decorators import dsa_view, disconnect_view DEFAULT_REDIRECT = setting('SOCIAL_AUTH_LOGIN_REDIRECT_URL', setting('LOGIN_REDIRECT_URL')) LOGIN_ERROR_URL = setting('LOGIN_ERROR_URL', setting('LOGIN_URL')) PIPELINE_KEY = setting('SOCIAL_AUTH_PARTIAL_PIPELINE_KEY', 'partial_pipeline') @dsa_view(setting('SOCIAL_AUTH_COMPLETE_URL_NAME', 'socialauth_complete')) def auth(request, backend): """Start authentication process""" platform = request.GET.get('platform') # Commenting this, as it was messing with the post-signup redirect # Not sure what it does, as there was no comment and the commit message was # unhelpful. # Originally added in: f83f7cfe8a3980a88a02b46cc6bc21b7692c22d0 # request.session.flush() # request.user = AnonymousUser()
"""Social auth models""" import types from importlib import import_module from social_auth.utils import setting SOCIAL_AUTH_MODELS_MODULE = import_module(setting('SOCIAL_AUTH_MODELS', 'social_auth.db.django_models')) globals().update((name, value) for name, value in ((name, getattr(SOCIAL_AUTH_MODELS_MODULE, name)) for name in dir(SOCIAL_AUTH_MODELS_MODULE)) if isinstance(value, (type, types.ClassType)))
def complete_process(request, backend, *args, **kwargs): """Authentication complete process""" # pop redirect value before the session is trashed on login() redirect_value = request.session.get(REDIRECT_FIELD_NAME, '') or \ request.REQUEST.get(REDIRECT_FIELD_NAME, '') user = auth_complete(request, backend, *args, **kwargs) if isinstance(user, HttpResponse): return user if not user and request.user.is_authenticated(): return HttpResponseRedirect(redirect_value) msg = None if user: if getattr(user, 'is_active', True): # catch is_new flag before login() might reset the instance is_new = getattr(user, 'is_new', False) login(request, user) # user.social_user is the used UserSocialAuth instance defined # in authenticate process social_user = user.social_user if redirect_value: request.session[REDIRECT_FIELD_NAME] = redirect_value or \ DEFAULT_REDIRECT if setting('SOCIAL_AUTH_SESSION_EXPIRATION', True): # Set session expiration date if present and not disabled by # setting. Use last social-auth instance for current provider, # users can associate several accounts with a same provider. expiration = social_user.expiration_datetime() if expiration: try: request.session.set_expiry(expiration) except OverflowError: # Handle django time zone overflow, set default expiry. request.session.set_expiry(None) # store last login backend name in session request.session['social_auth_last_login_backend'] = \ social_user.provider # Remove possible redirect URL from session, if this is a new # account, send him to the new-users-page if defined. new_user_redirect = backend_setting( backend, 'SOCIAL_AUTH_NEW_USER_REDIRECT_URL') if new_user_redirect and is_new: url = new_user_redirect else: url = redirect_value or \ backend_setting(backend, 'SOCIAL_AUTH_LOGIN_REDIRECT_URL') or \ DEFAULT_REDIRECT else: msg = setting('SOCIAL_AUTH_INACTIVE_USER_MESSAGE', None) url = backend_setting(backend, 'SOCIAL_AUTH_INACTIVE_USER_URL', LOGIN_ERROR_URL) else: msg = setting('LOGIN_ERROR_MESSAGE', None) url = backend_setting(backend, 'LOGIN_ERROR_URL', LOGIN_ERROR_URL) if msg: messages.error(request, msg) if redirect_value and redirect_value != url: redirect_value = quote(redirect_value) if '?' in url: url += '&%s=%s' % (REDIRECT_FIELD_NAME, redirect_value) else: url += '?%s=%s' % (REDIRECT_FIELD_NAME, redirect_value) return HttpResponseRedirect(url)
from uuid import uuid4 from social_auth.utils import setting, module_member from social_auth.models import UserSocialAuth slugify = module_member( setting('SOCIAL_AUTH_SLUGIFY_FUNCTION', 'django.template.defaultfilters.slugify')) def get_username(details, user=None, user_exists=UserSocialAuth.simple_user_exists, *args, **kwargs): """Return an username for new user. Return current user username if user was given. """ if user: return {'username': UserSocialAuth.user_username(user)} email_as_username = setting('SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL', False) uuid_length = setting('SOCIAL_AUTH_UUID_LENGTH', 16) do_slugify = setting('SOCIAL_AUTH_SLUGIFY_USERNAMES', False) if email_as_username and details.get('email'): username = details['email'] elif details.get('username'): username = unicode(details['username']) else: username = uuid4().get_hex()
from social_auth.exceptions import AuthTokenRevoked, AuthException from social_auth.utils import setting, log, dsa_urlopen # Vkontakte configuration VK_AUTHORIZATION_URL = 'http://oauth.vk.com/authorize' VK_ACCESS_TOKEN_URL = 'https://oauth.vk.com/access_token' VK_SERVER = 'vk.com' VK_DEFAULT_DATA = [ 'first_name', 'last_name', 'screen_name', 'nickname', 'photo' ] VKONTAKTE_API_URL = 'https://api.vkontakte.ru/method/' VKONTAKTE_SERVER_API_URL = 'http://api.vkontakte.ru/api.php' VKONTAKTE_API_VERSION = '3.0' USE_APP_AUTH = setting('VKONTAKTE_APP_AUTH', False) LOCAL_HTML = setting('VKONTAKTE_LOCAL_HTML', 'vkontakte.html') class VKontakteBackend(SocialAuthBackend): """VKontakte OpenAPI authentication backend""" name = 'vkontakte' def get_user_id(self, details, response): """Return user unique id provided by VKontakte""" return response['id'] def get_user_details(self, response): """Return user details from VKontakte request""" nickname = response.get('nickname') or response['id'] if isinstance(nickname, (
from django.db import models from django.contrib.auth import authenticate from django.contrib.auth.backends import ModelBackend from django.utils import simplejson from django.utils.importlib import import_module from social_auth.utils import setting, log, model_to_ctype, ctype_to_model, \ clean_partial_pipeline from social_auth.store import DjangoOpenIDStore from social_auth.backends.exceptions import StopPipeline, AuthException, \ AuthFailed, AuthCanceled, \ AuthUnknownError, AuthTokenError, \ AuthMissingParameter if setting('SOCIAL_AUTH_USER_MODEL'): User = models.get_model(*setting('SOCIAL_AUTH_USER_MODEL').rsplit('.', 1)) else: from django.contrib.auth.models import User # OpenID configuration OLD_AX_ATTRS = [('http://schema.openid.net/contact/email', 'old_email'), ('http://schema.openid.net/namePerson', 'old_fullname'), ('http://schema.openid.net/namePerson/friendly', 'old_nickname')] AX_SCHEMA_ATTRS = [ # Request both the full name and first/last components since some # providers offer one but not the other. ('http://axschema.org/contact/email', 'email'), ('http://axschema.org/namePerson', 'fullname'), ('http://axschema.org/namePerson/first', 'first_name'),
def get_api_url(self): return setting('YANDEX_OAUTH2_API_URL')