Exemple #1
0
def signup(request,
           template_name='im/signup.html',
           on_success='index',
           extra_context=None,
           activation_backend=None):
    """
    Allows a user to create a local account.

    In case of GET request renders a form for entering the user information.
    In case of POST handles the signup.

    The user activation will be delegated to the backend specified by the
    ``activation_backend`` keyword argument if present, otherwise to the
    ``astakos.im.activation_backends.InvitationBackend`` if
    settings.ASTAKOS_INVITATIONS_ENABLED is True or
    ``astakos.im.activation_backends.SimpleBackend`` if not (see
    activation_backends);

    Upon successful user creation, if ``next`` url parameter is present the
    user is redirected there otherwise renders the same page with a success
    message.

    On unsuccessful creation, renders ``template_name`` with an error message.

    **Arguments**

    ``template_name``
        A custom template to render. This is optional;
        if not specified, this will default to ``im/signup.html``.

    ``extra_context``
        An dictionary of variables to add to the template context.

    ``on_success``
        Resolvable view name to redirect on registration success.

    **Template:**

    im/signup.html or ``template_name`` keyword argument.
    """
    extra_context = extra_context or {}
    if request.user.is_authenticated():
        logger.info("%s already signed in, redirect to index",
                    request.user.log_display)
        return HttpResponseRedirect(reverse('index'))

    provider = get_query(request).get('provider', 'local')
    try:
        auth.get_provider(provider)
    except auth.InvalidProvider, e:
        messages.error(request, e.message)
        return HttpResponseRedirect(reverse("signup"))
Exemple #2
0
def signup(request, template_name='im/signup.html', on_success='index',
           extra_context=None, activation_backend=None):
    """
    Allows a user to create a local account.

    In case of GET request renders a form for entering the user information.
    In case of POST handles the signup.

    The user activation will be delegated to the backend specified by the
    ``activation_backend`` keyword argument if present, otherwise to the
    ``astakos.im.activation_backends.InvitationBackend`` if
    settings.ASTAKOS_INVITATIONS_ENABLED is True or
    ``astakos.im.activation_backends.SimpleBackend`` if not (see
    activation_backends);

    Upon successful user creation, if ``next`` url parameter is present the
    user is redirected there otherwise renders the same page with a success
    message.

    On unsuccessful creation, renders ``template_name`` with an error message.

    **Arguments**

    ``template_name``
        A custom template to render. This is optional;
        if not specified, this will default to ``im/signup.html``.

    ``extra_context``
        An dictionary of variables to add to the template context.

    ``on_success``
        Resolvable view name to redirect on registration success.

    **Template:**

    im/signup.html or ``template_name`` keyword argument.
    """
    extra_context = extra_context or {}
    if request.user.is_authenticated():
        logger.info("%s already signed in, redirect to index",
                    request.user.log_display)
        return HttpResponseRedirect(reverse('index'))

    provider = get_query(request).get('provider', 'local')
    try:
        auth.get_provider(provider)
    except auth.InvalidProvider, e:
        messages.error(request, e.message)
        return HttpResponseRedirect(reverse("signup"))
Exemple #3
0
def login(request, on_failure='im/login.html'):
    """
    on_failure: the template name to render on login failure
    """
    if request.method == 'GET':
        return HttpResponseRedirect(reverse('login'))

    was_limited = getattr(request, 'limited', False)
    form = LoginForm(data=request.POST,
                     was_limited=was_limited,
                     request=request)
    next = get_query(request).get('next', '')
    third_party_token = get_query(request).get('key', False)
    provider = auth.get_provider('local')

    if not form.is_valid():
        if third_party_token:
            messages.info(request, provider.get_login_to_add_msg)

        return render_to_response(on_failure, {
            'login_form': form,
            'next': next,
            'key': third_party_token
        },
                                  context_instance=RequestContext(request))

    # get the user from the cache
    user = form.user_cache
    provider = auth.get_provider('local', user)

    if not provider.get_login_policy:
        message = provider.get_login_disabled_msg
        messages.error(request, message)
        return HttpResponseRedirect(reverse('login'))

    message = None
    if not user:
        message = provider.get_authentication_failed_msg
    elif not user.is_active:
        message = user.get_inactive_message('local')

    elif not user.has_auth_provider('local'):
        # valid user logged in with no auth providers set, add local provider
        # and let him log in
        if not user.get_available_auth_providers():
            user.add_auth_provider('local')
        else:
            message = _(astakos_messages.NO_LOCAL_AUTH)

    if message:
        messages.error(request, message)
        return render_to_response(on_failure, {'login_form': form},
                                  context_instance=RequestContext(request))

    response = prepare_response(request, user, next)
    if third_party_token:
        # use requests to assign the account he just authenticated with with
        # a third party provider account
        try:
            request.user.add_pending_auth_provider(third_party_token)
        except PendingThirdPartyUser.DoesNotExist:
            provider = auth.get_provider('local', request.user)
            messages.error(request, provider.get_add_failed_msg)

    provider = user.get_auth_provider('local')
    messages.success(request, provider.get_login_success_msg)
    response.set_cookie('astakos_last_login_method', 'local')
    return response
Exemple #4
0
def next(request):
    return {'next': get_query(request).get('next', '')}
Exemple #5
0
def get_pending_key(request):
    third_party_token = get_query(request).get(
        'key', request.session.get('pending_key', False))
    if 'pending_key' in request.session:
        del request.session['pending_key']
    return third_party_token
Exemple #6
0
def signup(request,
           template_name='im/signup.html',
           on_success='index',
           extra_context=None,
           activation_backend=None):
    """
    Allows a user to create a local account.

    In case of GET request renders a form for entering the user information.
    In case of POST handles the signup.

    The user activation will be delegated to the backend specified by the
    ``activation_backend`` keyword argument if present, otherwise to the
    ``astakos.im.activation_backends.InvitationBackend`` if
    settings.ASTAKOS_INVITATIONS_ENABLED is True or
    ``astakos.im.activation_backends.SimpleBackend`` if not (see
    activation_backends);

    Upon successful user creation, if ``next`` url parameter is present the
    user is redirected there otherwise renders the same page with a success
    message.

    On unsuccessful creation, renders ``template_name`` with an error message.

    **Arguments**

    ``template_name``
        A custom template to render. This is optional;
        if not specified, this will default to ``im/signup.html``.

    ``extra_context``
        An dictionary of variables to add to the template context.

    ``on_success``
        Resolvable view name to redirect on registration success.

    **Template:**

    im/signup.html or ``template_name`` keyword argument.
    """
    extra_context = extra_context or {}
    if request.user.is_authenticated():
        logger.info("%s already signed in, redirect to index",
                    request.user.log_display)
        transaction.rollback()
        return HttpResponseRedirect(reverse('index'))

    provider = get_query(request).get('provider', 'local')
    if not auth.get_provider(provider).get_create_policy:
        logger.error("%s provider not available for signup", provider)
        transaction.rollback()
        raise PermissionDenied

    instance = None

    # user registered using third party provider
    third_party_token = request.REQUEST.get('third_party_token', None)
    unverified = None
    if third_party_token:
        # retreive third party entry. This was created right after the initial
        # third party provider handshake.
        pending = get_object_or_404(PendingThirdPartyUser,
                                    token=third_party_token)

        provider = pending.provider

        # clone third party instance into the corresponding AstakosUser
        instance = pending.get_user_instance()
        get_unverified = AstakosUserAuthProvider.objects.unverified

        # check existing unverified entries
        unverified = get_unverified(pending.provider,
                                    identifier=pending.third_party_identifier)

        if unverified and request.method == 'GET':
            messages.warning(request, unverified.get_pending_registration_msg)
            if unverified.user.moderated:
                messages.warning(request,
                                 unverified.get_pending_resend_activation_msg)
            else:
                messages.warning(request,
                                 unverified.get_pending_moderation_msg)

    # prepare activation backend based on current request
    if not activation_backend:
        activation_backend = activation_backends.get_backend()

    form_kwargs = {'instance': instance, 'request': request}
    if third_party_token:
        form_kwargs['third_party_token'] = third_party_token

    form = activation_backend.get_signup_form(provider, None, **form_kwargs)

    if request.method == 'POST':
        form = activation_backend.get_signup_form(provider, request.POST,
                                                  **form_kwargs)

        if form.is_valid():
            commited = False
            try:
                user = form.save(commit=False)

                # delete previously unverified accounts
                if AstakosUser.objects.user_exists(user.email):
                    AstakosUser.objects.get_by_identifier(user.email).delete()

                # store_user so that user auth providers get initialized
                form.store_user(user, request)
                result = activation_backend.handle_registration(user)
                if result.status == \
                        activation_backend.Result.PENDING_MODERATION:
                    # user should be warned that his account is not active yet
                    status = messages.WARNING
                else:
                    status = messages.SUCCESS
                message = result.message
                activation_backend.send_result_notifications(result, user)

                # commit user entry
                transaction.commit()
                # commited flag
                # in case an exception get raised from this point
                commited = True

                if user and user.is_active:
                    # activation backend directly activated the user
                    # log him in
                    next = request.POST.get('next', '')
                    response = prepare_response(request, user, next=next)
                    return response

                messages.add_message(request, status, message)
                return HttpResponseRedirect(reverse(on_success))
            except Exception, e:
                if not commited:
                    transaction.rollback()
                raise
Exemple #7
0
def login(request,
          template_name="im/login.html",
          on_failure='im/login.html',
          signup_template="/im/third_party_check_local.html",
          extra_context=None):
    """
    on_failure: the template name to render on login failure
    """
    if request.method == 'GET':
        return handle_get_to_login_view(request,
                                        primary_provider=LDAP_PROVIDER,
                                        login_form=LDAPLoginForm(request),
                                        template_name=template_name,
                                        extra_context=extra_context)

    # 'limited' attribute is used by recapatcha
    was_limited = getattr(request, 'limited', False)
    next = get_query(request).get('next', '')
    third_party_token = get_query(request).get('key', False)

    form = LDAPLoginForm(data=request.POST,
                         was_limited=was_limited,
                         request=request)
    provider = LDAP_PROVIDER

    if not form.is_valid():
        if third_party_token:
            messages.info(request, provider.get_login_to_add_msg)

        return render_to_response(on_failure, {
            'login_form': form,
            'next': next,
            'key': third_party_token
        },
                                  context_instance=get_context(
                                      request, primary_provider=LDAP_PROVIDER))

    # get the user from the cache
    user = form.ldap_user_cache
    provider = auth.get_provider('ldap', user)

    affiliation = 'LDAP'
    provider_info = dict(user.ldap_user.attrs)
    try:
        user_info = populate_user_attributes(provider, provider_info)
        user_id = user_info.pop('identifier')
    except (ValueError, KeyError):
        logger.exception(
            "Failed to map attributes from LDAP provider."
            " Provider attributes: %s", provider_info)
        msg = 'Invalid LDAP response. Please contact support.'
        messages.error(request, msg)
        return HttpResponseRedirect(reverse('login'))

    provider_info = dict([(k, smart_unicode(v, errors="ignore"))
                          for k, v in provider_info.items()
                          if k in provider.get_provider_info_attributes()])

    user_info['affiliation'] = affiliation

    if hasattr(user, 'group_names') and provider.get_policy('mirror_groups'):
        groups = [
            Group.objects.get_or_create(name=group_name)[0]
            for group_name in user.group_names
        ]
        user_info['groups'] = groups

    try:
        return handle_third_party_login(request,
                                        provider_module="ldap",
                                        identifier=user_id,
                                        provider_info=provider_info,
                                        affiliation=affiliation,
                                        user_info=user_info)
    except AstakosUser.DoesNotExist:
        third_party_key = get_pending_key(request)
        return handle_third_party_signup(request, user_id, 'ldap',
                                         third_party_key, provider_info,
                                         user_info, signup_template,
                                         extra_context)
Exemple #8
0
def login(request, template_name="im/login.html", on_failure='im/login.html',
          extra_context=None):
    """
    on_failure: the template name to render on login failure
    """
    if request.method == 'GET':
        extra_context = extra_context or {}

        third_party_token = request.GET.get('key', False)
        if third_party_token:
            messages.info(request, astakos_messages.AUTH_PROVIDER_LOGIN_TO_ADD)

        if request.user.is_authenticated():
            return HttpResponseRedirect(reverse('landing'))

        extra_context["primary_provider"] = LOCAL_PROVIDER

        return render_response(
            template_name,
            login_form=LoginForm(request=request),
            context_instance=get_context(request, extra_context)
        )

    was_limited = getattr(request, 'limited', False)
    form = LoginForm(data=request.POST,
                     was_limited=was_limited,
                     request=request)
    next = get_query(request).get('next', '')
    third_party_token = get_query(request).get('key', False)
    provider = auth.get_provider('local')

    if not form.is_valid():
        if third_party_token:
            messages.info(request, provider.get_login_to_add_msg)

        return render_to_response(
            on_failure,
            {'login_form': form,
             'next': next,
             'key': third_party_token},
            context_instance=get_context(request,
                                         primary_provider=LOCAL_PROVIDER))

    # get the user from the cache
    user = form.user_cache
    provider = auth.get_provider('local', user)

    if not provider.get_login_policy:
        message = provider.get_login_disabled_msg
        messages.error(request, message)
        return HttpResponseRedirect(reverse('login'))

    message = None
    if not user:
        message = provider.get_authentication_failed_msg
    elif not user.is_active:
        message = user.get_inactive_message('local')

    elif not user.has_auth_provider('local'):
        # valid user logged in with no auth providers set, add local provider
        # and let him log in
        if not user.get_available_auth_providers():
            user.add_auth_provider('local')
        else:
            message = _(astakos_messages.NO_LOCAL_AUTH)

    if message:
        messages.error(request, message)
        return render_to_response(on_failure,
                                  {'login_form': form},
                                  context_instance=RequestContext(request))

    response = prepare_response(request, user, next)
    if third_party_token:
        # use requests to assign the account he just authenticated with with
        # a third party provider account
        try:
            request.user.add_pending_auth_provider(third_party_token)
        except PendingThirdPartyUser.DoesNotExist:
            provider = auth.get_provider('local', request.user)
            messages.error(request, provider.get_add_failed_msg)

    provider = user.get_auth_provider('local')
    messages.success(request, provider.get_login_success_msg)
    response.set_cookie('astakos_last_login_method', 'local')
    provider.update_last_login_at()

    return response
Exemple #9
0
def get_pending_key(request):
    third_party_token = get_query(request).get(
        'key', request.session.get('pending_key', False))
    if 'pending_key' in request.session:
        del request.session['pending_key']
    return third_party_token
Exemple #10
0
def next(request):
    return {'next': get_query(request).get('next', '')}
Exemple #11
0
def signup(request, template_name='im/signup.html', on_success='index',
           extra_context=None, activation_backend=None):
    """
    Allows a user to create a local account.

    In case of GET request renders a form for entering the user information.
    In case of POST handles the signup.

    The user activation will be delegated to the backend specified by the
    ``activation_backend`` keyword argument if present, otherwise to the
    ``astakos.im.activation_backends.InvitationBackend`` if
    settings.ASTAKOS_INVITATIONS_ENABLED is True or
    ``astakos.im.activation_backends.SimpleBackend`` if not (see
    activation_backends);

    Upon successful user creation, if ``next`` url parameter is present the
    user is redirected there otherwise renders the same page with a success
    message.

    On unsuccessful creation, renders ``template_name`` with an error message.

    **Arguments**

    ``template_name``
        A custom template to render. This is optional;
        if not specified, this will default to ``im/signup.html``.

    ``extra_context``
        An dictionary of variables to add to the template context.

    ``on_success``
        Resolvable view name to redirect on registration success.

    **Template:**

    im/signup.html or ``template_name`` keyword argument.
    """
    extra_context = extra_context or {}
    if request.user.is_authenticated():
        logger.info("%s already signed in, redirect to index",
                    request.user.log_display)
        return HttpResponseRedirect(reverse('index'))

    provider = get_query(request).get('provider', 'local')
    if not auth.get_provider(provider).get_create_policy:
        logger.error("%s provider not available for signup", provider)
        raise PermissionDenied

    instance = None

    # user registered using third party provider
    third_party_token = request.REQUEST.get('third_party_token', None)
    unverified = None
    if third_party_token:
        # retreive third party entry. This was created right after the initial
        # third party provider handshake.
        pending = get_object_or_404(PendingThirdPartyUser,
                                    token=third_party_token)

        provider = pending.provider

        # clone third party instance into the corresponding AstakosUser
        instance = pending.get_user_instance()
        get_unverified = AstakosUserAuthProvider.objects.unverified

        # check existing unverified entries
        unverified = get_unverified(pending.provider,
                                    identifier=pending.third_party_identifier)

        if unverified and request.method == 'GET':
            messages.warning(request, unverified.get_pending_registration_msg)
            if unverified.user.moderated:
                messages.warning(request,
                                 unverified.get_pending_resend_activation_msg)
            else:
                messages.warning(request,
                                 unverified.get_pending_moderation_msg)

    # prepare activation backend based on current request
    if not activation_backend:
        activation_backend = activation_backends.get_backend()

    form_kwargs = {'instance': instance, 'request': request}
    if third_party_token:
        form_kwargs['third_party_token'] = third_party_token

    form = activation_backend.get_signup_form(
        provider, None, **form_kwargs)

    if request.method == 'POST':
        form = activation_backend.get_signup_form(
            provider,
            request.POST,
            **form_kwargs)

        if form.is_valid():
            user = form.save(commit=False)

            # delete previously unverified accounts
            if AstakosUser.objects.user_exists(user.email):
                AstakosUser.objects.get_by_identifier(user.email).delete()

            # store_user so that user auth providers get initialized
            form.store_user(user, request)
            result = activation_backend.handle_registration(user)
            if result.status == \
                    activation_backend.Result.PENDING_MODERATION:
                # user should be warned that his account is not active yet
                status = messages.WARNING
            else:
                status = messages.SUCCESS
            message = result.message
            activation_backend.send_result_notifications(result, user)

            # commit user entry
            transaction.commit()

            if user and user.is_active:
                # activation backend directly activated the user
                # log him in
                next = request.POST.get('next', '')
                response = prepare_response(request, user, next=next)
                return response

            messages.add_message(request, status, message)
            return HttpResponseRedirect(reverse(on_success))

    return render_response(template_name,
                           signup_form=form,
                           third_party_token=third_party_token,
                           provider=provider,
                           context_instance=get_context(request, extra_context))
Exemple #12
0
def login(request, template_name="im/login.html", on_failure='im/login.html',
          signup_template="/im/third_party_check_local.html",
          extra_context=None):
    """
    on_failure: the template name to render on login failure
    """
    if request.method == 'GET':
        return handle_get_to_login_view(request,
                                        primary_provider=LDAP_PROVIDER,
                                        login_form=LDAPLoginForm(request),
                                        template_name=template_name,
                                        extra_context=extra_context)

    # 'limited' attribute is used by recapatcha
    was_limited = getattr(request, 'limited', False)
    next = get_query(request).get('next', '')
    third_party_token = get_query(request).get('key', False)

    form = LDAPLoginForm(data=request.POST,
                         was_limited=was_limited,
                         request=request)
    provider = LDAP_PROVIDER

    if not form.is_valid():
        if third_party_token:
            messages.info(request, provider.get_login_to_add_msg)

        return render_to_response(
            on_failure,
            {'login_form': form,
             'next': next,
             'key': third_party_token},
            context_instance=get_context(request,
                                         primary_provider=LDAP_PROVIDER))

    # get the user from the cache
    user = form.ldap_user_cache
    provider = auth.get_provider('ldap', user)

    affiliation = 'LDAP'
    provider_info = dict(user.ldap_user.attrs)
    try:
        user_info = populate_user_attributes(provider, provider_info)
        user_id = user_info.pop('identifier')
    except (ValueError, KeyError):
        logger.exception("Failed to map attributes from LDAP provider."
                         " Provider attributes: %s", provider_info)
        msg = 'Invalid LDAP response. Please contact support.'
        messages.error(request, msg)
        return HttpResponseRedirect(reverse('login'))

    provider_info = dict([(k, smart_unicode(v, errors="ignore"))
                          for k, v in provider_info.items()
                          if k in provider.get_provider_info_attributes()])

    user_info['affiliation'] = affiliation

    if hasattr(user, 'group_names') and provider.get_policy('mirror_groups'):
        groups = [Group.objects.get_or_create(name=group_name)[0]
                  for group_name in user.group_names]
        user_info['groups'] = groups

    try:
        return handle_third_party_login(request, provider_module="ldap",
                                        identifier=user_id,
                                        provider_info=provider_info,
                                        affiliation=affiliation,
                                        user_info=user_info)
    except AstakosUser.DoesNotExist:
        third_party_key = get_pending_key(request)
        return handle_third_party_signup(request, user_id, 'ldap',
                                         third_party_key,
                                         provider_info,
                                         user_info,
                                         signup_template,
                                         extra_context)