|
|
b838e2 |
|
|
|
b838e2 |
|
|
|
b838e2 |
import hashlib
|
|
|
b838e2 |
|
|
|
b838e2 |
import exception
|
|
|
b838e2 |
|
|
|
b838e2 |
from model.base import ModelBase
|
|
|
b838e2 |
|
|
|
b838e2 |
|
|
|
b838e2 |
class User(ModelBase):
|
|
|
b838e2 |
def __init__(self, users, row):
|
|
|
b838e2 |
self.users = users
|
|
|
b838e2 |
super().__init__(self.users.model)
|
|
|
b838e2 |
|
|
|
b838e2 |
self.id = int(row['id'])
|
|
|
b838e2 |
self.login = str(row['login'])
|
|
|
b838e2 |
self.name = str(row['name'])
|
|
|
b838e2 |
self.superuser = None
|
|
|
b838e2 |
if self.id == self.rights.user_id:
|
|
|
b838e2 |
self._password = str(row['password'])
|
|
|
b838e2 |
if self.id == self.rights.user_id or self.rights.issuperuser():
|
|
|
b838e2 |
self.superuser = self.rights.get_superuser(self.id)
|
|
|
b838e2 |
|
|
|
b838e2 |
def reset_cache(self):
|
|
|
b838e2 |
self.users.reset_cache(self.id, self.login)
|
|
|
b838e2 |
|
|
|
b838e2 |
def change_password(self, newpassword, oldpassword = None):
|
|
|
b838e2 |
if self.id == self.rights.user_id:
|
|
|
b838e2 |
if oldpassword is None:
|
|
|
b838e2 |
raise exception.ModelDeny()
|
|
|
b838e2 |
oldhash = self.users.gen_password_hash(self.id, oldpassword)
|
|
|
b838e2 |
if oldhash != self._password:
|
|
|
b838e2 |
raise exception.ModelWrongData(self.t('Password incorrect'))
|
|
|
b838e2 |
if self.id != self.rights.user_id and not self.rights.issuperuser():
|
|
|
b838e2 |
raise exception.ModelDeny()
|
|
|
b838e2 |
hash = self.users.gen_password_hash(self.id, newpassword)
|
|
|
b838e2 |
self.connection.execute('UPDATE %T SET `password`=%s WHERE `id`=%d', self.users.TABLE, hash, self.id)
|
|
|
b838e2 |
self.reset_cache()
|
|
|
b838e2 |
self.server.sessions.delete_by_user_id(self.id)
|
|
|
b838e2 |
|
|
|
b838e2 |
def can_update(self):
|
|
|
b838e2 |
return self.id == self.rights.user_id or self.rights.issuperuser()
|
|
|
b838e2 |
|
|
|
b838e2 |
def update(self, name):
|
|
|
b838e2 |
if self.can_update():
|
|
|
b838e2 |
self.connection.execute('UPDATE %T SET `name`=%s WHERE `id`=%d', self.users.TABLE, name, self.id)
|
|
|
b838e2 |
self.reset_cache()
|
|
|
b838e2 |
else:
|
|
|
b838e2 |
raise exception.ModelDeny()
|
|
|
b838e2 |
|
|
|
b838e2 |
def can_delete(self):
|
|
|
b838e2 |
return self.server.config['users']['selfdelete'] if self.id == self.rights.user_id else self.rights.issuperuser()
|
|
|
b838e2 |
|
|
|
b838e2 |
def delete(self, password = None):
|
|
|
b838e2 |
if self.can_delete():
|
|
|
b838e2 |
if self.id == self.rights.user_id:
|
|
|
b838e2 |
if password is None:
|
|
|
b838e2 |
raise exception.ModelDeny()
|
|
|
b838e2 |
hash = self.users.gen_password_hash(self.id, str(password))
|
|
|
b838e2 |
if hash != self._password:
|
|
|
b838e2 |
raise exception.ModelWrongData(self.t('Password incorrect'))
|
|
|
b838e2 |
self.rights.delete_list(user_id = self.id)
|
|
|
b838e2 |
self.connection.execute('DELETE FROM %T WHERE `id`=%d', self.users.TABLE, self.id)
|
|
|
b838e2 |
self.reset_cache()
|
|
|
b838e2 |
self.server.sessions.delete_by_user_id(self.id)
|
|
|
b838e2 |
else:
|
|
|
b838e2 |
raise exception.ModelDeny()
|
|
|
b838e2 |
|
|
|
b838e2 |
def set_superuser(self, allowed):
|
|
|
b838e2 |
if id != self.rights.user_id and self.rights.issuperuser():
|
|
|
b838e2 |
self.rights.set_superuser(self.id, allowed)
|
|
|
b838e2 |
else:
|
|
|
b838e2 |
raise exception.ModelDeny()
|
|
|
b838e2 |
|
|
|
b838e2 |
|
|
|
b838e2 |
class Users(ModelBase):
|
|
|
b838e2 |
TABLE = 'users'
|
|
|
b838e2 |
|
|
|
b838e2 |
def __init__(self, model):
|
|
|
b838e2 |
super().__init__(model)
|
|
|
b838e2 |
|
|
|
b838e2 |
def reset_cache(self, id, login):
|
|
|
b838e2 |
self.connection.cache.reset_row(self.TABLE, id)
|
|
|
b838e2 |
self.connection.cache.reset(self.TABLE, {'login': login})
|
|
|
b838e2 |
|
|
|
b838e2 |
def gen_password_hash(self, id, password):
|
|
|
b838e2 |
salt = self.server.config['users']['salt']
|
|
|
b838e2 |
return hashlib.sha512(bytes(str(id) + '|' + str(salt) + '|' + password, 'utf8')).hexdigest()
|
|
|
b838e2 |
|
|
|
b838e2 |
def verify_login(self, login):
|
|
|
e5b0ac |
return self.model.identifier(login)
|
|
|
b838e2 |
|
|
|
b838e2 |
def can_create(self):
|
|
|
b838e2 |
return self.rights.issuperuser() or self.server.config['users']['selfcreate']
|
|
|
b838e2 |
|
|
|
b838e2 |
def create(self, login, password, name):
|
|
|
b838e2 |
if not self.can_create():
|
|
|
b838e2 |
raise exception.ModelDeny()
|
|
|
b838e2 |
if not self.verify_login(login):
|
|
|
b838e2 |
raise exception.ModelWrongData(self.t('Login incorrect'))
|
|
|
b838e2 |
if self.get_by_login(login):
|
|
|
b838e2 |
raise exception.ModelWrongData(self.t('Login already exists'))
|
|
|
b838e2 |
self.connection.execute("INSERT INTO %T SET `login`=%s, `password`='', `name`=%s", self.TABLE, login, name)
|
|
|
b838e2 |
id = self.connection.insert_id()
|
|
|
b838e2 |
hash = self.gen_password_hash(int(id), password)
|
|
|
b838e2 |
self.connection.execute('UPDATE %T SET `password`=%s WHERE `id`=%d', self.TABLE, hash, id)
|
|
|
b838e2 |
self.reset_cache(id, login)
|
|
|
b838e2 |
return self.get_by_id(id)
|
|
|
b838e2 |
|
|
|
b838e2 |
def check_password(self, login, password):
|
|
|
b838e2 |
assert(type(login) is str)
|
|
|
b838e2 |
assert(type(password) is str)
|
|
|
b838e2 |
rows = self.connection.cache.select(self.TABLE, {'login': login})
|
|
|
b838e2 |
if not rows or len(rows) > 1:
|
|
|
b838e2 |
return False
|
|
|
b838e2 |
row = rows[0]
|
|
|
b838e2 |
id = int(row['id'])
|
|
|
b838e2 |
if str(row['password']) == self.gen_password_hash(id, password):
|
|
|
b838e2 |
return id
|
|
|
b838e2 |
return 0
|
|
|
b838e2 |
|
|
|
b838e2 |
def get_by_id(self, id):
|
|
|
b838e2 |
assert(type(id) is int)
|
|
|
b838e2 |
row = None
|
|
|
b838e2 |
if id == self.rights.user_id or self.rights.issuperuser() or self.server.config['users']['showprofile']:
|
|
|
b838e2 |
row = self.connection.cache.row(self.TABLE, id)
|
|
|
b838e2 |
if not row:
|
|
|
b838e2 |
return None
|
|
|
b838e2 |
return User(self, row)
|
|
|
b838e2 |
|
|
|
b838e2 |
def get_by_login(self, login):
|
|
|
b838e2 |
assert(type(login) is str)
|
|
|
b838e2 |
rows = self.connection.cache.select(self.TABLE, {'login': login})
|
|
|
b838e2 |
if not rows or len(rows) > 1:
|
|
|
b838e2 |
return None
|
|
|
b838e2 |
row = rows[0]
|
|
|
b838e2 |
if int(row['id']) == self.rights.user_id or self.rights.issuperuser() or self.server.config['users']['showprofile']:
|
|
|
b838e2 |
return User(self, row)
|
|
|
b838e2 |
return None
|
|
|
b838e2 |
|
|
|
b838e2 |
def can_list(self):
|
|
|
b838e2 |
return self.rights.issuperuser() or (self.server.config['users']['showlist'] and self.server.config['users']['showprofile'])
|
|
|
b838e2 |
|
|
|
b838e2 |
def get_list(self):
|
|
|
b838e2 |
result = list()
|
|
|
b838e2 |
if self.can_list():
|
|
|
b838e2 |
rows = self.connection.query_dict('SELECT * FROM %T ORDER BY `login`', self.TABLE)
|
|
|
b838e2 |
for row in rows:
|
|
|
b838e2 |
result.append(User(self, row))
|
|
|
b838e2 |
elif self.rights.user_id:
|
|
|
b838e2 |
current_user = self.get_by_id(self.rights.user_id)
|
|
|
b838e2 |
if current_user:
|
|
|
b838e2 |
result.append(current_user)
|
|
|
b838e2 |
return result
|
|
|
b838e2 |
|