示例#1
0
def get_username(strategy, details, backend, user=None, *args, **kwargs):
    """
    Copy of social_core.pipeline.user.get_username with additional logging and case insensitive username checks.
    """
    if 'username' not in backend.setting('USER_FIELDS', USER_FIELDS):
        return
    storage = strategy.storage

    if not user:
        email_as_username = strategy.setting('USERNAME_IS_FULL_EMAIL', False)
        uuid_length = strategy.setting('UUID_LENGTH', 16)
        max_length = storage.user.username_max_length()
        do_slugify = strategy.setting('SLUGIFY_USERNAMES', False)
        do_clean = strategy.setting('CLEAN_USERNAMES', True)

        if do_clean:
            override_clean = strategy.setting('CLEAN_USERNAME_FUNCTION')
            if override_clean:
                clean_func = module_member(override_clean)
            else:
                clean_func = storage.user.clean_username
        else:
            clean_func = lambda val: val

        if do_slugify:
            override_slug = strategy.setting('SLUGIFY_FUNCTION')
            if override_slug:
                slug_func = module_member(override_slug)
            else:
                slug_func = slugify
        else:
            slug_func = lambda val: val

        if email_as_username and details.get('email'):
            username = details['email']
        elif details.get('username'):
            username = details['username']
        else:
            username = uuid4().hex

        short_username = (username[:max_length - uuid_length]
                          if max_length is not None
                          else username)
        final_username = slug_func(clean_func(username[:max_length]))

        # 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.
        # The final_username may be empty and will skip the loop.
        # We are using our own version of user_exists to avoid possible case sensitivity issues.
        while not final_username or user_exists({'username': final_username}):
            # These log statements are here for debugging purposes and should be removed when ENT-1500 is resolved.
            logger.info(u'Username %s is either empty or already in use, generating a new username!', final_username)
            username = short_username + uuid4().hex[:uuid_length]
            final_username = slug_func(clean_func(username[:max_length]))
            logger.info(u'Generated username %s.', final_username)
    else:
        final_username = storage.user.get_username(user)
    return {'username': final_username}
    def send_email_validation(self, backend, email, force_update=False, partial_token=None):
        from social_core.utils import module_member

        email_validation = self.setting('EMAIL_VALIDATION_FUNCTION')
        send_email = module_member(email_validation)
        # remove all codes with this email before creating new one
        CustomCode.objects.filter(email=email).delete()
        code = self.storage.code.make_code(email)
        user = self.request.user
        # store user data in code. We will use it after confirmation email link click.
        fields_to_store = ('first_name', 'last_name', 'password', 'next')
        if force_update:
            # when users change their email they should be redirected to page they come from
            # now it is /accounts/ url
            post_data = self.request.POST.copy()
            post_data['next'] = post_data.get('next', self.request.path)
            self.request.POST = post_data
        for field in fields_to_store:
            f_val = self.request.POST.get(field)
            # hack: to not override built-in func `next` in model, it is saved under 'next_page' filedname
            if field == 'next':
                field = 'next_page'
            setattr(
                code, field,
                f_val
            )
        if user and user.is_authenticated():
            code.force_update = force_update
            code.user_id = user.id
        code.save()
        self.request.session['cc_id'] = code.id
        send_email(self, backend, code, partial_token)
        return code
示例#3
0
def get_login_providers(request, short=False):
    """
    Returns a list of available login providers based on the
    AUTHENTICATION_BACKENDS setting. Each provider is represented as a
    dictionary containing the backend name, name of required parameter if
    required and its verbose name.
    """
    def extract_backend_data(klass):
        """
        Helper function which extracts information useful for use in
        templates from SocialAuth subclasses and returns it as a
        dictionary.
        """
        return {
            'name': klass.name,
            'required_field': klass.REQUIRED_FIELD_NAME,
            'required_field_verbose': klass.REQUIRED_FIELD_VERBOSE_NAME,
        }

    backends = (module_member(auth_backend) for auth_backend in setting('AUTHENTICATION_BACKENDS'))
    providers = [extract_backend_data(backend) for backend in backends if issubclass(backend, BaseAuth)]
    if short:
        return providers[:setting('AUTHENTICATION_PROVIDERS_BRIEF',
                                  DEFAULT_AUTHENTICATION_PROVIDERS_BRIEF)]
    return providers
示例#4
0
    def setUp(self):
        HTTPretty.enable()
        Backend = module_member(self.backend_path)
        self.strategy = views.load_strategy()
        self.backend = Backend(self.strategy, redirect_uri=self.complete_url)
        self.name = self.backend.name.upper().replace('-', '_')
        self.complete_url = self.strategy.build_absolute_uri(
            self.raw_complete_url.format(self.backend.name)
        )
        backends = (self.backend_path, )
        load_backends(backends, force_load=True)

        user_data_body = json.loads(self.user_data_body)
        self.email = '*****@*****.**'
        user_data_body['email'] = self.email
        self.user_data_body = json.dumps(user_data_body)

        self.do_rest_login()
示例#5
0
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base

from social_core.utils import setting_name, module_member
from social_sqlalchemy.storage import SQLAlchemyUserMixin, \
                                      SQLAlchemyAssociationMixin, \
                                      SQLAlchemyNonceMixin, \
                                      SQLAlchemyPartialMixin, \
                                      BaseSQLAlchemyStorage

SocialBase = declarative_base()

DB_SESSION_ATTR = cherrypy.config.get(setting_name('DB_SESSION_ATTR'), 'db')
UID_LENGTH = cherrypy.config.get(setting_name('UID_LENGTH'), 255)
User = module_member(cherrypy.config[setting_name('USER_MODEL')])


class CherryPySocialBase(object):
    @classmethod
    def _session(cls):
        return getattr(cherrypy.request, DB_SESSION_ATTR)


class UserSocialAuth(CherryPySocialBase, SQLAlchemyUserMixin, SocialBase):
    """Social Auth association model"""
    uid = Column(String(UID_LENGTH))
    user_id = Column(Integer, ForeignKey(User.id), nullable=False, index=True)
    user = relationship(User, backref='social_auth')

    @classmethod
示例#6
0
 def wrapper(request, *args, **kwargs):
     is_logged_in = module_member(
         request.backend.setting('LOGGEDIN_FUNCTION'))
     if not is_logged_in(request):
         raise HTTPForbidden('Not authorized user')
     return func(request, *args, **kwargs)
示例#7
0
from django.conf import settings
from django.core.urlresolvers import reverse
from django.http import Http404

from social_core.utils import setting_name, module_member, get_strategy
from social_core.exceptions import MissingBackend
from social_core.backends.utils import get_backend


BACKENDS = settings.AUTHENTICATION_BACKENDS
STRATEGY = getattr(settings, setting_name('STRATEGY'),
                   'social_django.strategy.DjangoStrategy')
STORAGE = getattr(settings, setting_name('STORAGE'),
                  'social_django.models.DjangoStorage')
Strategy = module_member(STRATEGY)
Storage = module_member(STORAGE)


def load_strategy(request=None):
    return get_strategy(STRATEGY, STORAGE, request)


def load_backend(strategy, name, redirect_uri):
    Backend = get_backend(BACKENDS, name)
    return Backend(strategy, redirect_uri)


def psa(redirect_uri=None, load_strategy=load_strategy):
    def decorator(func):
        @wraps(func)
示例#8
0
def _load_backend_classes(base_class=BaseAuth):
    """ Load the list of python-social-auth backend classes from Django settings """
    for class_path in settings.AUTHENTICATION_BACKENDS:
        auth_class = module_member(class_path)
        if issubclass(auth_class, base_class):
            yield auth_class
示例#9
0
 def _get_helper(self, name, do_import=False):
     this_config = self.config.get(setting_name(name),
                                   DEFAULTS.get(name, None))
     return do_import and module_member(this_config) or this_config
示例#10
0
def get_username(strategy, details, backend, user=None, *args, **kwargs):  # lint-amnesty, pylint: disable=keyword-arg-before-vararg
    """
    Copy of social_core.pipeline.user.get_username to achieve
    1. additional logging
    2. case insensitive username checks
    3. enforce same maximum and minimum length restrictions we have in `user_api/accounts`
    """
    if 'username' not in backend.setting('USER_FIELDS', USER_FIELDS):
        return
    storage = strategy.storage

    if not user:
        email_as_username = strategy.setting('USERNAME_IS_FULL_EMAIL', False)
        uuid_length = strategy.setting('UUID_LENGTH', 16)
        min_length = strategy.setting('USERNAME_MIN_LENGTH', accounts.USERNAME_MIN_LENGTH)
        max_length = strategy.setting('USERNAME_MAX_LENGTH', accounts.USERNAME_MAX_LENGTH)
        do_slugify = strategy.setting('SLUGIFY_USERNAMES', False)
        do_clean = strategy.setting('CLEAN_USERNAMES', True)

        if do_clean:
            override_clean = strategy.setting('CLEAN_USERNAME_FUNCTION')
            if override_clean:
                clean_func = module_member(override_clean)
            else:
                clean_func = storage.user.clean_username
        else:
            clean_func = lambda val: val

        if do_slugify:
            override_slug = strategy.setting('SLUGIFY_FUNCTION')
            if override_slug:
                slug_func = module_member(override_slug)
            else:
                slug_func = slugify
        else:
            slug_func = lambda val: val

        if email_as_username and details.get('email'):
            username = details['email']
        elif details.get('username'):
            username = details['username']
        else:
            username = uuid4().hex

        short_username = (username[:max_length - uuid_length]
                          if max_length is not None
                          else username)
        final_username = slug_func(clean_func(username[:max_length]))

        # 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.
        # The final_username may be empty and will skip the loop.
        # We are using our own version of user_exists to avoid possible case sensitivity issues.
        while not final_username or len(final_username) < min_length or user_exists({'username': final_username}):
            username = short_username + uuid4().hex[:uuid_length]
            final_username = slug_func(clean_func(username[:max_length]))
            logger.info('[THIRD_PARTY_AUTH] New username generated. Username: {username}'.format(
                username=final_username))
    else:
        final_username = storage.user.get_username(user)
    return {'username': final_username}
示例#11
0
from django.conf import settings
from django.core.urlresolvers import reverse
from django.http import Http404

from social_core.utils import setting_name, module_member, get_strategy, \
                              set_current_strategy_getter
from social_core.exceptions import MissingBackend
from social_core.backends.utils import get_backend

BACKENDS = settings.AUTHENTICATION_BACKENDS
STRATEGY = getattr(settings, setting_name('STRATEGY'),
                   'social_django.strategy.DjangoStrategy')
STORAGE = getattr(settings, setting_name('STORAGE'),
                  'social_django.models.DjangoStorage')
Strategy = module_member(STRATEGY)
Storage = module_member(STORAGE)


def load_strategy(request=None):
    return get_strategy(STRATEGY, STORAGE, request)


def load_backend(strategy, name, redirect_uri):
    Backend = get_backend(BACKENDS, name)
    return Backend(strategy, redirect_uri)


def psa(redirect_uri=None, load_strategy=load_strategy):
    def decorator(func):
        @wraps(func)
示例#12
0
def _load_backend_classes(base_class=BaseAuth):
    """ Load the list of python-social-auth backend classes from Django settings """
    for class_path in settings.AUTHENTICATION_BACKENDS:
        auth_class = module_member(class_path)
        if issubclass(auth_class, base_class):
            yield auth_class
示例#13
0
def get_strategy(strategy, storage, *args, **kwargs):
    strategy = module_member(strategy)
    return strategy(request=args[0], *args, **kwargs)
示例#14
0
def get_or_create_user(strategy, details, backend, user=None, *args, **kwargs):
    if 'username' not in backend.setting('USER_FIELDS', USER_FIELDS):
        return
    storage = strategy.storage

    if not user:
        email_as_username = strategy.setting('USERNAME_IS_FULL_EMAIL', False)
        uuid_length = strategy.setting('UUID_LENGTH', 16)
        max_length = storage.user.username_max_length()
        do_slugify = strategy.setting('SLUGIFY_USERNAMES', False)
        do_clean = strategy.setting('CLEAN_USERNAMES', True)

        if do_clean:
            override_clean = strategy.setting('CLEAN_USERNAME_FUNCTION')
            if override_clean:
                clean_func = module_member(override_clean)
            else:
                clean_func = storage.user.clean_username
        else:

            def f(val):
                return val

            clean_func = f

        if do_slugify:
            override_slug = strategy.setting('SLUGIFY_FUNCTION')
            if override_slug:
                slug_func = module_member(override_slug)
            else:
                slug_func = slugify
        else:

            def f(val):
                return val

            slug_func = f

        if email_as_username and details.get('email'):
            username = details['email']
        elif details.get('username'):
            username = details['username']
        else:
            username = uuid4().hex

        short_username = (username[:max_length - uuid_length]
                          if max_length is not None else username)
        final_username = slug_func(clean_func(username[:max_length]))

        if not final_username:
            username = short_username + uuid4().hex[:uuid_length]
            final_username = slug_func(clean_func(username[:max_length]))

        fields = dict((name, kwargs.get(name, details.get(name)))
                      for name in backend.setting('USER_FIELDS', USER_FIELDS))
        if not fields:
            return

        user, user_created = User.objects.get_or_create(
            fields, username=final_username)
        return {'is_new': user_created, 'user': user}

    return {'is_new': False}
示例#15
0
 def setUp(self):
     super().setUp()
     Backend = module_member('social_core.backends.github.GithubOAuth2')
     self.strategy = DjangoStrategy(DjangoStorage)
     self.backend = Backend(self.strategy, redirect_uri='/complete/github')
     self.login_redirect_url = '/'
示例#16
0
 def complete(self, backend, *args, **kwargs):
     login = cherrypy.config.get(setting_name('LOGIN_METHOD'))
     do_login = module_member(login) if login else self.do_login
     user = getattr(cherrypy.request, 'user', None)
     return do_complete(self.backend, do_login, user=user, *args, **kwargs)
示例#17
0
def get_helper(name, do_import=False):
    config = web.config.get(setting_name(name), DEFAULTS.get(name, None))
    return do_import and module_member(config) or config
示例#18
0
def get_helper(name, do_import=False):
    config = current_app.config.get(setting_name(name),
                                    DEFAULTS.get(name, None))
    if do_import:
        config = module_member(config)
    return config
示例#19
0
 def _get_helper(self, name, do_import=False):
     this_config = self.config.get(setting_name(name), DEFAULTS.get(name, None))
     return do_import and module_member(this_config) or this_config
示例#20
0
    def get_access_token(self, app, config, extra_data):
        handler = self.context.get('handler')
        request = self.context.get('request')
        strategy = load_strategy(handler, request, config)

        backend_path = config.get('backend_path')
        Backend = module_member(backend_path)

        if not issubclass(Backend, BaseAuth):
            return extra_data.get('access_token')

        backend = Backend(strategy, None)

        refresh_token = extra_data.get('refresh_token') or extra_data.get(
            'access_token')

        expires_on = None
        params_expires_on = extra_data.get('expires_on')
        params_token_updated = extra_data.get('token_updated')
        params_expires_in = extra_data.get('expires') or extra_data.get(
            'expires_in')

        try:
            if params_expires_on:
                expires_on = int(params_expires_on)
            elif params_expires_in and params_token_updated:
                expires_on = int(params_token_updated) + int(params_expires_in)
        except (ValueError, TypeError):
            pass

        try:
            if refresh_token and (not expires_on
                                  or expires_on <= int(time.time())):
                response = backend.refresh_token(token=refresh_token)
                if not backend.EXTRA_DATA or len(backend.EXTRA_DATA) == 0:
                    backend.GET_ALL_EXTRA_DATA = True
                new_extra_data = backend.extra_data(user=None,
                                                    uid=None,
                                                    response=response,
                                                    details={})
                access_token = new_extra_data.get('access_token')

                new_extra_data = {
                    'expires_on': new_extra_data.get('expires_on'),
                    'access_token': new_extra_data.get('access_token'),
                    'expires': new_extra_data.get('expires'),
                    'auth_time': new_extra_data.get('auth_time'),
                    'refresh_token': new_extra_data.get('refresh_token'),
                    'token_updated': int(time.time())
                }

                request = self.context.get('request')
                extra_data_key = '_'.join(['extra_data', app])

                new_extra_data_str = json.dumps(new_extra_data)

                if settings.COOKIE_COMPRESS:
                    new_extra_data_str = compress_data(new_extra_data_str)

                configuration.session_set(request,
                                          extra_data_key,
                                          new_extra_data_str,
                                          secure=not settings.COOKIE_COMPRESS)

                return access_token
        except Exception:
            pass

        return extra_data.get('access_token')