def toggle_following_repo(self, follow_repo_id, user_id): f = UserFollowing.query() \ .filter(UserFollowing.follows_repository_id == follow_repo_id) \ .filter(UserFollowing.user_id == user_id).scalar() if f is not None: try: Session().delete(f) action_logger(UserTemp(user_id), 'stopped_following_repo', RepoTemp(follow_repo_id)) return except Exception: log.error(traceback.format_exc()) raise try: f = UserFollowing() f.user_id = user_id f.follows_repository_id = follow_repo_id Session().add(f) action_logger(UserTemp(user_id), 'started_following_repo', RepoTemp(follow_repo_id)) except Exception: log.error(traceback.format_exc()) raise
def create(self, group_name, group_description, owner, parent=None, just_db=False, copy_permissions=False): try: owner = User.guess_instance(owner) parent_group = RepoGroup.guess_instance(parent) new_repo_group = RepoGroup() new_repo_group.owner = owner new_repo_group.group_description = group_description or group_name new_repo_group.parent_group = parent_group new_repo_group.group_name = new_repo_group.get_new_name(group_name) Session().add(new_repo_group) # create an ADMIN permission for owner except if we're super admin, # later owner should go into the owner field of groups if not owner.is_admin: self.grant_user_permission(repo_group=new_repo_group, user=owner, perm='group.admin') if parent_group and copy_permissions: # copy permissions from parent user_perms = UserRepoGroupToPerm.query() \ .filter(UserRepoGroupToPerm.group == parent_group).all() group_perms = UserGroupRepoGroupToPerm.query() \ .filter(UserGroupRepoGroupToPerm.group == parent_group).all() for perm in user_perms: # don't copy over the permission for user who is creating # this group, if he is not super admin he get's admin # permission set above if perm.user != owner or owner.is_admin: UserRepoGroupToPerm.create(perm.user, new_repo_group, perm.permission) for perm in group_perms: UserGroupRepoGroupToPerm.create(perm.users_group, new_repo_group, perm.permission) else: self._create_default_perms(new_repo_group) if not just_db: # we need to flush here, in order to check if database won't # throw any exceptions, create filesystem dirs at the very end Session().flush() self._create_group(new_repo_group.group_name) return new_repo_group except Exception: log.error(traceback.format_exc()) raise
def grant_user_group_permission(self, target_user_group, user_group, perm): """ Grant user group permission for given target_user_group :param target_user_group: :param user_group: :param perm: """ target_user_group = UserGroup.guess_instance(target_user_group) user_group = UserGroup.guess_instance(user_group) permission = Permission.guess_instance(perm) # forbid assigning same user group to itself if target_user_group == user_group: raise RepoGroupAssignmentError('target repo:%s cannot be ' 'assigned to itself' % target_user_group) # check if we have that permission already obj = UserGroupUserGroupToPerm.query() \ .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group) \ .filter(UserGroupUserGroupToPerm.user_group == user_group) \ .scalar() if obj is None: # create new ! obj = UserGroupUserGroupToPerm() Session().add(obj) obj.user_group = user_group obj.target_user_group = target_user_group obj.permission = permission log.debug('Granted perm %s to %s on %s', perm, target_user_group, user_group) return obj
def grant_user_permission(self, user_group, user, perm): """ Grant permission for user on given user group, or update existing one if found :param user_group: Instance of UserGroup, users_group_id, or users_group_name :param user: Instance of User, user_id or username :param perm: Instance of Permission, or permission_name """ user_group = UserGroup.guess_instance(user_group) user = User.guess_instance(user) permission = Permission.guess_instance(perm) # check if we have that permission already obj = UserUserGroupToPerm.query() \ .filter(UserUserGroupToPerm.user == user) \ .filter(UserUserGroupToPerm.user_group == user_group) \ .scalar() if obj is None: # create new ! obj = UserUserGroupToPerm() Session().add(obj) obj.user_group = user_group obj.user = user obj.permission = permission log.debug('Granted perm %s to %s on %s', perm, user, user_group) return obj
def delete(self, repo, forks=None, fs_remove=True, cur_user=None): """ Delete given repository, forks parameter defines what do do with attached forks. Throws AttachedForksError if deleted repo has attached forks :param repo: :param forks: str 'delete' or 'detach' :param fs_remove: remove(archive) repo from filesystem """ if not cur_user: cur_user = getattr(get_current_authuser(), 'username', None) repo = Repository.guess_instance(repo) if repo is not None: if forks == 'detach': for r in repo.forks: r.fork = None elif forks == 'delete': for r in repo.forks: self.delete(r, forks='delete') elif [f for f in repo.forks]: raise AttachedForksError() old_repo_dict = repo.get_dict() try: Session().delete(repo) if fs_remove: self._delete_filesystem_repo(repo) else: log.debug('skipping removal from filesystem') log_delete_repository(old_repo_dict, deleted_by=cur_user) except Exception: log.error(traceback.format_exc()) raise
def grant_user_permission(self, repo, user, perm): """ Grant permission for user on given repository, or update existing one if found :param repo: Instance of Repository, repository_id, or repository name :param user: Instance of User, user_id or username :param perm: Instance of Permission, or permission_name """ user = User.guess_instance(user) repo = Repository.guess_instance(repo) permission = Permission.guess_instance(perm) # check if we have that permission already obj = UserRepoToPerm.query() \ .filter(UserRepoToPerm.user == user) \ .filter(UserRepoToPerm.repository == repo) \ .scalar() if obj is None: # create new ! obj = UserRepoToPerm() Session().add(obj) obj.repository = repo obj.user = user obj.permission = permission log.debug('Granted perm %s to %s on %s', perm, user, repo) return obj
def grant_user_group_permission(self, repo, group_name, perm): """ Grant permission for user group on given repository, or update existing one if found :param repo: Instance of Repository, repository_id, or repository name :param group_name: Instance of UserGroup, users_group_id, or user group name :param perm: Instance of Permission, or permission_name """ repo = Repository.guess_instance(repo) group_name = UserGroup.guess_instance(group_name) permission = Permission.guess_instance(perm) # check if we have that permission already obj = UserGroupRepoToPerm.query() \ .filter(UserGroupRepoToPerm.users_group == group_name) \ .filter(UserGroupRepoToPerm.repository == repo) \ .scalar() if obj is None: # create new obj = UserGroupRepoToPerm() Session().add(obj) obj.repository = repo obj.users_group = group_name obj.permission = permission log.debug('Granted perm %s to %s on %s', perm, group_name, repo) return obj
def delete(self, repo_group, force_delete=False): repo_group = RepoGroup.guess_instance(repo_group) try: Session().delete(repo_group) self._delete_group(repo_group, force_delete) except Exception: log.error('Error removing repo_group %s', repo_group) raise
def revoke_perm(self, user_group, perm): user_group = UserGroup.guess_instance(user_group) perm = Permission.guess_instance(perm) obj = UserGroupToPerm.query() \ .filter(UserGroupToPerm.users_group == user_group) \ .filter(UserGroupToPerm.permission == perm).scalar() if obj is not None: Session().delete(obj)
def create_permissions(self): """ Create permissions for whole system """ for p in Permission.PERMS: if not Permission.get_by_key(p[0]): new_perm = Permission() new_perm.permission_name = p[0] Session().add(new_perm)
def delete(self, gist, fs_remove=True): gist = Gist.guess_instance(gist) try: Session().delete(gist) if fs_remove: self.__delete_gist(gist) else: log.debug('skipping removal from filesystem') except Exception: log.error(traceback.format_exc()) raise
def toggle_following_user(self, follow_user_id, user_id): f = UserFollowing.query() \ .filter(UserFollowing.follows_user_id == follow_user_id) \ .filter(UserFollowing.user_id == user_id).scalar() if f is not None: try: Session().delete(f) return except Exception: log.error(traceback.format_exc()) raise try: f = UserFollowing() f.user_id = user_id f.follows_user_id = follow_user_id Session().add(f) except Exception: log.error(traceback.format_exc()) raise
def set_status(self, repo, status, user, comment, revision=None, pull_request=None): """ Creates new status for changeset or updates the old ones bumping their version, leaving the current status at the value of 'status'. :param repo: :param status: :param user: :param comment: :param revision: :param pull_request: """ repo = Repository.guess_instance(repo) q = ChangesetStatus.query() if revision is not None: assert pull_request is None q = q.filter(ChangesetStatus.repo == repo) q = q.filter(ChangesetStatus.revision == revision) revisions = [revision] else: assert pull_request is not None pull_request = PullRequest.guess_instance(pull_request) repo = pull_request.org_repo q = q.filter(ChangesetStatus.repo == repo) q = q.filter(ChangesetStatus.revision.in_(pull_request.revisions)) revisions = pull_request.revisions cur_statuses = q.all() # update all current statuses with older version for st in cur_statuses: st.version += 1 new_statuses = [] for rev in revisions: new_status = ChangesetStatus() new_status.version = 0 # default new_status.author = User.guess_instance(user) new_status.repo = Repository.guess_instance(repo) new_status.status = status new_status.comment = comment new_status.revision = rev new_status.pull_request = pull_request new_statuses.append(new_status) Session().add(new_status) return new_statuses
def create_default_permissions(self, user, force=False): """ Create missing default permissions for user. If force is set, the default permissions for the user are reset, otherwise only missing permissions are created. :param user: """ user = User.guess_instance(user) def _make_perm(perm): new_perm = UserToPerm() new_perm.user = user new_perm.permission = Permission.get_by_key(perm) return new_perm def _get_group(perm_name): return '.'.join(perm_name.split('.')[:1]) perms = UserToPerm.query().filter(UserToPerm.user == user).all() defined_perms_groups = map(_get_group, (x.permission.permission_name for x in perms)) log.debug('GOT ALREADY DEFINED:%s', perms) DEFAULT_PERMS = Permission.DEFAULT_USER_PERMISSIONS if force: for perm in perms: Session().delete(perm) Session().commit() defined_perms_groups = [] # For every default permission that needs to be created, we check if # its group is already defined. If it's not, we create default permission. for perm_name in DEFAULT_PERMS: gr = _get_group(perm_name) if gr not in defined_perms_groups: log.debug('GR:%s not found, creating permission %s', gr, perm_name) new_perm = _make_perm(perm_name) Session().add(new_perm)
def update(self, repo_group, kwargs): try: repo_group = RepoGroup.guess_instance(repo_group) old_path = repo_group.full_path # change properties if 'group_description' in kwargs: repo_group.group_description = kwargs['group_description'] if 'parent_group_id' in kwargs: repo_group.parent_group_id = kwargs['parent_group_id'] if 'enable_locking' in kwargs: repo_group.enable_locking = kwargs['enable_locking'] if 'parent_group_id' in kwargs: assert kwargs['parent_group_id'] != u'-1', kwargs # RepoGroupForm should have converted to None repo_group.parent_group = RepoGroup.get(kwargs['parent_group_id']) if 'group_name' in kwargs: repo_group.group_name = repo_group.get_new_name(kwargs['group_name']) new_path = repo_group.full_path Session().add(repo_group) # iterate over all members of this groups and do fixes # set locking if given # if obj is a repoGroup also fix the name of the group according # to the parent # if obj is a Repo fix it's name # this can be potentially heavy operation for obj in repo_group.recursive_groups_and_repos(): #set the value from it's parent obj.enable_locking = repo_group.enable_locking if isinstance(obj, RepoGroup): new_name = obj.get_new_name(obj.name) log.debug('Fixing group %s to new name %s' \ % (obj.group_name, new_name)) obj.group_name = new_name elif isinstance(obj, Repository): # we need to get all repositories from this new group and # rename them accordingly to new group path new_name = obj.get_new_name(obj.just_name) log.debug('Fixing repo %s to new name %s' \ % (obj.repo_name, new_name)) obj.repo_name = new_name self._rename_group(old_path, new_path) return repo_group except Exception: log.error(traceback.format_exc()) raise
def update(self, user_group, form_data): try: user_group = UserGroup.guess_instance(user_group) for k, v in form_data.items(): if k == 'users_group_members': members_list = [] if v: v = [v] if isinstance(v, basestring) else v for u_id in set(v): member = UserGroupMember(user_group.users_group_id, u_id) members_list.append(member) Session().add(member) user_group.members = members_list setattr(user_group, k, v) # Flush to make db assign users_group_member_id to newly # created UserGroupMembers. Session().flush() except Exception: log.error(traceback.format_exc()) raise
def delete_stats(self, repo_name): """ removes stats for given repo :param repo_name: """ repo = Repository.guess_instance(repo_name) try: obj = Statistics.query() \ .filter(Statistics.repository == repo).scalar() if obj is not None: Session().delete(obj) except Exception: log.error(traceback.format_exc()) raise
def _create_default_perms(self, new_group): # create default permission default_perm = 'group.read' def_user = User.get_default_user() for p in def_user.user_perms: if p.permission.permission_name.startswith('group.'): default_perm = p.permission.permission_name break repo_group_to_perm = UserRepoGroupToPerm() repo_group_to_perm.permission = Permission.get_by_key(default_perm) repo_group_to_perm.group = new_group repo_group_to_perm.user_id = def_user.user_id Session().add(repo_group_to_perm) return repo_group_to_perm
def _create_default_perms(self, user_group): # create default permission default_perm = 'usergroup.read' def_user = User.get_default_user() for p in def_user.user_perms: if p.permission.permission_name.startswith('usergroup.'): default_perm = p.permission.permission_name break user_group_to_perm = UserUserGroupToPerm() user_group_to_perm.permission = Permission.get_by_key(default_perm) user_group_to_perm.user_group = user_group user_group_to_perm.user_id = def_user.user_id Session().add(user_group_to_perm) return user_group_to_perm
def grant_perm(self, user_group, perm): user_group = UserGroup.guess_instance(user_group) perm = Permission.guess_instance(perm) # if this permission is already granted skip it _perm = UserGroupToPerm.query() \ .filter(UserGroupToPerm.users_group == user_group) \ .filter(UserGroupToPerm.permission == perm) \ .scalar() if _perm: return new = UserGroupToPerm() new.users_group = user_group new.permission = perm Session().add(new) return new
def revoke_user_group_permission(self, target_user_group, user_group): """ Revoke user group permission for given target_user_group :param target_user_group: :param user_group: """ target_user_group = UserGroup.guess_instance(target_user_group) user_group = UserGroup.guess_instance(user_group) obj = UserGroupUserGroupToPerm.query() \ .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group) \ .filter(UserGroupUserGroupToPerm.user_group == user_group) \ .scalar() if obj is not None: Session().delete(obj) log.debug('Revoked perm on %s on %s', target_user_group, user_group)
def revoke_user_group_permission(self, repo, group_name): """ Revoke permission for user group on given repository :param repo: Instance of Repository, repository_id, or repository name :param group_name: Instance of UserGroup, users_group_id, or user group name """ repo = Repository.guess_instance(repo) group_name = UserGroup.guess_instance(group_name) obj = UserGroupRepoToPerm.query() \ .filter(UserGroupRepoToPerm.repository == repo) \ .filter(UserGroupRepoToPerm.users_group == group_name) \ .scalar() if obj is not None: Session().delete(obj) log.debug('Revoked perm to %s on %s', repo, group_name)
def revoke_user_permission(self, repo, user): """ Revoke permission for user on given repository :param repo: Instance of Repository, repository_id, or repository name :param user: Instance of User, user_id or username """ user = User.guess_instance(user) repo = Repository.guess_instance(repo) obj = UserRepoToPerm.query() \ .filter(UserRepoToPerm.repository == repo) \ .filter(UserRepoToPerm.user == user) \ .scalar() if obj is not None: Session().delete(obj) log.debug('Revoked perm on %s on %s', repo, user)
def _create_default_perms(self, repository, private): # create default permission default = 'repository.read' def_user = User.get_default_user() for p in def_user.user_perms: if p.permission.permission_name.startswith('repository.'): default = p.permission.permission_name break default_perm = 'repository.none' if private else default repo_to_perm = UserRepoToPerm() repo_to_perm.permission = Permission.get_by_key(default_perm) repo_to_perm.repository = repository repo_to_perm.user_id = def_user.user_id Session().add(repo_to_perm) return repo_to_perm
def revoke_user_permission(self, repo_group, user): """ Revoke permission for user on given repository group :param repo_group: Instance of RepoGroup, repositories_group_id, or repositories_group name :param user: Instance of User, user_id or username """ repo_group = RepoGroup.guess_instance(repo_group) user = User.guess_instance(user) obj = UserRepoGroupToPerm.query() \ .filter(UserRepoGroupToPerm.user == user) \ .filter(UserRepoGroupToPerm.group == repo_group) \ .scalar() if obj is not None: Session().delete(obj) log.debug('Revoked perm on %s on %s', repo_group, user)
def create(self, name, description, owner, active=True, group_data=None): try: new_user_group = UserGroup() new_user_group.owner = User.guess_instance(owner) new_user_group.users_group_name = name new_user_group.user_group_description = description new_user_group.users_group_active = active if group_data: new_user_group.group_data = group_data Session().add(new_user_group) self._create_default_perms(new_user_group) self.grant_user_permission(user_group=new_user_group, user=owner, perm='usergroup.admin') return new_user_group except Exception: log.error(traceback.format_exc()) raise
def remove_user_from_group(self, user_group, user): user_group = UserGroup.guess_instance(user_group) user = User.guess_instance(user) user_group_member = None for m in user_group.members: if m.user_id == user.user_id: # Found this user's membership row user_group_member = m break if user_group_member: try: Session().delete(user_group_member) return True except Exception: log.error(traceback.format_exc()) raise else: # User isn't in that group return False
def delete(self, user_group, force=False): """ Deletes user group, unless force flag is used raises exception if there are members in that group, else deletes group and users :param user_group: :param force: """ user_group = UserGroup.guess_instance(user_group) try: # check if this group is not assigned to repo assigned_groups = UserGroupRepoToPerm.query() \ .filter(UserGroupRepoToPerm.users_group == user_group).all() assigned_groups = [x.repository.repo_name for x in assigned_groups] if assigned_groups and not force: raise UserGroupsAssignedException('User Group assigned to %s' % ", ".join(assigned_groups)) Session().delete(user_group) except Exception: log.error(traceback.format_exc()) raise
def add_user_to_group(self, user_group, user): user_group = UserGroup.guess_instance(user_group) user = User.guess_instance(user) for m in user_group.members: u = m.user if u.user_id == user.user_id: # user already in the group, skip return True try: user_group_member = UserGroupMember() user_group_member.user = user user_group_member.users_group = user_group user_group.members.append(user_group_member) user.group_member.append(user_group_member) Session().add(user_group_member) return user_group_member except Exception: log.error(traceback.format_exc()) raise
def _create_repo(self, repo_name, repo_type, description, owner, private=False, clone_uri=None, repo_group=None, landing_rev='rev:tip', fork_of=None, copy_fork_permissions=False, enable_statistics=False, enable_locking=False, enable_downloads=False, copy_group_permissions=False, state=Repository.STATE_PENDING): """ Create repository inside database with PENDING state. This should only be executed by create() repo, with exception of importing existing repos. """ from kallithea.model.scm import ScmModel owner = User.guess_instance(owner) fork_of = Repository.guess_instance(fork_of) repo_group = RepoGroup.guess_instance(repo_group) try: repo_name = safe_unicode(repo_name) description = safe_unicode(description) # repo name is just a name of repository # while repo_name_full is a full qualified name that is combined # with name and path of group repo_name_full = repo_name repo_name = repo_name.split(self.URL_SEPARATOR)[-1] new_repo = Repository() new_repo.repo_state = state new_repo.enable_statistics = False new_repo.repo_name = repo_name_full new_repo.repo_type = repo_type new_repo.owner = owner new_repo.group = repo_group new_repo.description = description or repo_name new_repo.private = private new_repo.clone_uri = clone_uri new_repo.landing_rev = landing_rev new_repo.enable_statistics = enable_statistics new_repo.enable_locking = enable_locking new_repo.enable_downloads = enable_downloads if repo_group: new_repo.enable_locking = repo_group.enable_locking if fork_of: parent_repo = fork_of new_repo.fork = parent_repo Session().add(new_repo) if fork_of and copy_fork_permissions: repo = fork_of user_perms = UserRepoToPerm.query() \ .filter(UserRepoToPerm.repository == repo).all() group_perms = UserGroupRepoToPerm.query() \ .filter(UserGroupRepoToPerm.repository == repo).all() for perm in user_perms: UserRepoToPerm.create(perm.user, new_repo, perm.permission) for perm in group_perms: UserGroupRepoToPerm.create(perm.users_group, new_repo, perm.permission) elif repo_group and copy_group_permissions: user_perms = UserRepoGroupToPerm.query() \ .filter(UserRepoGroupToPerm.group == repo_group).all() group_perms = UserGroupRepoGroupToPerm.query() \ .filter(UserGroupRepoGroupToPerm.group == repo_group).all() for perm in user_perms: perm_name = perm.permission.permission_name.replace( 'group.', 'repository.') perm_obj = Permission.get_by_key(perm_name) UserRepoToPerm.create(perm.user, new_repo, perm_obj) for perm in group_perms: perm_name = perm.permission.permission_name.replace( 'group.', 'repository.') perm_obj = Permission.get_by_key(perm_name) UserGroupRepoToPerm.create(perm.users_group, new_repo, perm_obj) else: self._create_default_perms(new_repo, private) # now automatically start following this repository as owner ScmModel().toggle_following_repo(new_repo.repo_id, owner.user_id) # we need to flush here, in order to check if database won't # throw any exceptions, create filesystem dirs at the very end Session().flush() return new_repo except Exception: log.error(traceback.format_exc()) raise