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"))
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
def next(request): return {'next': get_query(request).get('next', '')}
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
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
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)
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
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))
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)