2fa-0.5
This commit is contained in:
parent
e6c8abe026
commit
a16cb64606
8
_2fa.tpl
8
_2fa.tpl
|
@ -17,10 +17,10 @@
|
|||
|
||||
% if data['secureAuth'] == True:
|
||||
|
||||
<form name="editEmailForm" method="post" action="/user">
|
||||
<form name="disable2faForm" method="post" action="/user">
|
||||
|
||||
<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">
|
||||
<a href="/user"><button class="green" type="button">{{ str['back'] }}</button></a>
|
||||
|
@ -31,10 +31,10 @@
|
|||
|
||||
% else:
|
||||
|
||||
<form name="editEmailForm" method="post" action="/user">
|
||||
<form name="enable2faForm" method="post" action="/enable_2fa">
|
||||
|
||||
<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">
|
||||
<a href="/user"><button class="green" type="button">{{ str['back'] }}</button></a>
|
||||
|
|
78
app.py
78
app.py
|
@ -269,11 +269,26 @@ def post_edit_email():
|
|||
try:
|
||||
edit_email(username, old_email, form('email').lower())
|
||||
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 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')
|
||||
def post_change_pwd():
|
||||
form = request.forms.getunicode
|
||||
|
@ -648,7 +663,6 @@ def new_email_address(conf, *args):
|
|||
LOG.error('{}: {!s}'.format(e.__class__.__name__, e))
|
||||
raise Error(i18n.msg[23])
|
||||
|
||||
|
||||
def update_email_address(conf, username, old_email, new_email):
|
||||
if(old_email == new_email):
|
||||
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 )]})
|
||||
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
|
||||
def change_passwords(username, old_pass, new_pass):
|
||||
changed = []
|
||||
|
@ -825,7 +892,8 @@ def get_user_email_array(user_dn, conn, old_email, new_email):
|
|||
def get_user_data(user_dn, conn):
|
||||
search_filter = '(objectClass=*)'
|
||||
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.append(conn.entries[0].active.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')
|
||||
data.append(str(conn.entries[0].lastLogin.values[0])[:-6])
|
||||
data.append(conn.entries[0].secureAuth.values[0])
|
||||
if(conn.entries[0].authCode):
|
||||
data.append(conn.entries[0].authCode.values[0])
|
||||
|
||||
return(data)
|
||||
|
||||
|
@ -942,6 +1012,7 @@ def newSession():
|
|||
self.ip = data[7]
|
||||
self.lastLogin = data[8]
|
||||
self.secureAuth = data[9]
|
||||
self.authCode = None
|
||||
|
||||
self.data['active'] = self.active
|
||||
self.data['fakeCn'] = self.fakeCn
|
||||
|
@ -953,6 +1024,7 @@ def newSession():
|
|||
self.data['ip'] = self.ip
|
||||
self.data['lastLogin'] = self.lastLogin
|
||||
self.data['secureAuth'] = self.secureAuth
|
||||
self.data['authCode'] = self.authCode
|
||||
|
||||
def close(self):
|
||||
self.data.pop('username')
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
import sqlite3
|
||||
import re
|
||||
from onetimepass import valid_totp
|
||||
from secrets import choice
|
||||
|
||||
class Tools():
|
||||
|
||||
|
@ -43,4 +45,11 @@ class Tools():
|
|||
regex = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!#%*?&]{8,18}$'
|
||||
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()
|
||||
|
|
7
start.sh
7
start.sh
|
@ -1,3 +1,8 @@
|
|||
##############################
|
||||
## Erabilera: ##
|
||||
## sudo chmod +x start.sh ##
|
||||
## ./start.sh $UID ##
|
||||
##############################
|
||||
#!/bin/bash
|
||||
if [ ! -f settings.ini ]; then
|
||||
cp settings.ini.example settings.ini
|
||||
|
@ -6,6 +11,8 @@ fi
|
|||
if [[ $# -gt 0 ]]; then
|
||||
UID_=$1
|
||||
echo $UID_
|
||||
export LDAP_ADMIN_PASSWORD=admin
|
||||
export LDAP_READONLY_PASSWORD=readonly
|
||||
fi
|
||||
|
||||
uwsgi --http :9090 --enable-threads --uid $UID_ --wsgi-file app.py
|
||||
|
|
Loading…
Reference in New Issue