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:
|
% 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
78
app.py
@ -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')
|
||||||
|
@ -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()
|
||||||
|
7
start.sh
7
start.sh
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user