예제 #1
0
def activate(request,
             greeting_email_template_name='im/welcome_email.txt',
             helpdesk_email_template_name='im/helpdesk_notification.txt'):
    """
    Activates the user identified by the ``auth`` request parameter, sends a
    welcome email and renews the user token.

    The view uses commit_manually decorator in order to ensure the user state
    will be updated only if the email will be send successfully.
    """
    token = request.GET.get('auth')
    next = request.GET.get('next')

    if request.user.is_authenticated():
        message = _(astakos_messages.LOGGED_IN_WARNING)
        messages.error(request, message)
        transaction.rollback()
        return HttpResponseRedirect(reverse('index'))

    try:
        user = AstakosUser.objects.get(verification_code=token)
    except AstakosUser.DoesNotExist:
        transaction.rollback()
        raise Http404

    if user.email_verified:
        message = _(astakos_messages.ACCOUNT_ALREADY_VERIFIED)
        messages.error(request, message)
        return HttpResponseRedirect(reverse('index'))

    try:
        backend = activation_backends.get_backend()
        result = backend.handle_verification(user, token)
        backend.send_result_notifications(result, user)
        next = settings.ACTIVATION_REDIRECT_URL or next
        response = HttpResponseRedirect(reverse('index'))
        if user.is_active:
            response = prepare_response(request, user, next, renew=True)
            messages.success(request, _(result.message))
        else:
            messages.warning(request, _(result.message))
    except Exception:
        transaction.rollback()
        raise
    else:
        transaction.commit()
        return response
예제 #2
0
파일: im.py 프로젝트: salsa-dev/synnefo
def activate(request, greeting_email_template_name='im/welcome_email.txt',
             helpdesk_email_template_name='im/helpdesk_notification.txt'):
    """
    Activates the user identified by the ``auth`` request parameter, sends a
    welcome email and renews the user token.

    The user state will be updated only if the email will be send successfully.
    """
    token = request.GET.get('auth', None)
    next = request.GET.get('next', None)

    if not token:
        raise PermissionDenied

    if request.user.is_authenticated():
        message = _(astakos_messages.LOGGED_IN_WARNING)
        messages.error(request, message)
        return HttpResponseRedirect(reverse('index'))

    try:
        user = AstakosUser.objects.select_for_update().\
            get(verification_code=token)
    except AstakosUser.DoesNotExist:
        messages.error(request, astakos_messages.INVALID_ACTIVATION_KEY)
        return HttpResponseRedirect(reverse('index'))

    if user.email_verified:
        message = _(astakos_messages.ACCOUNT_ALREADY_VERIFIED)
        messages.error(request, message)
        return HttpResponseRedirect(reverse('index'))

    backend = activation_backends.get_backend()
    result = backend.handle_verification(user, token)
    backend.send_result_notifications(result, user)
    next = settings.ACTIVATION_REDIRECT_URL or next or reverse('index')
    if user.is_active:
        response = prepare_response(request, user, next, renew=True)
        messages.success(request, _(result.message))
    else:
        response = HttpResponseRedirect(reverse('index'))
        messages.warning(request, _(result.message))

    return response
예제 #3
0
                    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))

    ldap_login_form = None
    if 'ldap' in settings.IM_MODULES:
        ldap_login_form = LDAPLoginForm(request)

    return render_response(template_name,
                           login_form=ldap_login_form,
                           signup_form=form,
                           third_party_token=third_party_token,
                           provider=provider,
                           context_instance=get_context(
예제 #4
0
파일: local.py 프로젝트: salsa-dev/synnefo
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
예제 #5
0
def handle_third_party_login(request,
                             provider_module,
                             identifier,
                             provider_info=None,
                             affiliation=None,
                             third_party_key=None):

    if not provider_info:
        provider_info = {}

    if not affiliation:
        affiliation = provider_module.title()

    next_redirect = request.GET.get('next',
                                    request.session.get('next_url', None))

    if 'next_url' in request.session:
        del request.session['next_url']

    third_party_request_params = get_third_party_session_params(request)
    from_login = third_party_request_params.get('from_login', False)
    switch_from = third_party_request_params.get('switch_from', False)
    provider_data = {'affiliation': affiliation, 'info': provider_info}

    provider = auth.get_provider(provider_module, request.user, identifier,
                                 **provider_data)

    # an existing user accessed the view
    if request.user.is_authenticated():
        if request.user.has_auth_provider(provider.module,
                                          identifier=identifier):
            return HttpResponseRedirect(reverse('edit_profile'))

        if provider.verified_exists():
            provider.log("add failed (identifier exists to another user)")
            messages.error(request, provider.get_add_exists_msg)
            return HttpResponseRedirect(reverse('edit_profile'))

        # automatically add identifier provider to user
        if not switch_from and not provider.get_add_policy:
            # TODO: handle existing uuid message separately
            provider.log("user cannot add provider")
            messages.error(request, provider.get_add_failed_msg)
            return HttpResponseRedirect(reverse('edit_profile'))

        user = request.user
        if switch_from:
            existing_provider = \
                request.user.auth_providers.active().get(
                    pk=int(switch_from), module=provider_module).settings

            # this is not a provider removal so we don't not use
            # provider.remove_from_user. Use low level access to the provider
            # db instance.
            if not provider.verified_exists():
                if provider.get_add_policy:
                    existing_provider._instance.delete()
                    existing_provider.log("removed")
                    provider.add_to_user()
                    provider.log("added")
            else:
                messages.error(request, provider.get_add_exists_msg)
                return HttpResponseRedirect(reverse('edit_profile'))

            messages.success(request, provider.get_switch_success_msg)
            return HttpResponseRedirect(reverse('edit_profile'))

        provider.add_to_user()
        provider.log("added")
        provider = user.get_auth_provider(provider_module, identifier)
        messages.success(request, provider.get_added_msg)
        return HttpResponseRedirect(reverse('edit_profile'))

    # astakos user exists ?
    try:
        user = AstakosUser.objects.get_auth_provider_user(
            provider_module,
            identifier=identifier,
            user__email_verified=True,
        )
    except AstakosUser.DoesNotExist:
        # TODO: add a message ? redirec to login ?
        if astakos_messages.AUTH_PROVIDER_SIGNUP_FROM_LOGIN:
            messages.warning(request,
                             astakos_messages.AUTH_PROVIDER_SIGNUP_FROM_LOGIN)
        raise

    if not third_party_key:
        third_party_key = get_pending_key(request)

    provider = user.get_auth_provider(provider_module, identifier)
    if user.is_active:
        if not provider.get_login_policy:
            messages.error(request, provider.get_login_disabled_msg)
            return HttpResponseRedirect(reverse('login'))

        # authenticate user
        response = prepare_response(request, user, next_redirect, 'renew'
                                    in request.GET)

        messages.success(request, provider.get_login_success_msg)
        add_pending_auth_provider(request, third_party_key, provider)
        response.set_cookie('astakos_last_login_method', provider_module)
        return response
    else:
        message = user.get_inactive_message(provider_module, identifier)
        messages.error(request, message)
        return HttpResponseRedirect(login_url(request))
예제 #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
예제 #7
0
파일: local.py 프로젝트: AthinaB/synnefo
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
예제 #8
0
파일: im.py 프로젝트: grnet/synnefo
            user = form.create_user()
            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)

            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))

    ldap_login_form = None
    if 'ldap' in settings.IM_MODULES:
        ldap_login_form = LDAPLoginForm(request)

    return render_response(
        template_name,
        login_form=ldap_login_form,
        signup_form=form,
        third_party_token=third_party_token,
        provider=provider,
예제 #9
0
def handle_third_party_login(request, provider_module, identifier,
                             provider_info=None, affiliation=None,
                             third_party_key=None):

    if not provider_info:
        provider_info = {}

    if not affiliation:
        affiliation = provider_module.title()

    next_redirect = request.GET.get(
        'next', request.session.get('next_url', None))

    if 'next_url' in request.session:
        del request.session['next_url']

    third_party_request_params = get_third_party_session_params(request)
    from_login = third_party_request_params.get('from_login', False)
    switch_from = third_party_request_params.get('switch_from', False)
    provider_data = {
        'affiliation': affiliation,
        'info': provider_info
    }

    provider = auth.get_provider(provider_module, request.user, identifier,
                                 **provider_data)

    # an existing user accessed the view
    if request.user.is_authenticated():
        if request.user.has_auth_provider(provider.module,
                                          identifier=identifier):
            return HttpResponseRedirect(reverse('edit_profile'))

        if provider.verified_exists():
            provider.log("add failed (identifier exists to another user)")
            messages.error(request, provider.get_add_exists_msg)
            return HttpResponseRedirect(reverse('edit_profile'))

        # automatically add identifier provider to user
        if not switch_from and not provider.get_add_policy:
            # TODO: handle existing uuid message separately
            provider.log("user cannot add provider")
            messages.error(request, provider.get_add_failed_msg)
            return HttpResponseRedirect(reverse('edit_profile'))

        user = request.user
        if switch_from:
            existing_provider = \
                request.user.auth_providers.active().get(
                    pk=int(switch_from), module=provider_module).settings

            # this is not a provider removal so we don't not use
            # provider.remove_from_user. Use low level access to the provider
            # db instance.
            if not provider.verified_exists():
                if provider.get_add_policy:
                    existing_provider._instance.delete()
                    existing_provider.log("removed")
                    provider.add_to_user()
                    provider.log("added")
            else:
                messages.error(request, provider.get_add_exists_msg)
                return HttpResponseRedirect(reverse('edit_profile'))

            messages.success(request, provider.get_switch_success_msg)
            return HttpResponseRedirect(reverse('edit_profile'))

        provider.add_to_user()
        provider.log("added")
        provider = user.get_auth_provider(provider_module, identifier)
        messages.success(request, provider.get_added_msg)
        return HttpResponseRedirect(reverse('edit_profile'))

    # astakos user exists ?
    try:
        user = AstakosUser.objects.get_auth_provider_user(
            provider_module,
            identifier=identifier,
            user__email_verified=True,
        )
    except AstakosUser.DoesNotExist:
        # TODO: add a message ? redirec to login ?
        if astakos_messages.AUTH_PROVIDER_SIGNUP_FROM_LOGIN:
            messages.warning(request,
                             astakos_messages.AUTH_PROVIDER_SIGNUP_FROM_LOGIN)
        raise

    if not third_party_key:
        third_party_key = get_pending_key(request)

    provider = user.get_auth_provider(provider_module, identifier)
    if user.is_active:
        if not provider.get_login_policy:
            messages.error(request, provider.get_login_disabled_msg)
            return HttpResponseRedirect(reverse('login'))

        # authenticate user
        response = prepare_response(request, user, next_redirect,
                                    'renew' in request.GET)

        messages.success(request, provider.get_login_success_msg)
        add_pending_auth_provider(request, third_party_key, provider)
        response.set_cookie('astakos_last_login_method', provider_module)
        return response
    else:
        message = user.get_inactive_message(provider_module, identifier)
        messages.error(request, message)
        return HttpResponseRedirect(login_url(request))
예제 #10
0
파일: im.py 프로젝트: cstavr/synnefo
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))