Compare commits

..

2 Commits

Author SHA1 Message Date
cbb7ed4498 2fa-0.7 2023-11-18 20:45:37 +01:00
4d2cf64f19 2fa-0.7 2023-11-18 20:44:06 +01:00
5 changed files with 87 additions and 32 deletions

1
.gitignore vendored
View File

@ -5,4 +5,5 @@
*.swo
*~
session
static/tmp
libs/__pycache__

View File

@ -16,11 +16,12 @@
<h1>2FA</h1>
% if data['secureAuth'] == True:
<div class="qr-code">
<img src="{{'static/tmp/'+data['authCode']+'.png'}}" />
</div>
<form name="disable2faForm" method="post" action="/disable_2fa">
<label for="2fa">2FA</label>
<input id="2fa" name="2fa" type="text" value="{{data['authCode']}}">
<input id="2fa" name="2fa" type="text" value="{{data['authCode']}}" readonly>
<div class="form-buttons">
<a href="/user"><button class="green" type="button">{{ str['back'] }}</button></a>
@ -30,11 +31,10 @@
</form>
% else:
<form name="enable2faForm" method="post" action="/enable_2fa">
<label for="2fa">2FA</label>
<input id="2fa" name="2fa" type="text" value="{{data['authCode']}}">
<input id="2fa" name="2fa" type="text" value="{{data['authCode']}}" readonly>
<div class="form-buttons">
<a href="/user"><button class="green" type="button">{{ str['back'] }}</button></a>

92
app.py
View File

@ -27,9 +27,10 @@ from ldap3 import Server, Connection, ALL
from ldap3 import SIMPLE, SUBTREE, MODIFY_REPLACE, MODIFY_ADD, MODIFY_DELETE, ALL_ATTRIBUTES
from ldap3.core.exceptions import LDAPBindError, LDAPConstraintViolationResult, \
LDAPInvalidCredentialsResult, LDAPUserNameIsMandatoryError, \
LDAPSocketOpenError, LDAPExceptionError, LDAPAttributeOrValueExistsResult
LDAPSocketOpenError, LDAPExceptionError, LDAPAttributeOrValueExistsResult, \
LDAPNoSuchAttributeResult
import logging
from os import getenv, environ, path
from os import getenv, environ, path, remove
from libs import flist, slist
from libs.localization import *
from libs.helper import tools
@ -118,11 +119,22 @@ def get_index():
@get('/_2fa')
def get_index():
#newSession().get()
try:
reload(newSession().get()['username'], None, None)
#add_auth_attribute_step1(newSession().get()['username'], None, None)
return _2fa_tpl(data=newSession().get(), str=i18n.str)
except Exception as e:
return index_tpl(str=i18n.str)
@get('/enable_2fa')
@get('/disable_2fa')
def get_index():
try:
return user_tpl(data=newSession().get(), str=i18n.str)
except Exception as e:
return index_tpl(str=i18n.str)
@post('/user')
def post_user():
form = request.forms.getunicode
@ -276,33 +288,47 @@ def post_edit_email():
@post('/enable_2fa')
def post_enable_2fa():
try:
username=newSession().get()['username']
add_auth_attribute_step1(username, tools.generate_secret(), action='enable')
'''
add attribute authCode
set session data
'''
except Error as e:
LOG.warning("akatsa")
return error(str(e))
return _2fa_tpl(data=newSession().get(), str=i18n.str)
def error(msg):
return _2fa_tpl(alerts=[('error', msg, 'fadeOut')], data=newSession().get(), str=i18n.str)
try:
if(not newSession().get()['secureAuth']):
try:
username=newSession().get()['username']
add_auth_attribute_step1(username, tools.generate_secret(), action='enable')
except Error as e:
#add_auth_attribute_step1(newSession().get()['username'], None, None)
reload(newSession().get()['username'], None, None)
LOG.warning(e)
return error('2 urratseko autentifikazioa birgaitua izan da.')
except Error as e:
LOG.warning(e)
return index_tpl(alerts=[('error', e, 'fadeOut')], str=i18n.str)
return _2fa_tpl(alerts=[('success', 'Bikain, 2 urratseko autentifikazioa gaitu da.', 'fadeOut')], data=newSession().get(), str=i18n.str)
@post('/disable_2fa')
def post_disable_2fa():
try:
username=newSession().get()['username']
add_auth_attribute_step1(username, tools.generate_secret(), action='disable')
'''
add attribute authCode
set session data
'''
except Error as e:
LOG.warning("akatsa")
return error(str(e))
return _2fa_tpl(data=newSession().get(), str=i18n.str)
def error(msg):
return _2fa_tpl(alerts=[('error', msg, 'fadeOut')], data=newSession().get(), str=i18n.str)
try:
if(newSession().get()['secureAuth']):
try:
username=newSession().get()['username']
add_auth_attribute_step1(username, None, action='disable')
except Error as e:
#add_auth_attribute_step1(newSession().get()['username'], None, None)
reload(newSession().get()['username'], None, None)
LOG.warning(e)
return error(str(e))
except Error as e:
LOG.warning(e)
return index_tpl(alerts=[('error', e, 'fadeOut')], str=i18n.str)
return _2fa_tpl(alerts=[('error', '2 urratseko autentifikazioa desgaitua izan da.', 'fadeOut')], data=newSession().get(), str=i18n.str)
@post('/change_pwd')
def post_change_pwd():
@ -366,6 +392,10 @@ def serve_static(filename):
def font(filepath):
return static_file(filepath, root="static/fonts")
@get("/static/tmp/<filepath:re:.*\.(png|svg)>")
def font(filepath):
return static_file(filepath, root="static/tmp")
def index_tpl(**kwargs):
return template('index', **kwargs)
@ -728,6 +758,10 @@ def add_auth_attribute_step2(conf, *args):
LOG.error('{}: {!s}'.format(e.__class__.__name__, e))
raise Error(i18n.msg[23])
except LDAPNoSuchAttributeResult as e:
LOG.error('{}: {!s}'.format(e.__class__.__name__, e))
raise Error('Dagoeneko desgaiturik zeneukan 2 urratseko autentifikazioa.')
except LDAPExceptionError as e:
LOG.error('{}: {!s}'.format(e.__class__.__name__, e))
raise Error(i18n.msg[23])
@ -746,8 +780,18 @@ def add_auth_attribute_step3(conf, username, code, action):
elif(action == 'disable'):
c.modify(user_dn,{'authCode': [(MODIFY_DELETE, [])]})
c.modify(user_dn,{'secureAuth': [MODIFY_REPLACE, [False]]})
#remove file
try:
remove('static/tmp/'+newSession().get()['authCode']+'.png')
except OSError as e:
LOG.warning(str(e))
#raise Error(e)
pass
newSession().set(get_user_data(user_dn, c))
reload=add_auth_attribute_step1
#CHANGE PASSWORD
def change_passwords(username, old_pass, new_pass):
changed = []

View File

@ -4,6 +4,7 @@ import sqlite3
import re
from onetimepass import valid_totp
from secrets import choice
import segno
class Tools():
@ -44,12 +45,14 @@ class Tools():
def pwd_validation(self, e):
regex = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!#%*?&]{8,18}$'
return(bool(re.fullmatch(regex, e)))
# 2FA
def generate_secret(self): # Function to return a random string with length 16.
secret = ''
while len(secret) < 16:
secret += choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
qrcode = segno.make(secret, micro=False)
qrcode.save('static/tmp/'+secret+'.png', scale=10)
return secret
tools = Tools()

View File

@ -194,6 +194,13 @@ button.red:hover{
animation-name: fadeOut;
}
/**/
.qr-code {
margin: 0 auto;
width: max-content;
text-align: center;
}
/**/
.grid-container {
display: grid;