This commit is contained in:
Aitzol 2023-11-16 13:17:59 +01:00
parent e6c8abe026
commit a16cb64606
4 changed files with 95 additions and 7 deletions

View File

@ -17,10 +17,10 @@
% if data['secureAuth'] == True: % if data['secureAuth'] == True:
<form name="editEmailForm" method="post" action="/user"> <form name="disable2faForm" method="post" action="/user">
<label for="2fa">2FA</label> <label for="2fa">2FA</label>
<input id="2fa" name="2fa" type="text" value="" required> <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>
@ -31,10 +31,10 @@
% else: % else:
<form name="editEmailForm" method="post" action="/user"> <form name="enable2faForm" method="post" action="/enable_2fa">
<label for="2fa">2FA</label> <label for="2fa">2FA</label>
<input id="2fa" name="2fa" type="text" value="" required> <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>

78
app.py
View File

@ -269,11 +269,26 @@ def post_edit_email():
try: try:
edit_email(username, old_email, form('email').lower()) edit_email(username, old_email, form('email').lower())
except Error as e: except Error as e:
LOG.warning("Unsuccessful attempt to change email addres for %s: %s" % (username, e)) LOG.warning("Unsuccessful attempt to change email address for %s: %s" % (username, e))
return error(str(e)) return error(str(e))
return user_tpl(alerts=[('success', i18n.msg[16], 'fadeOut' )], data=newSession().get(), str=i18n.str) return user_tpl(alerts=[('success', i18n.msg[16], 'fadeOut' )], data=newSession().get(), str=i18n.str)
@post('/enable_2fa')
def post_enable_2fa():
try:
username=newSession().get()['username']
add_auth_attribute_step1(username, tools.generate_secret())
'''
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)
@post('/change_pwd') @post('/change_pwd')
def post_change_pwd(): def post_change_pwd():
form = request.forms.getunicode form = request.forms.getunicode
@ -648,7 +663,6 @@ def new_email_address(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])
def update_email_address(conf, username, old_email, new_email): def update_email_address(conf, username, old_email, new_email):
if(old_email == new_email): if(old_email == new_email):
raise Error(i18n.msg[15]) raise Error(i18n.msg[15])
@ -662,6 +676,59 @@ def update_email_address(conf, username, old_email, new_email):
c.modify(user_dn, {'mail': [( MODIFY_REPLACE, new_email_addresses )]}) c.modify(user_dn, {'mail': [( MODIFY_REPLACE, new_email_addresses )]})
newSession().set(get_user_data(user_dn, c)) newSession().set(get_user_data(user_dn, c))
# ADD SECUREAUTH ATTRIBUTE - 2FA
def add_auth_attribute_step1(username, code):
changed = []
for key in (key for key in CONF.sections()
if key == 'ldap' or key.startswith('ldap:')):
LOG.debug("Adding secureAuth attribute %s to %s" % (key, username))
try:
add_auth_attribute_step2(CONF[key], username, code)
changed.append(key)
LOG.debug("%s changed email address on %s" % (username, key))
except Error as e:
for key in reversed(changed):
LOG.info("Reverting email change in %s for %s" % (key, username))
try:
new_email_address(CONF[key], username, new_email, old_email)
except Error as e2:
LOG.error('{}: {!s}'.format(e.__class__.__name__, e2))
raise e
def add_auth_attribute_step2(conf, *args):
try:
add_auth_attribute_step3(conf, *args)
except (LDAPBindError, LDAPInvalidCredentialsResult, LDAPUserNameIsMandatoryError):
raise Error(i18n.msg[26])
except LDAPConstraintViolationResult as e:
# Extract useful part of the error message (for Samba 4 / AD).
msg = e.message.split('check_password_restrictions: ')[-1].capitalize()
raise Error(msg)
except LDAPSocketOpenError as e:
LOG.error('{}: {!s}'.format(e.__class__.__name__, e))
raise Error(i18n.msg[23])
except LDAPExceptionError as e:
LOG.error('{}: {!s}'.format(e.__class__.__name__, e))
raise Error(i18n.msg[23])
def add_auth_attribute_step3(conf, username, code):
#set current LDAP
superUser = SuperUsers(conf)
with connect_ldap(conf, user=superUser.admin_dn, password=superUser.admin_pwd) as c:
user_dn = find_user_dn(conf, c, username)
'''OBJECT_CLASS = ['top', 'inetOrgPerson', 'posixAccount', 'accountsManagement']'''
OBJECT_CLASS = ['accountsManagement']
c.add(dn=user_dn,object_class=OBJECT_CLASS, attributes={'authCode': code})
newSession().set(get_user_data(user_dn, c))
#CHANGE PASSWORD #CHANGE PASSWORD
def change_passwords(username, old_pass, new_pass): def change_passwords(username, old_pass, new_pass):
changed = [] changed = []
@ -825,7 +892,8 @@ def get_user_email_array(user_dn, conn, old_email, new_email):
def get_user_data(user_dn, conn): def get_user_data(user_dn, conn):
search_filter = '(objectClass=*)' search_filter = '(objectClass=*)'
conn.search(user_dn, search_filter, conn.search(user_dn, search_filter,
attributes=['active','fakeCn','givenName','sn','uid','mail','devices','ip','lastLogin','secureAuth']) attributes=['active','fakeCn','givenName','sn','uid','mail','devices','ip','lastLogin','secureAuth',
'authCode'])
data = [] data = []
data.append(conn.entries[0].active.values[0]) data.append(conn.entries[0].active.values[0])
data.append(conn.entries[0].fakeCn.values[0]) data.append(conn.entries[0].fakeCn.values[0])
@ -840,6 +908,8 @@ def get_user_data(user_dn, conn):
#ts = datetime.strftime(t, '%Y-%m-%d %H:%M:%S') #ts = datetime.strftime(t, '%Y-%m-%d %H:%M:%S')
data.append(str(conn.entries[0].lastLogin.values[0])[:-6]) data.append(str(conn.entries[0].lastLogin.values[0])[:-6])
data.append(conn.entries[0].secureAuth.values[0]) data.append(conn.entries[0].secureAuth.values[0])
if(conn.entries[0].authCode):
data.append(conn.entries[0].authCode.values[0])
return(data) return(data)
@ -942,6 +1012,7 @@ def newSession():
self.ip = data[7] self.ip = data[7]
self.lastLogin = data[8] self.lastLogin = data[8]
self.secureAuth = data[9] self.secureAuth = data[9]
self.authCode = None
self.data['active'] = self.active self.data['active'] = self.active
self.data['fakeCn'] = self.fakeCn self.data['fakeCn'] = self.fakeCn
@ -953,6 +1024,7 @@ def newSession():
self.data['ip'] = self.ip self.data['ip'] = self.ip
self.data['lastLogin'] = self.lastLogin self.data['lastLogin'] = self.lastLogin
self.data['secureAuth'] = self.secureAuth self.data['secureAuth'] = self.secureAuth
self.data['authCode'] = self.authCode
def close(self): def close(self):
self.data.pop('username') self.data.pop('username')

View File

@ -2,6 +2,8 @@
import sqlite3 import sqlite3
import re import re
from onetimepass import valid_totp
from secrets import choice
class Tools(): class Tools():
@ -43,4 +45,11 @@ class Tools():
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)))
def generate_secret(self): # Function to return a random string with length 16.
secret = ''
while len(secret) < 16:
secret += choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
return secret
tools = Tools() tools = Tools()

View File

@ -1,3 +1,8 @@
##############################
## Erabilera: ##
## sudo chmod +x start.sh ##
## ./start.sh $UID ##
##############################
#!/bin/bash #!/bin/bash
if [ ! -f settings.ini ]; then if [ ! -f settings.ini ]; then
cp settings.ini.example settings.ini cp settings.ini.example settings.ini
@ -6,6 +11,8 @@ fi
if [[ $# -gt 0 ]]; then if [[ $# -gt 0 ]]; then
UID_=$1 UID_=$1
echo $UID_ echo $UID_
export LDAP_ADMIN_PASSWORD=admin
export LDAP_READONLY_PASSWORD=readonly
fi fi
uwsgi --http :9090 --enable-threads --uid $UID_ --wsgi-file app.py uwsgi --http :9090 --enable-threads --uid $UID_ --wsgi-file app.py