def enforce_groups(self, user, groups, extern_type=None): user = User.guess_instance(user) log.debug('Enforcing groups %s on user %s', user, groups) current_groups = user.group_member # find the external created groups externals = [ x.users_group for x in current_groups if 'extern_type' in x.users_group.group_data ] # calculate from what groups user should be removed # externals that are not in groups for gr in externals: if gr.users_group_name not in groups: log.debug('Removing user %s from user group %s', user, gr) self.remove_user_from_group(gr, user) # now we calculate in which groups user should be == groups params owner = User.get_first_admin().username for gr in set(groups): existing_group = UserGroup.get_by_group_name(gr) if not existing_group: desc = u'Automatically created from plugin:%s' % extern_type # we use first admin account to set the owner of the group existing_group = UserGroupModel().create( gr, desc, owner, group_data={'extern_type': extern_type}) # we can only add users to special groups created via plugins managed = 'extern_type' in existing_group.group_data if managed: log.debug('Adding user %s to user group %s', user, gr) UserGroupModel().add_user_to_group(existing_group, user) else: log.debug('Skipping addition to group %s since it is ' 'not managed by auth plugins' % gr)
def _api_key_test(self, api_key, status): """Verifies HTTP status code for accessing an auth-requiring page, using the given api_key URL parameter as well as using the API key with bearer authentication. If api_key is None, no api_key is passed at all. If api_key is True, a real, working API key is used. """ with fixture.anon_access(False): if api_key is None: params = {} headers = {} else: if api_key is True: api_key = User.get_first_admin().api_key params = {'api_key': api_key} headers = {'Authorization': 'Bearer ' + str(api_key)} self.app.get(base.url(controller='changeset', action='changeset_raw', repo_name=base.HG_REPO, revision='tip', **params), status=status) self.app.get(base.url(controller='changeset', action='changeset_raw', repo_name=base.HG_REPO, revision='tip'), headers=headers, status=status)
def enforce_groups(self, user, groups, extern_type=None): user = User.guess_instance(user) log.debug('Enforcing groups %s on user %s', user, groups) current_groups = user.group_member # find the external created groups externals = [x.users_group for x in current_groups if 'extern_type' in x.users_group.group_data] # calculate from what groups user should be removed # externals that are not in groups for gr in externals: if gr.users_group_name not in groups: log.debug('Removing user %s from user group %s', user, gr) self.remove_user_from_group(gr, user) # now we calculate in which groups user should be == groups params owner = User.get_first_admin().username for gr in set(groups): existing_group = UserGroup.get_by_group_name(gr) if not existing_group: desc = u'Automatically created from plugin:%s' % extern_type # we use first admin account to set the owner of the group existing_group = UserGroupModel().create(gr, desc, owner, group_data={'extern_type': extern_type}) # we can only add users to special groups created via plugins managed = 'extern_type' in existing_group.group_data if managed: log.debug('Adding user %s to user group %s', user, gr) UserGroupModel().add_user_to_group(existing_group, user) else: log.debug('Skipping addition to group %s since it is ' 'not managed by auth plugins' % gr)
def test_access_whitelisted_page_via_api_key(self, test_name, api_key, code): whitelist = self._get_api_whitelist(['ChangesetController:changeset_raw']) with mock.patch('kallithea.CONFIG', whitelist): self.assertEqual(['ChangesetController:changeset_raw'], whitelist['api_access_controllers_whitelist']) if test_name == 'proper_api_key': api_key = User.get_first_admin().api_key with fixture.anon_access(False): self.app.get(url(controller='changeset', action='changeset_raw', repo_name=HG_REPO, revision='tip', api_key=api_key), status=code)
def test_access_not_whitelisted_page_via_api_key(self, test_name, api_key): whitelist = self._get_api_whitelist([]) with mock.patch('kallithea.CONFIG', whitelist): self.assertEqual([], whitelist['api_access_controllers_whitelist']) if test_name == 'proper_api_key': #use builtin if api_key is None api_key = User.get_first_admin().api_key with fixture.anon_access(False): self.app.get(url(controller='changeset', action='changeset_raw', repo_name=HG_REPO, revision='tip', api_key=api_key), status=302)
def map_groups(path): """ Given a full path to a repository, create all nested groups that this repo is inside. This function creates parent-child relationships between groups and creates default perms for all new groups. :param paths: full path to repository """ sa = meta.Session() groups = path.split(Repository.url_sep()) parent = None group = None # last element is repo in nested groups structure groups = groups[:-1] rgm = RepoGroupModel(sa) owner = User.get_first_admin() for lvl, group_name in enumerate(groups): group_name = u'/'.join(groups[:lvl] + [group_name]) group = RepoGroup.get_by_group_name(group_name) desc = '%s group' % group_name # skip folders that are now removed repos if REMOVED_REPO_PAT.match(group_name): break if group is None: log.debug('creating group level: %s group_name: %s', lvl, group_name) group = RepoGroup(group_name, parent) group.group_description = desc group.user = owner sa.add(group) perm_obj = rgm._create_default_perms(group) sa.add(perm_obj) sa.flush() parent = group return group
def map_groups(path): """ Given a full path to a repository, create all nested groups that this repo is inside. This function creates parent-child relationships between groups and creates default perms for all new groups. :param paths: full path to repository """ from kallithea.model.repo_group import RepoGroupModel sa = meta.Session() groups = path.split(db.URL_SEP) parent = None group = None # last element is repo in nested groups structure groups = groups[:-1] rgm = RepoGroupModel() owner = User.get_first_admin() for lvl, group_name in enumerate(groups): group_name = '/'.join(groups[:lvl] + [group_name]) group = RepoGroup.get_by_group_name(group_name) desc = '%s group' % group_name # skip folders that are now removed repos if REMOVED_REPO_PAT.match(group_name): break if group is None: log.debug('creating group level: %s group_name: %s', lvl, group_name) group = RepoGroup(group_name, parent) group.group_description = desc group.owner = owner sa.add(group) rgm._create_default_perms(group) sa.flush() parent = group return group
def repo2db_mapper(initial_repo_list, remove_obsolete=False, install_git_hooks=False, user=None, overwrite_git_hooks=False): """ maps all repos given in initial_repo_list, non existing repositories are created, if remove_obsolete is True it also check for db entries that are not in initial_repo_list and removes them. :param initial_repo_list: list of repositories found by scanning methods :param remove_obsolete: check for obsolete entries in database :param install_git_hooks: if this is True, also check and install git hook for a repo if missing :param overwrite_git_hooks: if this is True, overwrite any existing git hooks that may be encountered (even if user-deployed) """ from kallithea.model.repo import RepoModel from kallithea.model.scm import ScmModel sa = meta.Session() repo_model = RepoModel() if user is None: user = User.get_first_admin() added = [] ##creation defaults defs = Setting.get_default_repo_settings(strip_prefix=True) enable_statistics = defs.get('repo_enable_statistics') enable_locking = defs.get('repo_enable_locking') enable_downloads = defs.get('repo_enable_downloads') private = defs.get('repo_private') for name, repo in initial_repo_list.items(): group = map_groups(name) unicode_name = safe_unicode(name) db_repo = repo_model.get_by_repo_name(unicode_name) # found repo that is on filesystem not in Kallithea database if not db_repo: log.info('repository %s not found, creating now', name) added.append(name) desc = (repo.description if repo.description != 'unknown' else '%s repository' % name) new_repo = repo_model._create_repo( repo_name=name, repo_type=repo.alias, description=desc, repo_group=getattr(group, 'group_id', None), owner=user, enable_locking=enable_locking, enable_downloads=enable_downloads, enable_statistics=enable_statistics, private=private, state=Repository.STATE_CREATED ) sa.commit() # we added that repo just now, and make sure it has githook # installed, and updated server info if new_repo.repo_type == 'git': git_repo = new_repo.scm_instance ScmModel().install_git_hooks(git_repo) # update repository server-info log.debug('Running update server info') git_repo._update_server_info() new_repo.update_changeset_cache() elif install_git_hooks: if db_repo.repo_type == 'git': ScmModel().install_git_hooks(db_repo.scm_instance, force_create=overwrite_git_hooks) removed = [] # remove from database those repositories that are not in the filesystem unicode_initial_repo_list = set(safe_unicode(name) for name in initial_repo_list) for repo in sa.query(Repository).all(): if repo.repo_name not in unicode_initial_repo_list: if remove_obsolete: log.debug("Removing non-existing repository found in db `%s`", repo.repo_name) try: RepoModel(sa).delete(repo, forks='detach', fs_remove=False) sa.commit() except Exception: #don't hold further removals on error log.error(traceback.format_exc()) sa.rollback() removed.append(repo.repo_name) return added, removed
def repo2db_mapper(initial_repo_dict, remove_obsolete=False, install_git_hooks=False, user=None, overwrite_git_hooks=False): """ maps all repos given in initial_repo_dict, non existing repositories are created, if remove_obsolete is True it also check for db entries that are not in initial_repo_dict and removes them. :param initial_repo_dict: mapping with repositories found by scanning methods :param remove_obsolete: check for obsolete entries in database :param install_git_hooks: if this is True, also check and install git hook for a repo if missing :param overwrite_git_hooks: if this is True, overwrite any existing git hooks that may be encountered (even if user-deployed) """ from kallithea.model.repo import RepoModel from kallithea.model.scm import ScmModel sa = meta.Session() repo_model = RepoModel() if user is None: user = User.get_first_admin() added = [] # creation defaults defs = Setting.get_default_repo_settings(strip_prefix=True) enable_statistics = defs.get('repo_enable_statistics') enable_downloads = defs.get('repo_enable_downloads') private = defs.get('repo_private') for name, repo in initial_repo_dict.items(): group = map_groups(name) db_repo = repo_model.get_by_repo_name(name) # found repo that is on filesystem not in Kallithea database if not db_repo: log.info('repository %s not found, creating now', name) added.append(name) desc = (repo.description if repo.description != 'unknown' else '%s repository' % name) new_repo = repo_model._create_repo( repo_name=name, repo_type=repo.alias, description=desc, repo_group=getattr(group, 'group_id', None), owner=user, enable_downloads=enable_downloads, enable_statistics=enable_statistics, private=private, state=Repository.STATE_CREATED) sa.commit() # we added that repo just now, and make sure it has githook # installed, and updated server info if new_repo.repo_type == 'git': git_repo = new_repo.scm_instance ScmModel().install_git_hooks(git_repo) # update repository server-info log.debug('Running update server info') git_repo._update_server_info() new_repo.update_changeset_cache() elif install_git_hooks: if db_repo.repo_type == 'git': ScmModel().install_git_hooks(db_repo.scm_instance, force_create=overwrite_git_hooks) removed = [] # remove from database those repositories that are not in the filesystem for repo in sa.query(Repository).all(): if repo.repo_name not in initial_repo_dict: if remove_obsolete: log.debug("Removing non-existing repository found in db `%s`", repo.repo_name) try: RepoModel().delete(repo, forks='detach', fs_remove=False) sa.commit() except Exception: #don't hold further removals on error log.error(traceback.format_exc()) sa.rollback() removed.append(repo.repo_name) return added, removed