Ejemplo n.º 1
0
    def done(self, form_list, **kwargs):
        """
        Finish the wizard. Save all forms and redirect.
        """
        # Remove secret key used for QR code generation
        try:
            del self.request.session[self.session_key_name]
        except KeyError:
            pass

        # TOTPDeviceForm
        if self.get_method() == 'generator':
            form = [
                form for form in form_list if isinstance(form, TOTPDeviceForm)
            ][0]
            device = form.save()

        # PhoneNumberForm / YubiKeyDeviceForm
        elif self.get_method() in ('call', 'sms', 'yubikey'):
            device = self.get_device()
            device.save()

        else:
            raise NotImplementedError("Unknown method '%s'" %
                                      self.get_method())

        django_otp.login(self.request, device)
        return redirect(self.success_url)
Ejemplo n.º 2
0
    def done(self, form_list, **kwargs):
        """
        Finish the wizard. Save all forms and redirect.
        """
        # Remove secret key used for QR code generation
        try:
            del self.request.session[self.session_key_name]
        except KeyError:
            pass

        # TOTPDeviceForm
        if self.get_method() == 'generator':
            form = [form for form in form_list if isinstance(form, TOTPDeviceForm)][0]
            device = form.save()

        # PhoneNumberForm / YubiKeyDeviceForm
        elif self.get_method() in ('call', 'sms', 'yubikey'):
            device = self.get_device()
            device.save()

        else:
            raise NotImplementedError("Unknown method '%s'" % self.get_method())

        django_otp.login(self.request, device)
        return redirect(self.success_url)
Ejemplo n.º 3
0
def tf_setup(request):
    if request.method == 'POST':
        key = request.session.get('tf_key')
        form = PleioTOTPDeviceForm(data=request.POST,
                                   key=key,
                                   user=request.user)

        if form.is_valid():
            device = form.save()
            django_otp.login(request, device)
            return redirect('two_factor:setup_complete')

    else:
        key = random_hex(20).decode('ascii')
        rawkey = unhexlify(key.encode('ascii'))
        b32key = b32encode(rawkey).decode('utf-8')

        request.session['tf_key'] = key
        request.session['django_two_factor-qr_secret_key'] = b32key

    return render(
        request, 'tf_setup.html', {
            'form': PleioTOTPDeviceForm(key=key, user=request.user),
            'QR_URL': reverse('two_factor:qr')
        })
Ejemplo n.º 4
0
def two_factor_form(request, page_action):
    two_factor_authorization =  {}
    if page_action == '2fa_setup-a2f_configuration':
        key = random_hex(20).decode('ascii')
        rawkey = unhexlify(key.encode('ascii'))
        b32key = b32encode(rawkey).decode('utf-8')

        request.session['tf_key'] = key
        request.session['django_two_factor-qr_secret_key'] = b32key

        two_factor_authorization = ({
            'form': PleioTOTPDeviceForm(key=key, user=request.user),
            'QR_URL': reverse('two_factor:qr')
        })
        two_factor_authorization['state'] = 'setup'

    elif page_action == '2fa_setupnext-a2f_configurationsuivante':
        key = request.session.get('tf_key')
        form = PleioTOTPDeviceForm(data=request.POST, key=key, user=request.user)
        if form.is_valid():
            device = form.save()
            django_otp.login(request, device)
            two_factor_authorization['default_device'] = True
            two_factor_authorization['show_state'] = True
        else:
            two_factor_authorization['form'] = form
            two_factor_authorization['QR_URL'] = reverse('two_factor:qr')
            two_factor_authorization['state'] = 'setup'

    elif page_action == '2fa_disable-a2f_desactiver':
        two_factor_authorization = DisableView.as_view(template_name='security_pages.html')(request).context_data
        two_factor_authorization['state'] = 'disable'

    elif page_action == '2fa_disableconfirm-a2f_desactiverconfirmer':
        two_factor_authorization = DisableView.as_view(template_name='security_pages.html')(request)
        two_factor_authorization['state'] = 'default'
        two_factor_authorization['show_state'] = 'true'

    elif page_action == '2fa_showcodes-a2f_afficherlescodes':
        two_factor_authorization = PleioBackupTokensView.as_view(template_name='backup_tokens.html')(request).context_data
        two_factor_authorization['default_device'] = 'true'
        two_factor_authorization['state'] = 'codes'
        two_factor_authorization['show_state'] = 'true'

    elif page_action == '2fa_generatecodes-a2f_genererdescodes':
        two_factor_authorization = PleioBackupTokensView.as_view(template_name='security_pages.html')(request).context_data
        two_factor_authorization['default_device'] = 'true'
        two_factor_authorization['show_state'] = 'true'
        two_factor_authorization['state'] = 'codes'

    else:
        two_factor_authorization = PleioProfileView.as_view(template_name='security_pages.html')(request).context_data
        two_factor_authorization['state'] = 'default'
        two_factor_authorization['show_state'] = 'true'

    return two_factor_authorization
Ejemplo n.º 5
0
 def tfa_setup_check(self, request):
     """Check TFA setup."""
     serializer = serializers.CheckTFASetupSerializer(
         data=request.data, context={"user": request.user})
     serializer.is_valid(raise_exception=True)
     # create static device for recovery purposes
     device = StaticDevice.objects.create(user=request.user,
                                          name="{} static device".format(
                                              request.user))
     for cpt in range(10):
         token = StaticToken.random_token()
         device.token_set.create(token=token)
     django_otp.login(self.request, request.user.totpdevice_set.first())
     return response.Response()
Ejemplo n.º 6
0
    def done(self, form_list, **kwargs):
        """
        Login the user and redirect to the desired page.
        """
        login(self.request, self.get_user())

        redirect_to = self.request.POST.get(
            self.redirect_field_name,
            self.request.GET.get(self.redirect_field_name, ''))
        if not is_safe_url(url=redirect_to,
                           allowed_hosts=[self.request.get_host()]):
            redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)

        device = default_device(self.get_user())
        if device:
            django_otp.login(self.request, device)
        return redirect(redirect_to)
Ejemplo n.º 7
0
    def done(self, form_list, **kwargs):
        """
        Finish the wizard. Save all forms and redirect.
        """
        # TOTPDeviceForm
        if self.get_method() == 'generator':
            form = [form for form in form_list if isinstance(form, TOTPDeviceForm)][0]
            device = form.save()

        # PhoneNumberForm / YubiKeyDeviceForm
        elif self.get_method() in ('call', 'sms', 'yubikey'):
            device = self.get_device()
            device.save()

        else:
            raise NotImplementedError("Unknown method '%s'" % self.get_method())

        django_otp.login(self.request, device)
        return redirect(self.redirect_url)
Ejemplo n.º 8
0
    def done(self, form_list, **kwargs):
        """
        Finish the wizard. Save all forms and redirect.
        """
        # TOTPDeviceForm
        if self.get_method() == 'generator':
            form = [form for form in form_list if isinstance(form, TOTPDeviceForm)][0]
            device = form.save()

        # PhoneNumberForm / YubiKeyDeviceForm
        elif self.get_method() in ('call', 'sms', 'yubikey'):
            device = self.get_device()
            device.save()

        else:
            raise NotImplementedError("Unknown method '%s'" % self.get_method())

        django_otp.login(self.request, device)
        return redirect(self.redirect_url)
Ejemplo n.º 9
0
def do_two_factor_login(request: HttpRequest, user_profile: UserProfile) -> None:
    device = default_device(user_profile)
    if device:
        django_otp.login(request, device)
Ejemplo n.º 10
0
def do_two_factor_login(request: HttpRequest, user_profile: UserProfile) -> None:
    device = default_device(user_profile)
    if device:
        django_otp.login(request, device)
Ejemplo n.º 11
0
 def form_valid(self, form):
     """Login user."""
     django_otp.login(self.request, form.cleaned_data["tfa_code"])
     return HttpResponseRedirect(
         find_nextlocation(self.request, self.request.user))
Ejemplo n.º 12
0
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
    login_form_class = OpenIDLoginForm if oreq else LoginForm
    strong_auth_req = 'strong_auth_requested' in request.session

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

            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():
                username = login_form.cleaned_data['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(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)
        try:
            set_secondary_password(request=request, password=password)
        except Exception as error:
            logger.critical(error, extra=log_extra_data(request))
            logger_mail.exception(error)
            raise OkupyError("Can't contact LDAP server")
    if (request.user.is_authenticated()
            and (not strong_auth_req
                 or 'secondary_password' in request.session)):
        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
    else:
        if 'encrypted_id' not in request.session:
            # .cache_key is a very good property since it ensures
            # that the cache is actually created, and works from first
            # request
            session_id = request.session.cache_key

            # since it always starts with the backend module name
            # and __init__() expects pure id, we can strip that
            assert(session_id.startswith('django.contrib.sessions.cache'))
            session_id = session_id[29:]
            request.session['encrypted_id'] = base64.b64encode(
                cipher.encrypt(session_id))

        # 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_id': request.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)

    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,
        'is_otp': is_otp,
    })
Ejemplo n.º 13
0
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,
        })
Ejemplo n.º 14
0
    def form_valid(self, form):
        login(self.request, self.request.user.otp_device)

        return super().form_valid(form)
Ejemplo n.º 15
0
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,
    })