def login(request, **kwargs): """ This is a replacement for :func:`django.contrib.auth.views.login` that requires two-factor authentication. It's slightly clever: if the user is already authenticated but not verified, it will only ask the user for their OTP token. If the user is anonymous or is already verified by an OTP device, it will use the full username/password/token form. In order to use this, you must supply a template that is compatible with both :class:`~django_otp.forms.OTPAuthenticationForm` and :class:`~django_otp.forms.OTPTokenForm`. This is a good view for :setting:`OTP_LOGIN_URL`. Parameters are the same as :func:`~django.contrib.auth.views.login` except that this view always overrides ``authentication_form``. """ user = request.user if _user_is_anonymous(user) or user.is_verified(): form = OTPAuthenticationForm else: form = partial(OTPTokenForm, user) # A minor hack to make django.contrib.auth.login happy user.backend = request.session[BACKEND_SESSION_KEY] kwargs['authentication_form'] = form return auth_login(request, **kwargs)
def dispatch(self, request, *args, **kwargs): user = self.request.user if _user_is_anonymous(user) or user.is_verified() or not ( user.is_staff or user.is_superuser): return redirect('/admin/') user.backend = 'cosinnus.backends.EmailAuthBackend' return super(AdminOnlyOTPTokenValidationView, self).dispatch(request, *args, **kwargs)
def authentication_form(self): user = self.request.user if _user_is_anonymous(user) or user.is_verified(): form = self.otp_authentication_form else: form = partial(self.otp_token_form, user) return form
def login(request, **kwargs): """ This is just like :func:`django_otp.views.login` except that it uses our agent-trust-enabled forms. """ user = request.user if _user_is_anonymous(user) or user.is_verified(): form = OTPAuthenticationForm else: form = partial(OTPTokenForm, user) # A minor hack to make django.contrib.auth.login happy user.backend = request.session[BACKEND_SESSION_KEY] kwargs['authentication_form'] = form return auth_login(request, **kwargs)
def process_request(self, request): """ Automatically ensure users who should be logged in via OTP are. """ current_url = request.path_info # We don't need to worry about annon users if _user_is_anonymous(request.user): return None # A select few views can't be captured. For example # * Logout means we can never leave the site # * OTP login means a redirect loop when viewing the otp login url. # if current_url in self.excluded_urls_list: # FIXME: This is really poor and should be fixed. Something like # https://stackoverflow.com/a/30197797 will help, but this is still a hack. for exclude_url in self.excluded_urls_list: test_result = current_url.find(exclude_url) if test_result >= 0: logger.debug( 'Currently requested url ({0}) matches {1} in excluded urls list ({2})' .format(current_url, exclude_url, self.excluded_urls_list)) return None logger.debug('{0} visited {1} which is not excluded'.format( request.user, current_url)) # Only need to check in more detail if they are logged in if _user_is_authenticated(request.user): # Run our checks and redirect code, it lives apart to be easily overridden. if self.user_must_authenticate(request): # Returned true, send the user away logger.debug( '{0} needs to supply their second factor. Redirecting to {1}' .format(request.user, self.otp_login_url)) return HttpResponseRedirect(self.otp_login_url) # If nothing else causes a redirect, return None to finish off return None