2fa-0.7
This commit is contained in:
parent
fc224038a3
commit
4d2cf64f19
BIN
NHO8HV5OO57PVC3A.png
Normal file
BIN
NHO8HV5OO57PVC3A.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 252 B |
12
_2fa.tpl
12
_2fa.tpl
@ -16,11 +16,12 @@
|
|||||||
<h1>2FA</h1>
|
<h1>2FA</h1>
|
||||||
|
|
||||||
% if data['secureAuth'] == True:
|
% if data['secureAuth'] == True:
|
||||||
|
<div class="qr-code">
|
||||||
|
<img src="{{'static/tmp/'+data['authCode']+'.png'}}" />
|
||||||
|
</div>
|
||||||
<form name="disable2faForm" method="post" action="/disable_2fa">
|
<form name="disable2faForm" method="post" action="/disable_2fa">
|
||||||
|
|
||||||
<label for="2fa">2FA</label>
|
<input id="2fa" name="2fa" type="text" value="{{data['authCode']}}" readonly>
|
||||||
<input id="2fa" name="2fa" type="text" value="{{data['authCode']}}">
|
|
||||||
|
|
||||||
<div class="form-buttons">
|
<div class="form-buttons">
|
||||||
<a href="/user"><button class="green" type="button">{{ str['back'] }}</button></a>
|
<a href="/user"><button class="green" type="button">{{ str['back'] }}</button></a>
|
||||||
@ -30,11 +31,10 @@
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
% else:
|
% else:
|
||||||
|
|
||||||
<form name="enable2faForm" method="post" action="/enable_2fa">
|
<form name="enable2faForm" method="post" action="/enable_2fa">
|
||||||
|
|
||||||
<label for="2fa">2FA</label>
|
<input id="2fa" name="2fa" type="text" value="{{data['authCode']}}" readonly>
|
||||||
<input id="2fa" name="2fa" type="text" value="{{data['authCode']}}">
|
|
||||||
|
|
||||||
<div class="form-buttons">
|
<div class="form-buttons">
|
||||||
<a href="/user"><button class="green" type="button">{{ str['back'] }}</button></a>
|
<a href="/user"><button class="green" type="button">{{ str['back'] }}</button></a>
|
||||||
|
92
app.py
92
app.py
@ -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 import SIMPLE, SUBTREE, MODIFY_REPLACE, MODIFY_ADD, MODIFY_DELETE, ALL_ATTRIBUTES
|
||||||
from ldap3.core.exceptions import LDAPBindError, LDAPConstraintViolationResult, \
|
from ldap3.core.exceptions import LDAPBindError, LDAPConstraintViolationResult, \
|
||||||
LDAPInvalidCredentialsResult, LDAPUserNameIsMandatoryError, \
|
LDAPInvalidCredentialsResult, LDAPUserNameIsMandatoryError, \
|
||||||
LDAPSocketOpenError, LDAPExceptionError, LDAPAttributeOrValueExistsResult
|
LDAPSocketOpenError, LDAPExceptionError, LDAPAttributeOrValueExistsResult, \
|
||||||
|
LDAPNoSuchAttributeResult
|
||||||
import logging
|
import logging
|
||||||
from os import getenv, environ, path
|
from os import getenv, environ, path, remove
|
||||||
from libs import flist, slist
|
from libs import flist, slist
|
||||||
from libs.localization import *
|
from libs.localization import *
|
||||||
from libs.helper import tools
|
from libs.helper import tools
|
||||||
@ -118,11 +119,22 @@ def get_index():
|
|||||||
|
|
||||||
@get('/_2fa')
|
@get('/_2fa')
|
||||||
def get_index():
|
def get_index():
|
||||||
|
#newSession().get()
|
||||||
try:
|
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)
|
return _2fa_tpl(data=newSession().get(), str=i18n.str)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return index_tpl(str=i18n.str)
|
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')
|
@post('/user')
|
||||||
def post_user():
|
def post_user():
|
||||||
form = request.forms.getunicode
|
form = request.forms.getunicode
|
||||||
@ -276,33 +288,47 @@ def post_edit_email():
|
|||||||
|
|
||||||
@post('/enable_2fa')
|
@post('/enable_2fa')
|
||||||
def 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')
|
@post('/disable_2fa')
|
||||||
def 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')
|
@post('/change_pwd')
|
||||||
def post_change_pwd():
|
def post_change_pwd():
|
||||||
@ -366,6 +392,10 @@ def serve_static(filename):
|
|||||||
def font(filepath):
|
def font(filepath):
|
||||||
return static_file(filepath, root="static/fonts")
|
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):
|
def index_tpl(**kwargs):
|
||||||
return template('index', **kwargs)
|
return template('index', **kwargs)
|
||||||
|
|
||||||
@ -728,6 +758,10 @@ def add_auth_attribute_step2(conf, *args):
|
|||||||
LOG.error('{}: {!s}'.format(e.__class__.__name__, e))
|
LOG.error('{}: {!s}'.format(e.__class__.__name__, e))
|
||||||
raise Error(i18n.msg[23])
|
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:
|
except LDAPExceptionError as e:
|
||||||
LOG.error('{}: {!s}'.format(e.__class__.__name__, e))
|
LOG.error('{}: {!s}'.format(e.__class__.__name__, e))
|
||||||
raise Error(i18n.msg[23])
|
raise Error(i18n.msg[23])
|
||||||
@ -746,8 +780,18 @@ def add_auth_attribute_step3(conf, username, code, action):
|
|||||||
elif(action == 'disable'):
|
elif(action == 'disable'):
|
||||||
c.modify(user_dn,{'authCode': [(MODIFY_DELETE, [])]})
|
c.modify(user_dn,{'authCode': [(MODIFY_DELETE, [])]})
|
||||||
c.modify(user_dn,{'secureAuth': [MODIFY_REPLACE, [False]]})
|
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))
|
newSession().set(get_user_data(user_dn, c))
|
||||||
|
|
||||||
|
reload=add_auth_attribute_step1
|
||||||
|
|
||||||
#CHANGE PASSWORD
|
#CHANGE PASSWORD
|
||||||
def change_passwords(username, old_pass, new_pass):
|
def change_passwords(username, old_pass, new_pass):
|
||||||
changed = []
|
changed = []
|
||||||
|
@ -4,6 +4,7 @@ import sqlite3
|
|||||||
import re
|
import re
|
||||||
from onetimepass import valid_totp
|
from onetimepass import valid_totp
|
||||||
from secrets import choice
|
from secrets import choice
|
||||||
|
import segno
|
||||||
|
|
||||||
class Tools():
|
class Tools():
|
||||||
|
|
||||||
@ -44,12 +45,14 @@ class Tools():
|
|||||||
def pwd_validation(self, e):
|
def pwd_validation(self, e):
|
||||||
regex = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!#%*?&]{8,18}$'
|
regex = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!#%*?&]{8,18}$'
|
||||||
return(bool(re.fullmatch(regex, e)))
|
return(bool(re.fullmatch(regex, e)))
|
||||||
|
|
||||||
|
# 2FA
|
||||||
def generate_secret(self): # Function to return a random string with length 16.
|
def generate_secret(self): # Function to return a random string with length 16.
|
||||||
secret = ''
|
secret = ''
|
||||||
while len(secret) < 16:
|
while len(secret) < 16:
|
||||||
secret += choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
|
secret += choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
|
||||||
|
qrcode = segno.make(secret, micro=False)
|
||||||
|
qrcode.save('static/tmp/'+secret+'.png', scale=10)
|
||||||
return secret
|
return secret
|
||||||
|
|
||||||
|
|
||||||
tools = Tools()
|
tools = Tools()
|
||||||
|
@ -194,6 +194,13 @@ button.red:hover{
|
|||||||
animation-name: fadeOut;
|
animation-name: fadeOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
.qr-code {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: max-content;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
.grid-container {
|
.grid-container {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
Loading…
Reference in New Issue
Block a user