def test_unique_encrypted_are_generated_after_revocation(self): session = SessionStore() session['test'] = 'in-test' session.save() eid1 = sessionrefcipher.encrypt(session) session = sessionrefcipher.decrypt(eid1) eid2 = sessionrefcipher.encrypt(session) self.assertNotEqual(eid1, eid2)
def test_revoked_encrypted_id_raises_valueerror(self): session = SessionStore() session['test'] = 'in-test' session.save() eid1 = sessionrefcipher.encrypt(session) session = sessionrefcipher.decrypt(eid1) eid2 = sessionrefcipher.encrypt(session) if eid1 == eid2: raise SkipTest('Non-unique encrypted IDs generated') self.assertRaises(ValueError, sessionrefcipher.decrypt, eid1)
def test_encrypt_decrypt(self): session = SessionStore() session['test'] = 'in-test' session.save() eid = sessionrefcipher.encrypt(session) sess = sessionrefcipher.decrypt(eid) self.assertEqual(sess.get('test'), 'in-test')
def login(request): """ The login page """ user = None oreq = request.session.get('openid_request', None) # this can be POST or GET, and can be null or empty next = request.REQUEST.get('next') or reverse(index) is_otp = False login_form = None strong_auth_req = 'strong_auth_requested' in request.session if oreq: login_form_class = OpenIDLoginForm elif ('strong_auth_requested' in request.session and request.user.is_authenticated()): login_form_class = StrongAuthForm else: login_form_class = LoginForm try: if request.method != 'POST': pass elif 'cancel' in request.POST: # note: this wipes request.session _logout(request) if oreq is not None: oresp = oreq.answer(False) return render_openid_response(request, oresp) elif 'otp_token' in request.POST: # if user's not authenticated, go back to square one if not request.user.is_authenticated(): raise OkupyError('OTP verification timed out') is_otp = True otp_form = OTPForm(request.POST) if otp_form.is_valid(): token = otp_form.cleaned_data['otp_token'] else: raise OkupyError('OTP verification failed') # prevent replay attacks and race conditions if not RevokedToken.add(token, request.user): raise OkupyError('OTP verification failed') dev = django_otp.match_token(request.user, token) if not dev: raise OkupyError('OTP verification failed') django_otp.login(request, dev) else: login_form = login_form_class(request.POST) if login_form.is_valid(): if login_form_class != StrongAuthForm: username = login_form.cleaned_data['username'] else: username = request.user.username password = login_form.cleaned_data['password'] else: raise OkupyError('Login failed') """ Perform authentication, if it retrieves a user object then it was successful. If it retrieves None then it failed to login """ try: user = authenticate(request=request, username=username, password=password) except Exception as error: logger.critical(error, extra=log_extra_data(request)) logger_mail.exception(error) raise OkupyError( "Can't contact the LDAP server or the database") if not user: raise OkupyError('Login failed') if oreq: request.session['auto_logout'] = ( login_form.cleaned_data['auto_logout']) except OkupyError as error: messages.error(request, str(error)) if user and user.is_active: _login(request, user) # prepare devices, and see if OTP is enabled init_otp(request) set_secondary_password(request=request, password=password) if request.user.is_authenticated(): if (strong_auth_req and not 'secondary_password' in request.session): if request.method != 'POST': messages.info( request, 'You need to type in your password' + ' again to perform this action') else: if request.user.is_verified(): return redirect(next) login_form = OTPForm() is_otp = True if login_form is None: login_form = login_form_class() if is_otp or strong_auth_req: ssl_auth_form = None ssl_auth_uri = None ssh_auth_command = None else: encrypted_id = sessionrefcipher.encrypt(request.session) # TODO: it fails when: # 1. site is accessed via IP (auth.127.0.0.1), # 2. HTTP used on non-standard port (https://...:8000). ssl_auth_form = SSLCertLoginForm({ 'session': encrypted_id, 'next': request.build_absolute_uri(next), 'login_uri': request.build_absolute_uri(request.get_full_path()), }) ssl_auth_host = 'auth.' + request.get_host() ssl_auth_path = reverse(ssl_auth) ssl_auth_uri = urljoin('https://' + ssl_auth_host, ssl_auth_path) if settings.SSH_BIND[1] == 22: ssh_port_opt = '' else: ssh_port_opt = '-p %d ' % settings.SSH_BIND[1] ssh_auth_command = 'ssh %sauth+%s@%s' % ( ssh_port_opt, encrypted_id, request.get_host().split(':')[0]) return render( request, 'login.html', { 'login_form': login_form, 'openid_request': oreq, 'next': next, 'ssl_auth_uri': ssl_auth_uri, 'ssl_auth_form': ssl_auth_form, 'ssh_auth_command': ssh_auth_command, 'is_otp': is_otp, })
def login(request): """ The login page """ user = None oreq = request.session.get('openid_request', None) # this can be POST or GET, and can be null or empty next = request.REQUEST.get('next') or reverse(index) is_otp = False login_form = None strong_auth_req = 'strong_auth_requested' in request.session if oreq: login_form_class = OpenIDLoginForm elif ('strong_auth_requested' in request.session and request.user.is_authenticated()): login_form_class = StrongAuthForm else: login_form_class = LoginForm try: if request.method != 'POST': pass elif 'cancel' in request.POST: # note: this wipes request.session _logout(request) if oreq is not None: oresp = oreq.answer(False) return render_openid_response(request, oresp) elif 'otp_token' in request.POST: # if user's not authenticated, go back to square one if not request.user.is_authenticated(): raise OkupyError('OTP verification timed out') is_otp = True otp_form = OTPForm(request.POST) if otp_form.is_valid(): token = otp_form.cleaned_data['otp_token'] else: raise OkupyError('OTP verification failed') # prevent replay attacks and race conditions if not RevokedToken.add(token, request.user): raise OkupyError('OTP verification failed') dev = django_otp.match_token(request.user, token) if not dev: raise OkupyError('OTP verification failed') django_otp.login(request, dev) else: login_form = login_form_class(request.POST) if login_form.is_valid(): if login_form_class != StrongAuthForm: username = login_form.cleaned_data['username'] else: username = request.user.username password = login_form.cleaned_data['password'] else: raise OkupyError('Login failed') """ Perform authentication, if it retrieves a user object then it was successful. If it retrieves None then it failed to login """ try: user = authenticate( request=request, username=username, password=password) except Exception as error: logger.critical(error, extra=log_extra_data(request)) logger_mail.exception(error) raise OkupyError( "Can't contact the LDAP server or the database") if not user: raise OkupyError('Login failed') if oreq: request.session['auto_logout'] = ( login_form.cleaned_data['auto_logout']) except OkupyError as error: messages.error(request, str(error)) if user and user.is_active: _login(request, user) # prepare devices, and see if OTP is enabled init_otp(request) set_secondary_password(request=request, password=password) if request.user.is_authenticated(): if (strong_auth_req and not 'secondary_password' in request.session): if request.method != 'POST': messages.info(request, 'You need to type in your password' + ' again to perform this action') else: if request.user.is_verified(): return redirect(next) login_form = OTPForm() is_otp = True if login_form is None: login_form = login_form_class() if is_otp or strong_auth_req: ssl_auth_form = None ssl_auth_uri = None ssh_auth_command = None else: encrypted_id = sessionrefcipher.encrypt(request.session) # TODO: it fails when: # 1. site is accessed via IP (auth.127.0.0.1), # 2. HTTP used on non-standard port (https://...:8000). ssl_auth_form = SSLCertLoginForm({ 'session': encrypted_id, 'next': request.build_absolute_uri(next), 'login_uri': request.build_absolute_uri(request.get_full_path()), }) ssl_auth_host = 'auth.' + request.get_host() ssl_auth_path = reverse(ssl_auth) ssl_auth_uri = urljoin('https://' + ssl_auth_host, ssl_auth_path) if settings.SSH_BIND[1] == 22: ssh_port_opt = '' else: ssh_port_opt = '-p %d ' % settings.SSH_BIND[1] ssh_auth_command = 'ssh %sauth+%s@%s' % ( ssh_port_opt, encrypted_id, request.get_host().split(':')[0]) return render(request, 'login.html', { 'login_form': login_form, 'openid_request': oreq, 'next': next, 'ssl_auth_uri': ssl_auth_uri, 'ssl_auth_form': ssl_auth_form, 'ssh_auth_command': ssh_auth_command, 'is_otp': is_otp, })