Blame model/repositories.py

Ivan Mahonin e5b0ac
Ivan Mahonin e5b0ac
import exception
Ivan Mahonin e5b0ac
Ivan Mahonin e146e6
from model.base import ModelItemBase, ModelManagerBase
Ivan Mahonin e146e6
from model.users import User
Ivan Mahonin e5b0ac
Ivan Mahonin e5b0ac
Ivan Mahonin e146e6
class RepositoryRight:
Ivan Mahonin e146e6
  def __init__(self, user, mode):
Ivan Mahonin e146e6
    assert(not user or type(user) is User)
Ivan Mahonin e146e6
    assert(type(mode) is str)
Ivan Mahonin e146e6
    self.all_users = not user
Ivan Mahonin e146e6
    self.user = user
Ivan Mahonin e146e6
    self.mode = mode
Ivan Mahonin e146e6
    
Ivan Mahonin e146e6
Ivan Mahonin e146e6
class Repository(ModelItemBase):
Ivan Mahonin e5b0ac
  def __init__(self, repositories, row, user = None):
Ivan Mahonin e146e6
    super().__init__(repositories, row)
Ivan Mahonin e5b0ac
    
Ivan Mahonin e5b0ac
    self.id = int(row['id'])
Ivan Mahonin e5b0ac
    self.user_id = int(row['user_id'])
Ivan Mahonin e5b0ac
    self.name = str(row['name'])
Ivan Mahonin e5b0ac
    self.type = str(row['type'])
Ivan Mahonin e5b0ac
    self.title = str(row['title'])
Ivan Mahonin e5b0ac
    self.description = str(row['description'])
Ivan Mahonin e5b0ac
    
Ivan Mahonin e146e6
    assert(not user or (type(user) is User and user.id == self.user_id))
Ivan Mahonin e5b0ac
    self.user = user
Ivan Mahonin e146e6
    self.repotype = self.manager.repotypes[self.type]
Ivan Mahonin e146e6
    self.user_rights = None
Ivan Mahonin e5b0ac
Ivan Mahonin e5b0ac
  def get_user(self):
Ivan Mahonin e5b0ac
    if self.user == None:
Ivan Mahonin e5b0ac
      self.user = self.model.users.get_by_id(self.user_id)
Ivan Mahonin e5b0ac
    assert(self.user)
Ivan Mahonin e5b0ac
    assert(self.user.id == self.user_id)
Ivan Mahonin e5b0ac
    return self.user
Ivan Mahonin e5b0ac
Ivan Mahonin e146e6
  def get_user_rights(self):
Ivan Mahonin e146e6
    if self.user_rights is None:
Ivan Mahonin e146e6
      self.user_rights = list()
Ivan Mahonin e146e6
      rights = self.rights.get_list(target_type = self.table(), target_id = self.id)
Ivan Mahonin e146e6
      if self.can_update():
Ivan Mahonin e146e6
        self.user_rights = rights
Ivan Mahonin e146e6
      else:
Ivan Mahonin e146e6
        for i in rights:
Ivan Mahonin e146e6
          if i.user_id == 0 or i.user_id == self.rights.user_id:
Ivan Mahonin e146e6
            self.user_rights.append(i)
Ivan Mahonin e146e6
    assert(not self.user_rights is None)
Ivan Mahonin e146e6
    return self.user_rights
Ivan Mahonin e146e6
Ivan Mahonin e5b0ac
  def reset_cache(self):
Ivan Mahonin e146e6
    self.manager.reset_cache(self.id, self.user_id, self.name)
Ivan Mahonin e5b0ac
    
Ivan Mahonin e5b0ac
  def gen_subpath(self):
Ivan Mahonin e146e6
    return self.manager.gen_subpath(self.get_user().login, self.name)
Ivan Mahonin e5b0ac
Ivan Mahonin e5b0ac
  def gen_internalurl(self):
Ivan Mahonin e5b0ac
    return self.repotype.gen_internalurl( self.gen_subpath() )
Ivan Mahonin e5b0ac
    
Ivan Mahonin 3976df
  def can_write(self):
Ivan Mahonin 3976df
    return self.can_update() or self.rights.isallowed(self.table(), self.id, self.manager.REPOWRITE)
Ivan Mahonin e146e6
  
Ivan Mahonin e5b0ac
  def can_update(self):
Ivan Mahonin e5b0ac
    return self.user_id == self.rights.user_id or self.rights.issuperuser()
Ivan Mahonin e5b0ac
  
Ivan Mahonin e5b0ac
  def update(self, title, description):
Ivan Mahonin e5b0ac
    if self.can_update():
Ivan Mahonin e5b0ac
      self.connection.execute(
Ivan Mahonin e5b0ac
        'UPDATE %T SET `title`=%s, `description`=%s WHERE `id`=%d',
Ivan Mahonin e146e6
        self.table(), title, description, self.id )
Ivan Mahonin e5b0ac
      self.reset_cache()
Ivan Mahonin e5b0ac
    else:
Ivan Mahonin e5b0ac
      raise exception.ModelDeny()
Ivan Mahonin e5b0ac
Ivan Mahonin e5b0ac
  def can_delete(self):
Ivan Mahonin e5b0ac
    return self.user_id == self.rights.user_id or self.rights.issuperuser()
Ivan Mahonin e146e6
  
Ivan Mahonin e146e6
  def delete(self):
Ivan Mahonin e5b0ac
    if self.can_delete():
Ivan Mahonin e146e6
      self.rights.delete_list(target_type = self.table(), target_id = self.id)
Ivan Mahonin e5b0ac
      self.connection.execute(
Ivan Mahonin e5b0ac
        'DELETE FROM %T WHERE `id`=%d',
Ivan Mahonin e146e6
        self.table(), self.id )
Ivan Mahonin e5b0ac
      self.reset_cache()
Ivan Mahonin e5b0ac
      self.connection.call_on_commit(self.repotype.delete, self.gen_subpath())
Ivan Mahonin e5b0ac
    else:
Ivan Mahonin e5b0ac
      raise exception.ModelDeny()
Ivan Mahonin e146e6
  
Ivan Mahonin e146e6
  def set_user_right(self, user_id, mode, allowed, all_users = False):
Ivan Mahonin e146e6
    assert(all_users == (user_id == 0))
Ivan Mahonin e146e6
    assert(type(user_id) is int)
Ivan Mahonin e146e6
    if self.can_update():
Ivan Mahonin e146e6
      if not mode in (self.manager.READ, self.manager.REPOWRITE):
Ivan Mahonin e146e6
        raise exception.ModelWrongData(self.t('Wrong mode'))
Ivan Mahonin 89ea6c
      if not user_id and mode == self.manager.REPOWRITE:
Ivan Mahonin 89ea6c
        raise exception.ModelWrongData(self.t('Cannot grant write access for all users'))
Ivan Mahonin e146e6
      self.rights.set(user_id, self.table(), self.id, mode, allowed)
Ivan Mahonin e146e6
    else:
Ivan Mahonin e146e6
      raise exception.ModelDeny()
Ivan Mahonin e5b0ac
Ivan Mahonin e5b0ac
Ivan Mahonin e146e6
class Repositories(ModelManagerBase):
Ivan Mahonin e146e6
  READ = 'read'
Ivan Mahonin e146e6
  REPOWRITE = 'repowrite'
Ivan Mahonin e5b0ac
  
Ivan Mahonin e5b0ac
  def __init__(self, model):
Ivan Mahonin e5b0ac
    super().__init__(model)
Ivan Mahonin e5b0ac
    self.repotypes = self.server.repotypes
Ivan Mahonin e5b0ac
    
Ivan Mahonin e146e6
  def table(self):
Ivan Mahonin e146e6
    return 'repositories'
Ivan Mahonin e146e6
    
Ivan Mahonin e146e6
  def itemtype(self):
Ivan Mahonin e146e6
    return Repository
Ivan Mahonin e146e6
Ivan Mahonin e5b0ac
  def reset_cache(self, id, user_id, name):
Ivan Mahonin e146e6
    super().reset_cache(id)
Ivan Mahonin e146e6
    self.connection.cache.reset(self.table(), {'user_id': user_id, 'name': name})
Ivan Mahonin e5b0ac
Ivan Mahonin e5b0ac
  def verify_name(self, name):
Ivan Mahonin e5b0ac
    return self.model.verify_identifier(name)
Ivan Mahonin e5b0ac
Ivan Mahonin e5b0ac
  def gen_subpath(self, login, name):
Ivan Mahonin e5b0ac
    assert( self.model.verify_path_entry(login) )
Ivan Mahonin e5b0ac
    assert( self.model.verify_path_entry(name) )
Ivan Mahonin e5b0ac
    return login + '/' + name
Ivan Mahonin e5b0ac
Ivan Mahonin e146e6
  def can_read(self, user, id):
Ivan Mahonin e146e6
    assert(type(user) is User)
Ivan Mahonin e146e6
    assert(type(id) is int)
Ivan Mahonin e146e6
    return user.id == self.rights.user_id \
Ivan Mahonin e146e6
        or self.rights.issuperuser() \
Ivan Mahonin e146e6
        or self.rights.isallowed(self.table(), id, self.READ)
Ivan Mahonin e146e6
Ivan Mahonin e146e6
  def can_create(self, user):
Ivan Mahonin e146e6
    assert(type(user) is User)
Ivan Mahonin e146e6
    return user.id == self.rights.user_id or self.rights.issuperuser()
Ivan Mahonin e5b0ac
Ivan Mahonin e146e6
  def create(self, user, name, repotype, title, description):
Ivan Mahonin e146e6
    if not self.can_create(user):
Ivan Mahonin e5b0ac
      raise exception.ModelDeny()
Ivan Mahonin e5b0ac
    if not self.verify_name(name):
Ivan Mahonin e5b0ac
      raise exception.ModelWrongData(self.t('Repository name is incorrect'))
Ivan Mahonin e5b0ac
    if not type(repotype) is str or not repotype in self.repotypes:
Ivan Mahonin e5b0ac
      raise exception.ModelWrongData(self.t('Repository type is incorrect'))
Ivan Mahonin e146e6
    if self.get_by_name(user, name):
Ivan Mahonin e5b0ac
      raise exception.ModelWrongData(self.t('Repository already exists'))
Ivan Mahonin e5b0ac
    
Ivan Mahonin e5b0ac
    self.connection.execute(
Ivan Mahonin e5b0ac
      'INSERT INTO %T SET `user_id`=%d, `name`=%s, `type`=%s, `title`=%s, `description`=%s',
Ivan Mahonin e146e6
      self.table(), user.id, name, repotype, title, description )
Ivan Mahonin e5b0ac
    id = self.connection.insert_id()
Ivan Mahonin e146e6
    self.reset_cache(id, user.id, name)
Ivan Mahonin e5b0ac
    
Ivan Mahonin e5b0ac
    subpath = self.gen_subpath(user.login, name)
Ivan Mahonin e5b0ac
    repotype_instance = self.repotypes[repotype]
Ivan Mahonin e5b0ac
    self.connection.call_on_rollback(repotype_instance.delete, subpath)
Ivan Mahonin e5b0ac
    repotype_instance.create(subpath)
Ivan Mahonin e5b0ac
Ivan Mahonin e5b0ac
    return self.get_by_id(id, user)
Ivan Mahonin e5b0ac
Ivan Mahonin e5b0ac
  def get_by_id(self, id, user = None):
Ivan Mahonin e5b0ac
    assert(type(id) is int)
Ivan Mahonin e146e6
    row = self.connection.cache.row(self.table(), id)
Ivan Mahonin e5b0ac
    if not row:
Ivan Mahonin e5b0ac
      return None
Ivan Mahonin e5b0ac
    if not user:
Ivan Mahonin e5b0ac
      user = self.model.users.get_by_id(row['user_id'])
Ivan Mahonin e5b0ac
      if not user:
Ivan Mahonin e5b0ac
        return None
Ivan Mahonin e146e6
    if not self.can_read(user, row['id']):
Ivan Mahonin e146e6
      return None
Ivan Mahonin e5b0ac
    return Repository(self, row, user)
Ivan Mahonin e5b0ac
    
Ivan Mahonin e146e6
  def get_by_name(self, user, name):
Ivan Mahonin e146e6
    assert(type(user) is User)
Ivan Mahonin e5b0ac
    assert(type(name) is str)
Ivan Mahonin e5b0ac
    
Ivan Mahonin e146e6
    rows = self.connection.cache.select(self.table(), {'user_id': user.id, 'name': name})
Ivan Mahonin e5b0ac
    if not rows or len(rows) > 1:
Ivan Mahonin e5b0ac
      return None
Ivan Mahonin e5b0ac
    row = rows[0]
Ivan Mahonin e146e6
    if not self.can_read(user, row['id']):
Ivan Mahonin e146e6
      return None
Ivan Mahonin e5b0ac
    return Repository(self, row, user)
Ivan Mahonin e5b0ac
  
Ivan Mahonin e5b0ac
  def get_list(self, user):
Ivan Mahonin e146e6
    assert(type(user) is User)
Ivan Mahonin e5b0ac
    result = list()
Ivan Mahonin e146e6
    rows = self.connection.query_dict('SELECT * FROM %T WHERE `user_id`=%d ORDER BY `name`', self.table(), user.id)
Ivan Mahonin e5b0ac
    for row in rows:
Ivan Mahonin e146e6
      if self.can_read(user, row['id']):
Ivan Mahonin e146e6
        result.append(Repository(self, row, user))
Ivan Mahonin e5b0ac
    return result
Ivan Mahonin e5b0ac