Exemple #1
0
def partial_pipeline_data(backend,
                          user=None,
                          *args,
                          **kwargs):  # pragma: no cover
    """
    Add the session key to a signed base64 encoded signature on the email request.
    """
    data = backend.strategy.request_data()
    if 'signature' in data:
        try:
            signed_details = signing.loads(data['signature'],
                                           key=settings.SECRET_KEY)
            session = Session.objects.get(pk=signed_details['session_key'])
        except BadSignature, Session.DoesNotExist:
            raise InvalidEmail(backend)

        session_details = session.get_decoded()
        backend.strategy.session_set(
            'email_validation_address',
            session_details['email_validation_address'])
        backend.strategy.session_set('next', session_details.get('next'))
        backend.strategy.session_set('partial_pipeline',
                                     session_details['partial_pipeline'])
        backend.strategy.session_set(
            backend.name + '_state',
            session_details.get(backend.name + '_state'))
        backend.strategy.session_set(
            backend.name + 'unauthorized_token_name',
            session_details.get(backend.name + 'unauthorized_token_name'))
Exemple #2
0
def partial_pipeline_data(backend, user=None, *args, **kwargs):  # pragma: no cover
    """
    Add the session key to a signed base64 encoded signature on the email request.
    """
    data = backend.strategy.request_data()
    if 'signature' in data:
        try:
            signed_details = signing.loads(data['signature'], key=settings.SECRET_KEY)
            session = Session.objects.get(pk=signed_details['session_key'])
        except BadSignature as xxx_todo_changeme:
            Session.DoesNotExist = xxx_todo_changeme
            raise InvalidEmail(backend)

        session_details = session.get_decoded()
        backend.strategy.session_set('email_validation_address', session_details['email_validation_address'])
        backend.strategy.session_set('next', session_details.get('next'))
        backend.strategy.session_set('partial_pipeline', session_details['partial_pipeline'])
        backend.strategy.session_set(backend.name + '_state', session_details.get(backend.name + '_state'))
        backend.strategy.session_set(backend.name + 'unauthorized_token_name',
                                     session_details.get(backend.name + 'unauthorized_token_name'))

    partial = backend.strategy.session_get('partial_pipeline', None)
    if partial:
        idx, backend_name, xargs, xkwargs = \
            backend.strategy.partial_from_session(partial)
        if backend_name == backend.name:
            kwargs.setdefault('pipeline_index', idx)
            if user:  # don't update user if it's None
                kwargs.setdefault('user', user)
            kwargs.setdefault('request', backend.strategy.request_data())
            xkwargs.update(kwargs)
            return xargs, xkwargs
        else:
            backend.strategy.clean_partial_pipeline()
Exemple #3
0
def mail_validation(backend, details, is_new=False, *args, **kwargs):
    requires_validation = backend.REQUIRES_EMAIL_VALIDATION or \
                          backend.setting('FORCE_EMAIL_VALIDATION', False)
    send_validation = details.get('email') and \
                      (is_new or backend.setting('PASSWORDLESS', False))
    logging.debug("mail_validation requires_validation=%s send_validation=%s" %
                  (requires_validation, send_validation))
    if requires_validation and send_validation:
        data = backend.strategy.request_data()
        logging.debug("mail_validation data=%s" % (str(data)))
        if 'verification_code' in data:
            logging.debug("no verificatio code")
            backend.strategy.session_pop('email_validation_address')
            if not backend.strategy.validate_email(details['email'],
                                                   data['verification_code']):
                logging.debug("raising invalid email")
                raise InvalidEmail(backend)
        else:
            logging.debug("mail_validation sending ...")
            try:
                backend.strategy.send_email_validation(backend,
                                                       details['email'])
            except Exception, e:
                logging.debug("mail_validation sending %s" % str(e))

            logging.debug("mail_validation setting session ...")
            backend.strategy.session_set('email_validation_address',
                                         details['email'])
            logging.debug("mail_validation redirect=%s" %
                          (backend.strategy.setting('EMAIL_VALIDATION_URL')))
            return backend.strategy.redirect(
                backend.strategy.setting('EMAIL_VALIDATION_URL'))
Exemple #4
0
def partial_pipeline_data(backend, user=None, *args, **kwargs):  # pragma: no cover
    """
    Add the session key to a signed base64 encoded signature on the email request.
    """
    data = backend.strategy.request_data()
    if "signature" in data:
        try:
            signed_details = signing.loads(data["signature"], key=settings.SECRET_KEY)
            session = Session.objects.get(pk=signed_details["session_key"])
        except BadSignature as xxx_todo_changeme:
            Session.DoesNotExist = xxx_todo_changeme  # type: ignore
            raise InvalidEmail(backend)

        session_details = session.get_decoded()
        backend.strategy.session_set("email_validation_address", session_details["email_validation_address"])
        backend.strategy.session_set("next", session_details.get("next"))
        backend.strategy.session_set("partial_pipeline", session_details["partial_pipeline"])
        backend.strategy.session_set(backend.name + "_state", session_details.get(backend.name + "_state"))
        backend.strategy.session_set(
            backend.name + "unauthorized_token_name", session_details.get(backend.name + "unauthorized_token_name")
        )

    partial = backend.strategy.session_get("partial_pipeline", None)
    if partial:
        idx, backend_name, xargs, xkwargs = backend.strategy.partial_from_session(partial)
        if backend_name == backend.name:
            kwargs.setdefault("pipeline_index", idx)
            if user:  # don't update user if it's None
                kwargs.setdefault("user", user)
            kwargs.setdefault("request", backend.strategy.request_data())
            xkwargs.update(kwargs)
            return xargs, xkwargs
        else:
            backend.strategy.clean_partial_pipeline()
Exemple #5
0
def partial_pipeline_data(backend, user=None, *args, **kwargs):
    """
    Monkey-patch utils.partial_pipeline_data to enable us to retrieve session data by signature key in request.
    This is necessary to allow users to follow a link in an email to validate their account from a different
    browser than the one they were using to sign up for the account, or after they've closed/re-opened said
    browser and potentially flushed their cookies. By adding the session key to a signed base64 encoded signature
    on the email request, we can retrieve the necessary details from our Django session table.
    We fetch only the needed details to complete the pipeline authorization process from the session, to prevent
    nefarious use.
    """
    data = backend.strategy.request_data()
    if 'signature' in data:
        try:
            signed_details = signing.loads(data['signature'],
                                           key=settings.EMAIL_SECRET_KEY)
            session = Session.objects.get(pk=signed_details['session_key'])
        except BadSignature, Session.DoesNotExist:
            raise InvalidEmail(backend)

        session_details = session.get_decoded()
        backend.strategy.session_set(
            'email_validation_address',
            session_details['email_validation_address'])
        backend.strategy.session_set('next', session_details.get('next'))
        backend.strategy.session_set('partial_pipeline',
                                     session_details['partial_pipeline'])
        backend.strategy.session_set(
            backend.name + '_state',
            session_details.get(backend.name + '_state'))
        backend.strategy.session_set(
            backend.name + 'unauthorized_token_name',
            session_details.get(backend.name + 'unauthorized_token_name'))
Exemple #6
0
def mail_validation(strategy, details, user=None, is_new=False,
                    *args, **kwargs):
    if user is None or is_new and details.get('email'):
        data = strategy.request_data()
        if 'code' in data:
            strategy.session_pop('email_validation_address')
            if not strategy.validate_email(details['email'], data['code']):
                raise InvalidEmail(strategy.backend)
        elif strategy.backend.REQUIRES_EMAIL_VALIDATION or \
             strategy.setting('FORCE_EMAIL_VALIDATION', False):
            strategy.send_email_validation(details['email'])
            strategy.session_set('email_validation_address', details['email'])
            return strategy.redirect(strategy.setting('EMAIL_VALIDATION_URL'))
Exemple #7
0
def mail_validation(strategy, details, *args, **kwargs):
    requires_validation = strategy.backend.REQUIRES_EMAIL_VALIDATION or \
                          strategy.setting('FORCE_EMAIL_VALIDATION', False)
    if requires_validation and details.get('email'):
        data = strategy.request_data()
        if 'verification_code' in data:
            strategy.session_pop('email_validation_address')
            if not strategy.validate_email(details['email'],
                                           data['verification_code']):
                raise InvalidEmail(strategy.backend)
        else:
            strategy.send_email_validation(details['email'])
            strategy.session_set('email_validation_address', details['email'])
            return strategy.redirect(strategy.setting('EMAIL_VALIDATION_URL'))
Exemple #8
0
def custom_mail_validation(backend,
                           details,
                           user=None,
                           is_new=False,
                           *args,
                           **kwargs):
    """Email validation pipeline

    Verify email or send email with validation link.
    """
    requires_validation = backend.REQUIRES_EMAIL_VALIDATION or \
        backend.setting('FORCE_EMAIL_VALIDATION', False)
    send_validation = (details.get('email')
                       and (is_new or backend.setting('PASSWORDLESS', False)))

    if requires_validation and send_validation and backend.name == 'email':
        data = backend.strategy.request_data()
        if 'verification_code' in data:
            backend.strategy.session_pop('email_validation_address')
            if not backend.strategy.validate_email(
                    details.get('email'), data.get('verification_code')):
                raise InvalidEmail(backend)
            code = backend.strategy.storage.code.get_code(
                data['verification_code'])
            # This is very straightforward method
            # TODO Need to check current user to avoid unnecessary check
            if code.user_id:
                user_from_code = User.objects.filter(id=code.user_id).first()
                if user_from_code:
                    user = user_from_code
                    _next = backend.strategy.request.session.get('next')
                    logout(backend.strategy.request)
                    user.backend = 'django.contrib.auth.backends.ModelBackend'
                    login(backend.strategy.request, user)
                    backend.strategy.session_set('next', _next)
                    return {'user': user}
        else:
            if user and user.groups.filter(name='Temporary').exists():
                AnonymEmail.objects.get_or_create(
                    user=user,
                    email=details.get('email'),
                    defaults={'date': datetime.now()})
            backend.strategy.send_email_validation(backend,
                                                   details.get('email'))
            backend.strategy.session_set('email_validation_address',
                                         details.get('email'))
            backend.strategy.session_set('next', data.get('next'))
            return backend.strategy.redirect(
                backend.strategy.setting('EMAIL_VALIDATION_URL'))
Exemple #9
0
def mail_validation(backend, details, is_new=False, *args, **kwargs):
    requires_validation = backend.REQUIRES_EMAIL_VALIDATION or \
                          backend.setting('FORCE_EMAIL_VALIDATION', False)
    send_validation = details.get('email') and \
                      (is_new or backend.setting('PASSWORDLESS', False))
    if requires_validation and send_validation:
        data = backend.strategy.request_data()
        if 'verification_code' in data:
            backend.strategy.session_pop('email_validation_address')
            if not backend.strategy.validate_email(details['email'],
                                                   data['verification_code']):
                raise InvalidEmail(backend)
        else:
            backend.strategy.send_email_validation(backend, details['email'])
            backend.strategy.session_set('email_validation_address',
                                         details['email'])
            return backend.strategy.redirect(
                backend.strategy.setting('EMAIL_VALIDATION_URL'))
Exemple #10
0
def verify_email(backend, details, *args, **kwargs):
    if not details['email']:
        raise InvalidEmail(backend)