Added support for disable login if excessive trials

This commit is contained in:
absurdo 2023-07-22 22:14:28 +02:00
parent f2948c74ff
commit a2bd05536f
3 changed files with 86 additions and 6 deletions

View file

@ -1,9 +1,10 @@
from flask import Blueprint, redirect, session, url_for, request, g, make_response, abort from flask import Blueprint, redirect, session, url_for, request, g, make_response, abort
from settings import config from settings import config
from paramecio2.libraries.i18n import I18n from paramecio2.libraries.i18n import I18n
from paramecio2.libraries.datetime import now, format_local_strtime, timestamp_to_datetime, obtain_timestamp
from paramecio2.libraries.formsutils import show_form, generate_csrf, set_extra_forms_user, pass_values_to_form from paramecio2.libraries.formsutils import show_form, generate_csrf, set_extra_forms_user, pass_values_to_form
from paramecio2.libraries.db.webmodel import WebModel from paramecio2.libraries.db.webmodel import WebModel
from paramecio2.modules.admin.models.admin import UserAdmin from paramecio2.modules.admin.models.admin import UserAdmin, LoginTries
from paramecio2.libraries.keyutils import create_key_encrypt, create_key from paramecio2.libraries.keyutils import create_key_encrypt, create_key
from time import time from time import time
import os, sys import os, sys
@ -249,6 +250,8 @@ def login():
sendmail.send(config.portal_email, [arr_user['email']], I18n.lang('admin', 'code_for_complete_login', 'Code for complete login'), I18n.lang('admin', 'code_for_complete_login_explain', 'We send to you a code for activate your account using double authentication:')+"\n"+token_auth, content_type='plain', attachments=[]) sendmail.send(config.portal_email, [arr_user['email']], I18n.lang('admin', 'code_for_complete_login', 'Code for complete login'), I18n.lang('admin', 'code_for_complete_login_explain', 'We send to you a code for activate your account using double authentication:')+"\n"+token_auth, content_type='plain', attachments=[])
arr_update['last_login']=now()
if len(arr_update)>0: if len(arr_update)>0:
user_admin.set_conditions('WHERE id=%s', [arr_user['id']]).update(arr_update) user_admin.set_conditions('WHERE id=%s', [arr_user['id']]).update(arr_update)
@ -263,11 +266,15 @@ def login():
else: else:
return {'error': 1, 'csrf_token': generate_csrf()} you_cannot_login=check_login_tries()
return {'error': 1, 'you_cannot_login': you_cannot_login}
else: else:
return {'error': 1, 'csrf_token': generate_csrf()} you_cannot_login=check_login_tries()
return {'error': 1, 'you_cannot_login': you_cannot_login}
#if #if
@ -356,10 +363,16 @@ def auth_check():
user_admin=UserAdmin(g.connection) user_admin=UserAdmin(g.connection)
user_admin.check_user=False
c=user_admin.set_conditions('WHERE id=%s AND token_auth=%s', [session['user_id'], code]).select_count() c=user_admin.set_conditions('WHERE id=%s AND token_auth=%s', [session['user_id'], code]).select_count()
if c==1: if c==1:
user_admin.safe_query()
user_admin.set_conditions('WHERE id=%s', [session['user_id']]).update({'token_auth': ''})
session['verify_auth']=True session['verify_auth']=True
error=0 error=0
@ -369,3 +382,41 @@ def auth_check():
def recovery_password(): def recovery_password():
return "" return ""
def check_login_tries():
logintries=LoginTries(g.connection)
logintries.safe_query()
if request.headers.getlist("X-Forwarded-For"):
ip=request.headers.getlist("X-Forwarded-For")[0]
else:
ip=request.remote_addr
you_cannot_login=0
arr_try=logintries.set_conditions('WHERE ip=%s', [ip]).select_a_row_where()
now_str=now()
date_now=format_local_strtime('YYYY-MM-DD HH:mm:ss', now_str)
date_check=format_local_strtime('YYYY-MM-DD HH:mm:ss', timestamp_to_datetime(obtain_timestamp(now_str)-300))
logintries.query('delete from logintries where last_login<%s', [date_check])
if arr_try:
if arr_try['num_tries']<5:
logintries.query('update logintries set num_tries=num_tries+1, last_login=%s WHERE ip=%s', [date_now, ip])
else:
you_cannot_login=1
else:
logintries.query('insert into logintries (`ip`, `num_tries`, `last_login`) VALUES (%s, %s, %s)', [ip, 1, date_now])
return you_cannot_login

View file

@ -7,6 +7,8 @@ from paramecio2.libraries.db import corefields
from paramecio2.libraries.db.extrafields.emailfield import EmailField from paramecio2.libraries.db.extrafields.emailfield import EmailField
from paramecio2.libraries.db.extrafields.passwordfield import PasswordField from paramecio2.libraries.db.extrafields.passwordfield import PasswordField
from paramecio2.libraries.db.extrafields.langfield import LangField from paramecio2.libraries.db.extrafields.langfield import LangField
from paramecio2.libraries.db.extrafields.datetimefield import DateTimeField
from paramecio2.libraries.db.extrafields.ipfield import IpField
class PrivilegesField(corefields.IntegerField): class PrivilegesField(corefields.IntegerField):
@ -92,8 +94,21 @@ class UserAdmin(UserModel):
self.register(corefields.BooleanField('double_auth')) self.register(corefields.BooleanField('double_auth'))
self.register(corefields.IntegerField('num_tries', 1)) #self.register(corefields.IntegerField('num_tries', 1))
self.register(DateTimeField('last_login'))
class LoginTries(UserModel):
#def create_fields(self):
def __init__(self, connection=None):
super().__init__(connection)
self.register(IpField('ip'))
self.register(corefields.IntegerField('num_tries', 1))
self.register(DateTimeField('last_login'))
""" """
user_admin=WebModel('user_admin') user_admin=WebModel('user_admin')

View file

@ -60,7 +60,21 @@
$('#username_error').html("${lang('common', 'error_disabled', 'Error, your user is disabled, you need support of web administration')}"); $('#username_error').html("${lang('common', 'error_disabled', 'Error, your user is disabled, you need support of web administration')}");
} else { } if(data.hasOwnProperty('you_cannot_login')) {
if(data.you_cannot_login) {
$('#username_error').html("${lang('common', 'error_tries_disabled', 'Error, excessive tries, wait some minutes for login again')}");
}
else {
$('#username_error').html("${lang('common', 'error_login', 'Error, wrong username or password')}");
}
}
else {
$('#username_error').html("${lang('common', 'error_login', 'Error, wrong username or password')}"); $('#username_error').html("${lang('common', 'error_login', 'Error, wrong username or password')}");