From e146e6375471b228ae716bb032615af74adac407 Mon Sep 17 00:00:00 2001
From: Ivan Mahonin
Date: Oct 07 2019 12:55:40 +0000
Subject: manage repository rights
---
diff --git a/action/repo.py b/action/repo.py
index 5b8ea4e..5cc8e77 100644
--- a/action/repo.py
+++ b/action/repo.py
@@ -16,6 +16,10 @@ class RepoBase(UserBase):
raise exception.ActionError( request.t('Repository Id incorrect') )
return repository_id
+ def redirect_to_repo(self, request, repo, path = None):
+ if path is None: path = list()
+ return self.redirect_to_user(request, repo.get_user(), ['repo', str(repo.name)] + path)
+
class RepoCreate(RepoBase):
def process(self, request):
@@ -25,14 +29,18 @@ class RepoCreate(RepoBase):
title = str(request.postvars.get('title', ''))
description = str(request.postvars.get('description', ''))
+ user = request.model.users.get_by_id(user_id)
+ if not user:
+ raise exception.ActionError( request.t('User not found') )
+
repo = None
try:
- repo = request.model.repositories.create(user_id, name, repotype, title, description)
+ repo = request.model.repositories.create(user, name, repotype, title, description)
except Exception as e:
self.propagate_exception(e)
request.connection.commit()
- return request.answer.complete_redirect(['user', str(repo.get_user().login), 'repo', str(repo.name)])
+ return self.redirect_to_repo(request, repo)
class RepoUpdate(RepoBase):
@@ -51,7 +59,7 @@ class RepoUpdate(RepoBase):
self.propagate_exception(e)
request.connection.commit()
- return request.answer.complete_redirect(['user', str(repo.get_user().login), 'repo', str(repo.name)])
+ return self.redirect_to_repo(request, repo)
class RepoDelete(RepoBase):
@@ -61,7 +69,7 @@ class RepoDelete(RepoBase):
repo = request.model.repositories.get_by_id(repository_id)
if not repo:
raise exception.ActionError( request.t('Repository not found') )
- login = repo.get_user().login
+ user = repo.get_user()
try:
repo.delete()
@@ -69,13 +77,55 @@ class RepoDelete(RepoBase):
self.propagate_exception(e)
request.connection.commit()
- return request.answer.complete_redirect(['user', login, 'repos'])
+ return self.redirect_to_user(request, user, ['repos'])
+class RepoSetUserRight(RepoBase):
+ def process(self, request):
+ repository_id = self.parse_repository_id(request)
+ repo = request.model.repositories.get_by_id(repository_id)
+ if not repo:
+ raise exception.ActionError( request.t('Repository not found') )
+
+ allowed = bool(request.postvars.get('allowed', False))
+ mode = str(request.postvars.get('mode', ''))
+
+ try:
+ user_id = int(request.postvars.get('user_id', 0))
+ except Exception:
+ raise exception.ActionError( request.t('User Id incorrect') )
+ user_login = str(request.postvars.get('user_login', ''))
+ all_users = bool(request.postvars.get('all_users', False))
+
+ if user_id and user_login:
+ raise exception.ActionError( request.t('Both user id and user login was set') )
+ if all_users and (user_id or user_login):
+ raise exception.ActionError( request.t('All users flag was set with selection of concrete user') )
+
+ user = None
+ if user_id:
+ user = request.model.users.get_by_id(user_id)
+ elif user_login:
+ user = request.model.users.get_by_login(user_login)
+ user_id = user.id
+
+ if not all_users and not user:
+ raise exception.ActionError( request.t('User not found') )
+
+ try:
+ repo.set_user_right(user_id, mode, allowed, all_users = all_users)
+ except Exception as e:
+ self.propagate_exception(e)
+
+ request.connection.commit()
+ return self.redirect_to_repo(request, repo, ['edit'])
+
+
actions = {
- 'create' : RepoCreate(),
- 'update' : RepoUpdate(),
- 'delete' : RepoDelete(),
+ 'create' : RepoCreate(),
+ 'update' : RepoUpdate(),
+ 'delete' : RepoDelete(),
+ 'setuserright' : RepoSetUserRight(),
}
diff --git a/action/user.py b/action/user.py
index c3520ac..8a1131b 100644
--- a/action/user.py
+++ b/action/user.py
@@ -17,6 +17,10 @@ class UserBase(Action):
raise exception.ActionError( request.t('Used Id incorrect') )
return user_id
+ def redirect_to_user(self, request, user, path = None):
+ if path is None: path = list()
+ return request.answer.complete_redirect(['user', str(user.login)] + path)
+
class UserLogin(UserBase):
def __init__(self):
@@ -52,7 +56,7 @@ class UserCreate(UserBase):
self.propagate_exception(e)
request.connection.commit()
- return request.answer.complete_redirect(['user', str(user.login)])
+ return self.redirect_to_user(request, user)
class UserUpdate(UserBase):
@@ -70,7 +74,7 @@ class UserUpdate(UserBase):
self.propagate_exception(e)
request.connection.commit()
- return request.answer.complete_redirect(['user', str(user.login)])
+ return self.redirect_to_user(request, user)
class UserDelete(UserBase):
@@ -114,7 +118,7 @@ class UserSetPassword(UserBase):
self.propagate_exception(e)
request.connection.commit()
- return request.answer.complete_redirect(['user', str(user.login)])
+ return self.redirect_to_user(request, user)
class UserSetSuperuser(UserBase):
@@ -132,7 +136,7 @@ class UserSetSuperuser(UserBase):
self.propagate_exception(e)
request.connection.commit()
- return request.answer.complete_redirect(['user', str(user.login)])
+ return self.redirect_to_user(request, user)
actions = {
diff --git a/data/common.css b/data/common.css
index 8b13789..5338f59 100644
--- a/data/common.css
+++ b/data/common.css
@@ -1 +1,13 @@
+fieldset > div > span {
+ display: inline-block;
+ vertical-align: text-top;
+ text-align: right;
+ width: 200px;
+}
+
+fieldset > div > div {
+ display: inline-block;
+ vertical-align: text-top;
+ width: 400px;
+}
diff --git a/db/types.py b/db/types.py
index 3120a99..5589c01 100644
--- a/db/types.py
+++ b/db/types.py
@@ -6,6 +6,9 @@ import datetime
dateformat = '%Y-%m-%dT%H:%M:%S'
datepattern = '0000-00-00T00:00:00'
+def any_to_str(s):
+ return '' if s is None else str(s)
+
def date_to_str(date):
return date.strftime(dateformat).rjust(len(datepattern), '0')
@@ -40,7 +43,7 @@ class Int(Type):
class String(Type):
def from_raw(self, value):
- return '' if value is None else str(value)
+ return any_to_str(value)
def to_db(self, connection, value):
return "'" + connection.escape_string(self.from_raw(value)) + "'"
@@ -52,14 +55,14 @@ class Float(Type):
class Date(Type):
def from_raw(self, value):
- return str_to_date(date_to_str(value) if type(value) is datetime.datetime else str(value))
+ return str_to_date(date_to_str(value) if type(value) is datetime.datetime else any_to_str(value))
def from_db(self, connection, value):
return set_timezone(value)
class Field(Type):
def from_raw(self, value):
- result = str(value)
+ result = any_to_str(value)
assert(result.isidentifier())
return result
def to_db(self, connection, value):
@@ -68,17 +71,27 @@ class Field(Type):
class Table(Type):
def from_raw(self, value):
- result = str(value)
+ result = any_to_str(value)
assert(result.isidentifier())
return result
def from_db(self, connection, value):
- value = str(value)
+ value = any_to_str(value)
prefix = connection.pool.server.config['db']['prefix']
assert value.startswith(prefix)
return self.from_raw(value[len(prefix):])
def to_db(self, connection, value):
return '`' + connection.escape_string( connection.pool.server.config['db']['prefix'] + self.from_raw(value)) + '`'
+class Query(Type):
+ def from_raw(self, value):
+ assert type(value) is str
+ return value
+ def from_db(self, connection, value):
+ assert type(value) is str
+ return value
+ def to_db(self, connection, value):
+ return self.from_raw(value)
+
tint = Int()
tstring = String()
@@ -86,6 +99,7 @@ tfloat = Float()
tdate = Date()
tfield = Field()
ttable = Table()
+tquery = Query()
bytype = {
@@ -102,4 +116,5 @@ bychar = {
'D': tdate,
'F': tfield,
'T': ttable,
+ 'Q': tquery,
}
diff --git a/doc/plan.ods b/doc/plan.ods
index e682e2f..aab4a63 100644
Binary files a/doc/plan.ods and b/doc/plan.ods differ
diff --git a/model/base.py b/model/base.py
index deeb988..596d6e5 100644
--- a/model/base.py
+++ b/model/base.py
@@ -1,4 +1,5 @@
+
class ModelBase:
def __init__(self, model):
self.model = model
@@ -11,3 +12,36 @@ class ModelBase:
return self.translator.translate(text)
def t(self, text):
return self.translate(text)
+
+
+class ModelItemBase(ModelBase):
+ def __init__(self, manager, row):
+ self.manager = manager
+ super().__init__(self.manager.model)
+ assert(self.manager.itemtype() == type(self))
+
+ self.id = int(row['id'])
+ assert(self.id)
+
+ def reset_cache(self):
+ self.manager.cache.reset_row(self.table(), self.id)
+
+ def table(self):
+ return self.manager.table()
+
+
+class ModelManagerBase(ModelBase):
+ def __init__(self, model):
+ super().__init__(model)
+
+ def table(self):
+ raise Exception()
+
+ def itemtype(self):
+ raise Exception()
+
+ def item(self, *args, **kvargs):
+ raise self.itemtype()(self, *args, **kvargs)
+
+ def reset_cache(self, id):
+ self.connection.cache.reset_row(self.table(), id)
diff --git a/model/model.py b/model/model.py
index e1d6a70..dd7876a 100644
--- a/model/model.py
+++ b/model/model.py
@@ -10,7 +10,7 @@ class Model:
self.connection = connection
self.server = self.connection.server
self.internal_rights = InternalRights(self.connection, user_id, superuser)
- self.myrights = MyRights(self.internal_rights)
+ self.myrights = MyRights(self.internal_rights, self)
self.translator = translator
self.users = Users(self)
diff --git a/model/repositories.py b/model/repositories.py
index 41774ea..ceef0cc 100644
--- a/model/repositories.py
+++ b/model/repositories.py
@@ -1,13 +1,22 @@
import exception
-from model.base import ModelBase
+from model.base import ModelItemBase, ModelManagerBase
+from model.users import User
-class Repository(ModelBase):
+class RepositoryRight:
+ def __init__(self, user, mode):
+ assert(not user or type(user) is User)
+ assert(type(mode) is str)
+ self.all_users = not user
+ self.user = user
+ self.mode = mode
+
+
+class Repository(ModelItemBase):
def __init__(self, repositories, row, user = None):
- self.repositories = repositories
- super().__init__(self.repositories.model)
+ super().__init__(repositories, row)
self.id = int(row['id'])
self.user_id = int(row['user_id'])
@@ -16,9 +25,10 @@ class Repository(ModelBase):
self.title = str(row['title'])
self.description = str(row['description'])
- assert(not user or user.id == self.user_id)
+ assert(not user or (type(user) is User and user.id == self.user_id))
self.user = user
- self.repotype = self.repositories.repotypes[self.type]
+ self.repotype = self.manager.repotypes[self.type]
+ self.user_rights = None
def get_user(self):
if self.user == None:
@@ -27,15 +37,31 @@ class Repository(ModelBase):
assert(self.user.id == self.user_id)
return self.user
+ def get_user_rights(self):
+ if self.user_rights is None:
+ self.user_rights = list()
+ rights = self.rights.get_list(target_type = self.table(), target_id = self.id)
+ if self.can_update():
+ self.user_rights = rights
+ else:
+ for i in rights:
+ if i.user_id == 0 or i.user_id == self.rights.user_id:
+ self.user_rights.append(i)
+ assert(not self.user_rights is None)
+ return self.user_rights
+
def reset_cache(self):
- self.repositories.reset_cache(self.id, self.user_id, self.name)
+ self.manager.reset_cache(self.id, self.user_id, self.name)
def gen_subpath(self):
- return self.repositories.gen_subpath(self.get_user().login, self.name)
+ return self.manager.gen_subpath(self.get_user().login, self.name)
def gen_internalurl(self):
return self.repotype.gen_internalurl( self.gen_subpath() )
+ def can_write(self):
+ return self.can_update() or self.rights.isallowed(self.table(), self.id, self.manager.REPOWRITE)
+
def can_update(self):
return self.user_id == self.rights.user_id or self.rights.issuperuser()
@@ -43,35 +69,53 @@ class Repository(ModelBase):
if self.can_update():
self.connection.execute(
'UPDATE %T SET `title`=%s, `description`=%s WHERE `id`=%d',
- self.repositories.TABLE, title, description, self.id )
+ self.table(), title, description, self.id )
self.reset_cache()
else:
raise exception.ModelDeny()
def can_delete(self):
return self.user_id == self.rights.user_id or self.rights.issuperuser()
-
- def delete(self, password = None):
+
+ def delete(self):
if self.can_delete():
+ self.rights.delete_list(target_type = self.table(), target_id = self.id)
self.connection.execute(
'DELETE FROM %T WHERE `id`=%d',
- self.repositories.TABLE, self.id )
+ self.table(), self.id )
self.reset_cache()
self.connection.call_on_commit(self.repotype.delete, self.gen_subpath())
else:
raise exception.ModelDeny()
+
+ def set_user_right(self, user_id, mode, allowed, all_users = False):
+ assert(all_users == (user_id == 0))
+ assert(type(user_id) is int)
+ if self.can_update():
+ if not mode in (self.manager.READ, self.manager.REPOWRITE):
+ raise exception.ModelWrongData(self.t('Wrong mode'))
+ self.rights.set(user_id, self.table(), self.id, mode, allowed)
+ else:
+ raise exception.ModelDeny()
-class Repositories(ModelBase):
- TABLE = 'repositories'
+class Repositories(ModelManagerBase):
+ READ = 'read'
+ REPOWRITE = 'repowrite'
def __init__(self, model):
super().__init__(model)
self.repotypes = self.server.repotypes
+ def table(self):
+ return 'repositories'
+
+ def itemtype(self):
+ return Repository
+
def reset_cache(self, id, user_id, name):
- self.connection.cache.reset_row(self.TABLE, id)
- self.connection.cache.reset(self.TABLE, {'user_id': user_id, 'name': name})
+ super().reset_cache(id)
+ self.connection.cache.reset(self.table(), {'user_id': user_id, 'name': name})
def verify_name(self, name):
return self.model.verify_identifier(name)
@@ -81,31 +125,32 @@ class Repositories(ModelBase):
assert( self.model.verify_path_entry(name) )
return login + '/' + name
- def can_create(self, user_id):
- assert(type(user_id) is int and user_id)
- return user_id == self.rights.user_id or self.rights.issuperuser()
+ def can_read(self, user, id):
+ assert(type(user) is User)
+ assert(type(id) is int)
+ return user.id == self.rights.user_id \
+ or self.rights.issuperuser() \
+ or self.rights.isallowed(self.table(), id, self.READ)
+
+ def can_create(self, user):
+ assert(type(user) is User)
+ return user.id == self.rights.user_id or self.rights.issuperuser()
- def create(self, user_id, name, repotype, title, description, user = None):
- assert(not user or user.id == user_id)
- if not self.can_create(user_id):
+ def create(self, user, name, repotype, title, description):
+ if not self.can_create(user):
raise exception.ModelDeny()
if not self.verify_name(name):
raise exception.ModelWrongData(self.t('Repository name is incorrect'))
if not type(repotype) is str or not repotype in self.repotypes:
raise exception.ModelWrongData(self.t('Repository type is incorrect'))
- if self.get_by_name(user_id, name):
+ if self.get_by_name(user, name):
raise exception.ModelWrongData(self.t('Repository already exists'))
- if not user:
- user = self.model.users.get_by_id(user_id)
- if not user:
- raise exception.ModelWrongData(self.t('User not found'))
-
self.connection.execute(
'INSERT INTO %T SET `user_id`=%d, `name`=%s, `type`=%s, `title`=%s, `description`=%s',
- self.TABLE, user_id, name, repotype, title, description )
+ self.table(), user.id, name, repotype, title, description )
id = self.connection.insert_id()
- self.reset_cache(id, user_id, name)
+ self.reset_cache(id, user.id, name)
subpath = self.gen_subpath(user.login, name)
repotype_instance = self.repotypes[repotype]
@@ -116,35 +161,35 @@ class Repositories(ModelBase):
def get_by_id(self, id, user = None):
assert(type(id) is int)
- row = self.connection.cache.row(self.TABLE, id)
+ row = self.connection.cache.row(self.table(), id)
if not row:
return None
if not user:
user = self.model.users.get_by_id(row['user_id'])
if not user:
return None
+ if not self.can_read(user, row['id']):
+ return None
return Repository(self, row, user)
- def get_by_name(self, user_id, name, user = None):
- assert(not user or user.id == user_id)
- assert(type(user_id) is int)
+ def get_by_name(self, user, name):
+ assert(type(user) is User)
assert(type(name) is str)
- rows = self.connection.cache.select(self.TABLE, {'user_id': user_id, 'name': name})
+ rows = self.connection.cache.select(self.table(), {'user_id': user.id, 'name': name})
if not rows or len(rows) > 1:
return None
row = rows[0]
- if not user:
- user = self.model.users.get_by_id(row['user_id'])
- if not user:
- return None
+ if not self.can_read(user, row['id']):
+ return None
return Repository(self, row, user)
def get_list(self, user):
- assert(user)
+ assert(type(user) is User)
result = list()
- rows = self.connection.query_dict('SELECT * FROM %T WHERE `user_id`=%d ORDER BY `name`', self.TABLE, user.id)
+ rows = self.connection.query_dict('SELECT * FROM %T WHERE `user_id`=%d ORDER BY `name`', self.table(), user.id)
for row in rows:
- result.append(Repository(self, row, user))
+ if self.can_read(user, row['id']):
+ result.append(Repository(self, row, user))
return result
diff --git a/model/rights.py b/model/rights.py
index 478028b..57d46f0 100644
--- a/model/rights.py
+++ b/model/rights.py
@@ -9,9 +9,20 @@ class Right:
class MyRights:
- def __init__(self, internal):
+ def __init__(self, internal, model):
self.internal = internal
+ self.model = model
self.user_id = self.internal.user_id
+ self.user = None
+
+ def get_user():
+ if self.user_id:
+ assert self.user
+ return None
+ if not self.user:
+ self.model.users.get_by_id(self.user_id)
+ assert self.user
+ return self.user
def issuperuser(self):
return self.internal.issuperuser()
@@ -45,24 +56,26 @@ class InternalRights:
return True
if self.user_id and self.get(self.user_id, target_type, target_id, mode):
return True
+ if self.get(0, target_type, target_id, mode):
+ return True
return False
def build_where(self, user_id = None, target_type = None, target_id = None, mode = None):
where = list()
args = list()
- if user_id:
+ if not user_id is None:
assert(type(user_id) is int)
where.append("`user_id`=%d")
args.append(user_id)
- if target_type:
+ if not target_type is None:
assert(type(target_type) is str)
where.append("`target_type`=%s")
args.append(target_type)
- if target_id:
+ if not target_id is None:
assert(type(target_id) is int)
where.append("`target_id`=%d")
args.append(target_id)
- if mode:
+ if not mode is None:
assert(type(mode) is str)
where.append("`mode`=%s")
args.append(mode)
@@ -72,7 +85,7 @@ class InternalRights:
def get_list(self, user_id = None, target_type = None, target_id = None, mode = None):
where, args = self.build_where(user_id, target_type, target_id, mode)
- rows = connection.query_dict('SELECT * FROM %T' + where, self.TABLE, *args)
+ rows = self.connection.query_dict('SELECT * FROM %T' + where, self.TABLE, *args)
rights = list()
for row in rows:
rights.append( Right(row) )
diff --git a/model/users.py b/model/users.py
index 4b98f83..f17c86a 100644
--- a/model/users.py
+++ b/model/users.py
@@ -4,37 +4,43 @@ import hashlib
import exception
-from model.base import ModelBase
+from model.base import ModelItemBase, ModelManagerBase
-class User(ModelBase):
+class User(ModelItemBase):
def __init__(self, users, row):
- self.users = users
- super().__init__(self.users.model)
+ super().__init__(users, row)
self.id = int(row['id'])
self.login = str(row['login'])
self.name = str(row['name'])
+ self.superuser_ready = False
self.superuser = None
if self.id == self.rights.user_id:
self._password = str(row['password'])
- if self.id == self.rights.user_id or self.rights.issuperuser():
- self.superuser = self.rights.get_superuser(self.id)
+
+ def get_superuser(self):
+ if not self.superuser_ready:
+ self.superuser = None
+ if self.id == self.rights.user_id or self.rights.issuperuser():
+ self.superuser = self.rights.get_superuser(self.id)
+ self.superuser_ready = True
+ return self.superuser
def reset_cache(self):
- self.users.reset_cache(self.id, self.login)
+ self.manager.reset_cache(self.id, self.login)
def change_password(self, newpassword, oldpassword = None):
if self.id == self.rights.user_id:
if oldpassword is None:
raise exception.ModelDeny()
- oldhash = self.users.gen_password_hash(self.id, oldpassword)
+ oldhash = self.manager.gen_password_hash(self.id, oldpassword)
if oldhash != self._password:
raise exception.ModelWrongData(self.t('Password incorrect'))
if self.id != self.rights.user_id and not self.rights.issuperuser():
raise exception.ModelDeny()
- hash = self.users.gen_password_hash(self.id, newpassword)
- self.connection.execute('UPDATE %T SET `password`=%s WHERE `id`=%d', self.users.TABLE, hash, self.id)
+ hash = self.manager.gen_password_hash(self.id, newpassword)
+ self.connection.execute('UPDATE %T SET `password`=%s WHERE `id`=%d', self.table(), hash, self.id)
self.reset_cache()
self.server.sessions.delete_by_user_id(self.id)
@@ -43,7 +49,7 @@ class User(ModelBase):
def update(self, name):
if self.can_update():
- self.connection.execute('UPDATE %T SET `name`=%s WHERE `id`=%d', self.users.TABLE, name, self.id)
+ self.connection.execute('UPDATE %T SET `name`=%s WHERE `id`=%d', self.table(), name, self.id)
self.reset_cache()
else:
raise exception.ModelDeny()
@@ -56,11 +62,17 @@ class User(ModelBase):
if self.id == self.rights.user_id:
if password is None:
raise exception.ModelDeny()
- hash = self.users.gen_password_hash(self.id, str(password))
+ hash = self.manager.gen_password_hash(self.id, str(password))
if hash != self._password:
raise exception.ModelWrongData(self.t('Password incorrect'))
+
+ repositories = self.model.repositories.get_list(self)
+ for repo in repositories:
+ repo.delete()
+
self.rights.delete_list(user_id = self.id)
- self.connection.execute('DELETE FROM %T WHERE `id`=%d', self.users.TABLE, self.id)
+ self.rights.delete_list(target_type = self.table(), target_id = self.id)
+ self.connection.execute('DELETE FROM %T WHERE `id`=%d', self.table(), self.id)
self.reset_cache()
self.server.sessions.delete_by_user_id(self.id)
else:
@@ -73,15 +85,19 @@ class User(ModelBase):
raise exception.ModelDeny()
-class Users(ModelBase):
- TABLE = 'users'
-
+class Users(ModelManagerBase):
def __init__(self, model):
super().__init__(model)
+
+ def table(self):
+ return 'users'
+
+ def itemtype(self):
+ return User
def reset_cache(self, id, login):
- self.connection.cache.reset_row(self.TABLE, id)
- self.connection.cache.reset(self.TABLE, {'login': login})
+ super().reset_cache(id)
+ self.connection.cache.reset(self.table(), {'login': login})
def gen_password_hash(self, id, password):
salt = self.server.config['users']['salt']
@@ -100,17 +116,17 @@ class Users(ModelBase):
raise exception.ModelWrongData(self.t('Login incorrect'))
if self.get_by_login(login):
raise exception.ModelWrongData(self.t('Login already exists'))
- self.connection.execute("INSERT INTO %T SET `login`=%s, `password`='', `name`=%s", self.TABLE, login, name)
+ self.connection.execute("INSERT INTO %T SET `login`=%s, `password`='', `name`=%s", self.table(), login, name)
id = self.connection.insert_id()
hash = self.gen_password_hash(int(id), password)
- self.connection.execute('UPDATE %T SET `password`=%s WHERE `id`=%d', self.TABLE, hash, id)
+ self.connection.execute('UPDATE %T SET `password`=%s WHERE `id`=%d', self.table(), hash, id)
self.reset_cache(id, login)
return self.get_by_id(id)
def check_password(self, login, password):
assert(type(login) is str)
assert(type(password) is str)
- rows = self.connection.cache.select(self.TABLE, {'login': login})
+ rows = self.connection.cache.select(self.table(), {'login': login})
if not rows or len(rows) > 1:
return False
row = rows[0]
@@ -123,14 +139,14 @@ class Users(ModelBase):
assert(type(id) is int)
row = None
if id == self.rights.user_id or self.rights.issuperuser() or self.server.config['users']['showprofile']:
- row = self.connection.cache.row(self.TABLE, id)
+ row = self.connection.cache.row(self.table(), id)
if not row:
return None
- return User(self, row)
+ return self.itemtype()(self, row)
def get_by_login(self, login):
assert(type(login) is str)
- rows = self.connection.cache.select(self.TABLE, {'login': login})
+ rows = self.connection.cache.select(self.table(), {'login': login})
if not rows or len(rows) > 1:
return None
row = rows[0]
@@ -144,7 +160,7 @@ class Users(ModelBase):
def get_list(self):
result = list()
if self.can_list():
- rows = self.connection.query_dict('SELECT * FROM %T ORDER BY `login`', self.TABLE)
+ rows = self.connection.query_dict('SELECT * FROM %T ORDER BY `login`', self.table())
for row in rows:
result.append(User(self, row))
elif self.rights.user_id:
diff --git a/page/repo.py b/page/repo.py
index 54c8ecb..d9cbbb0 100644
--- a/page/repo.py
+++ b/page/repo.py
@@ -10,7 +10,7 @@ class RepoCreatePage(Page):
user = request.answer.objects['user']
if path:
raise exception.HttpNotFound()
- if not request.model.repositories.can_create(user.id):
+ if not request.model.repositories.can_create(user):
raise exception.HttpNotFound()
answer = request.answer
answer.add_uipath_entry( answer.t('Create repository'), prevpath )
@@ -41,7 +41,7 @@ class RepoPage(Page):
answer = request.answer
user = request.answer.objects['user']
- repo = request.model.repositories.get_by_name(user.id, str(path[0]), user)
+ repo = request.model.repositories.get_by_name(user, str(path[0]))
if not repo:
raise exception.HttpNotFound()
@@ -105,7 +105,39 @@ class RepoUpdatePage(Page):
form.add_submit()
form.end()
answer.content += form.content
-
+
+ user_rights = repo.get_user_rights()
+ for i in user_rights:
+ form = Form(request)
+ form.begin('Rights', 'repo.setuserright')
+ form.add_hidden('repository_id', repo.id)
+ form.add_hidden('allowed', '')
+ form.add_hidden('all_users', '' if i.user_id else '1')
+ form.add_hidden('user_id', i.user_id)
+ form.add_hidden('mode', i.mode)
+ if i.user_id == 0:
+ form.add_field_raw('all users', '')
+ else:
+ user = request.model.users.get_by_id(i.user_id)
+ login = user.login if user else ''
+ form.add_field_raw('login:', answer.e(login))
+ form.add_field_raw('mode:', answer.te(i.mode))
+ form.add_submit('Delete')
+ form.end()
+ answer.content += form.content
+
+ form = Form(request)
+ form.begin('Add rights', 'repo.setuserright')
+ form.add_hidden('repository_id', repo.id)
+ form.add_hidden('allowed', 1)
+ form.add_checkbox('for all users:', 'all_users')
+ form.add_input('login:', 'user_login', 'text')
+ form.add_select('mode:', 'mode', {
+ request.model.repositories.READ : request.model.repositories.READ,
+ request.model.repositories.REPOWRITE : request.model.repositories.REPOWRITE })
+ form.add_submit()
+ form.end()
+ answer.content += form.content
if repo.can_delete() and prevpath:
url = request.get_urlpath_escaped(prevpath[:-1] + ['delete'])
@@ -167,7 +199,7 @@ class RepoListPage(Page):
+ answer.e(repo.name) + ' ' \
+ answer.e(repo.title) + '
\n'
- if request.model.repositories.can_create(user.id):
+ if request.model.repositories.can_create(user):
answer.content += '' + self.make_link(answer, prevpath[:-1] + ['repo_create'], 'Create repository') + '
\n'
return answer.complete_content()
diff --git a/page/user.py b/page/user.py
index d6621e7..7f319a0 100644
--- a/page/user.py
+++ b/page/user.py
@@ -78,7 +78,7 @@ class UserProfilePage(Page):
answer.content += '' + answer.e(user.login) + '
\n'
answer.content += '' + answer.e(user.name) + '
\n'
- if user.superuser:
+ if user.get_superuser():
answer.content += '' + answer.te('Site admin') + '
\n'
if user.can_update():
answer.content += '' + self.make_link(answer, prevpath + ['edit'], 'Edit user') + '
\n'
@@ -119,11 +119,11 @@ class UserUpdatePage(Page):
form.end()
answer.content += form.content
- if user.id != request.model.myrights.user_id and not user.superuser is None:
+ if user.id != request.model.myrights.user_id and not user.get_superuser() is None:
form = Form(request)
form.begin('Global rights', 'user.setsuperuser')
form.add_hidden('user_id', user.id)
- form.add_checkbox('site admin:', 'superuser', user.superuser)
+ form.add_checkbox('site admin:', 'superuser', user.get_superuser())
form.add_submit()
form.end()
answer.content += form.content
diff --git a/repoproxy.py b/repoproxy.py
index a59c194..4a127a1 100644
--- a/repoproxy.py
+++ b/repoproxy.py
@@ -165,9 +165,7 @@ class RepoProxy:
writeaccess = repo.repotype.iswriteaccess(request, nextpath)
if writeaccess:
- if not user:
- return self.unauthorized()
- if user.id != repo.user_id and not request.model.rights.get_superuser(user.id):
+ if not repo.can_write():
return self.unauthorized()
url = repo.gen_internalurl()