Author SHA1 Message Date
aitzol 0136747a7f segurtasuna hobetzeko lanetan 2023-04-06 16:40:24 +02:00
aitzol 6094fc1156 ipa eta gailua 2023-04-05 13:23:26 +02:00
aitzol 6968957159 device detection 2023-04-04 20:26:56 +02:00
aitzol 93f79cb4f0 device detection 2023-04-04 13:25:10 +02:00
14 changed files with 67 additions and 11 deletions
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+2 -1
View File
@@ -1,5 +1,6 @@
/settings.ini /settings.ini
/settings.ini.example.original /settings.ini.example.original
/uwsgi.ini /uwsgi.ini
/*.sw*
session session
libs/__pycache__ libs/__pycache__
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+51 -10
View File
@@ -24,7 +24,7 @@ from bottle import SimpleTemplate
from bottle.ext import beaker from bottle.ext import beaker
from configparser import ConfigParser from configparser import ConfigParser
from ldap3 import Server, Connection, ALL from ldap3 import Server, Connection, ALL
from ldap3 import SIMPLE, SUBTREE, MODIFY_REPLACE, ALL_ATTRIBUTES from ldap3 import SIMPLE, SUBTREE, MODIFY_REPLACE, MODIFY_ADD, 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
@@ -34,11 +34,13 @@ from libs import flist, slist
from libs.localization import * from libs.localization import *
from libs.helper import * from libs.helper import *
import random import random
from user_agents import parse
from datetime import datetime
BASE_DIR = path.dirname(__file__) BASE_DIR = path.dirname(__file__)
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
LOG_FORMAT = '%(asctime)s %(levelname)s: %(message)s' LOG_FORMAT = '%(asctime)s %(levelname)s: %(message)s'
VERSION = '0.0.1' VERSION = '0.0.2'
@get('/') @get('/')
def get_index(): def get_index():
@@ -50,6 +52,7 @@ def get_index():
@get('/user') @get('/user')
def get_index(): def get_index():
try: try:
print(newSession().get())
return user_tpl(data=newSession().get(), str=i18n.str) return user_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)
@@ -184,8 +187,8 @@ def post_signup():
elif form('password') != form('confirm-password'): elif form('password') != form('confirm-password'):
return error(i18n.msg[7]) return error(i18n.msg[7])
try: try:
account_request(username, firstname, surname, form('password'), email, isFake) account_request(username, firstname, surname, form('password'), email, isFake, get_dev())
except Error as e: except Error as e:
LOG.warning("Unsuccessful attempt to create an account for %s: %s" % (form('username'), e)) LOG.warning("Unsuccessful attempt to create an account for %s: %s" % (form('username'), e))
return error(str(e)) return error(str(e))
@@ -388,10 +391,14 @@ def login_user_ldap(conf, username, password):
#with connect_ldap(conf) as c: #with connect_ldap(conf) as c:
with connect_ldap(conf, user=superUser.readonly_dn, password=superUser.readonly_pwd) as c: with connect_ldap(conf, user=superUser.readonly_dn, password=superUser.readonly_pwd) as c:
user_dn = find_user_dn(conf, c, username) user_dn = find_user_dn(conf, c, username)
cur_dev = get_dev()
known_device = find_device(conf, c, cur_dev)
print('KNOWN DEVICE:',known_device)
print(request.environ.get('HTTP_X_REAL_IP', request.remote_addr))
# Note: raises LDAPUserNameIsMandatoryError when user_dn is None. # Note: raises LDAPUserNameIsMandatoryError when user_dn is None.
with connect_ldap(conf, authentication=SIMPLE, user=user_dn, password=password) as c: with connect_ldap(conf, authentication=SIMPLE, user=user_dn, password=password) as c:
c.bind() c.bind()
update_login_info(conf, user_dn)
newSession().set(get_user_data(user_dn, c)) newSession().set(get_user_data(user_dn, c))
LOG.debug("%s logged in to %s" % (username, conf['base'])) LOG.debug("%s logged in to %s" % (username, conf['base']))
@@ -442,14 +449,14 @@ def logout_user_ldap(conf, username):
LOG.info("%s LOGED OUT" % (username)) LOG.info("%s LOGED OUT" % (username))
#SIGN UP #SIGN UP
def account_request(username, firstname, surname, password, email, isFake): def account_request(username, firstname, surname, password, email, isFake, device):
created = [] created = []
for key in (key for key in CONF.sections() for key in (key for key in CONF.sections()
if key == 'ldap' or key.startswith('ldap:')): if key == 'ldap' or key.startswith('ldap:')):
LOG.debug("Creating account for %s on %s server" % (username, key)) LOG.debug("Creating account for %s on %s server" % (username, key))
try: try:
new_user_account(CONF[key], username, firstname, surname, password, email, isFake) new_user_account(CONF[key], username, firstname, surname, password, email, isFake, device)
created.append(key) created.append(key)
except Error as e: except Error as e:
for key in reversed(created): for key in reversed(created):
@@ -476,7 +483,7 @@ def new_user_account(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 register(conf, username, firstname, surname, password, email, isFake): def register(conf, username, firstname, surname, password, email, isFake, device):
def to_ascii(str): def to_ascii(str):
ascii_str="" ascii_str=""
@@ -507,7 +514,10 @@ def register(conf, username, firstname, surname, password, email, isFake):
uidNumber = find_uid_number(conf,c)+1 uidNumber = find_uid_number(conf,c)+1
directory = 'home/user/'+to_ascii(username) directory = 'home/user/'+to_ascii(username)
OBJECT_CLASS = ['top', 'inetOrgPerson', 'posixAccount', 'accountsManagement'] OBJECT_CLASS = ['top', 'inetOrgPerson', 'posixAccount', 'accountsManagement']
attributes = {'gidNumber': '501', 'uidNumber': uidNumber, 'homeDirectory': directory, 'givenName': firstname, 'sn': surname, 'uid' : username, 'mail': email, 'active': False, 'fakeCn': isFake} t = datetime.now().strftime('%Y%m%d%H%M%S')+'Z'
attributes = {'gidNumber': '501', 'uidNumber': uidNumber, 'homeDirectory': directory, 'givenName':
firstname, 'sn': surname, 'uid' : username, 'mail': email, 'active': False, 'fakeCn': isFake,
'devices':device, 'ip':request.environ.get('HTTP_X_REAL_IP', request.remote_addr), 'lastLogin': t}
new_user_dn = "cn="+firstname+" "+surname+" - "+username+",cn=users,"+conf['base'] new_user_dn = "cn="+firstname+" "+surname+" - "+username+",cn=users,"+conf['base']
c.add(dn=new_user_dn,object_class=OBJECT_CLASS, attributes=attributes) c.add(dn=new_user_dn,object_class=OBJECT_CLASS, attributes=attributes)
#create/change user password #create/change user password
@@ -757,6 +767,17 @@ def find_email(conf, conn, email):
return False return False
#find devices
def find_device(conf, conn, device):
search_filter = '(uid=*)'
if conn.search(conf['base'], search_filter, attributes=['devices']):
for i in conn.response:
for j in i['attributes']['devices']:
if(j == device):
return True
return False
#find highest uidNumber #find highest uidNumber
def find_uid_number(conf, conn): def find_uid_number(conf, conn):
search_filter = '(uid=*)' search_filter = '(uid=*)'
@@ -783,7 +804,7 @@ 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, attributes=['active','fakeCn','givenName','sn','uid','mail']) conn.search(user_dn, search_filter, attributes=['active','fakeCn','givenName','sn','uid','mail','devices'])
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])
@@ -791,6 +812,7 @@ def get_user_data(user_dn, conn):
data.append(conn.entries[0].sn.values[0]) data.append(conn.entries[0].sn.values[0])
data.append(conn.entries[0].uid.values[0]) data.append(conn.entries[0].uid.values[0])
data.append(conn.entries[0].mail.values[0]) data.append(conn.entries[0].mail.values[0])
data.append(conn.entries[0].devices.values)
return(data) return(data)
def read_config(): def read_config():
@@ -816,6 +838,23 @@ def reg():
allowed = reg() allowed = reg()
def get_dev():
ua_string = bottle.request.environ.get('HTTP_USER_AGENT')
user_agent = parse(ua_string)
return str(user_agent)
def update_login_info(conf, user_dn):
superUser = SuperUsers(conf)
with connect_ldap(conf, user=superUser.admin_dn, password=superUser.admin_pwd) as c:
ip = request.environ.get('HTTP_X_REAL_IP', request.remote_addr)
t = datetime.now().strftime('%Y%m%d%H%M%S')+'Z'
c.modify(user_dn, {'ip': [( MODIFY_REPLACE, str(ip) )], 'lastLogin': [( MODIFY_REPLACE, t )] })
d = get_dev()
if not find_device(conf, c, d):
OBJECT_CLASS = ['top', 'inetOrgPerson', 'posixAccount', 'accountsManagement']
c.modify(user_dn, {'devices': [( MODIFY_ADD, d )] })
c.unbind()
class Error(Exception): class Error(Exception):
pass pass
@@ -853,6 +892,7 @@ def newSession():
self.surname = data[3] self.surname = data[3]
self.username = data[4] self.username = data[4]
self.mail = data[5] self.mail = data[5]
self.devices = data[6]
self.data['active'] = self.active self.data['active'] = self.active
self.data['fakeCn'] = self.fakeCn self.data['fakeCn'] = self.fakeCn
@@ -860,6 +900,7 @@ def newSession():
self.data['surname'] = self.surname self.data['surname'] = self.surname
self.data['username'] = self.username self.data['username'] = self.username
self.data['mail'] = self.mail self.data['mail'] = self.mail
self.data['devices'] = self.devices
def close(self): def close(self):
self.data.pop('username') self.data.pop('username')
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3
View File
@@ -2,3 +2,6 @@ bottle>=0.12.19
bottle-beaker>=0.1.3 bottle-beaker>=0.1.3
ldap3>=2.9.1 ldap3>=2.9.1
uwsgi>=2.0.21 uwsgi>=2.0.21
pyyaml>=6.0
ua-parser>=0.16.1
user-agents>=2.2.0
+11
View File
@@ -51,6 +51,17 @@
<a href="/change_pwd">{{ str['edit'] }}</a> <a href="/change_pwd">{{ str['edit'] }}</a>
</div> </div>
<div class="grid-item">
<div class="account">
<h5>Erregistroak</h5>
</div>
</div>
<div class="grid-item">
<a href="/change_pwd">ikusi</a>
</div>
<div class="account"> <div class="account">
<a href="/logout"><button class="green" type="button">{{ str['log-out'] }}</button></a> <a href="/logout"><button class="green" type="button">{{ str['log-out'] }}</button></a>
<a href="/delete"><button class="red" type="button">{{ str['del'] }}</button></a> <a href="/delete"><button class="red" type="button">{{ str['del'] }}</button></a>