def test_delete_non_ascii(self): self.log_user() non_ascii = "ąęł" repo_name = "%s%s" % (self.NEW_REPO, non_ascii) description = 'description for newly created repo' + non_ascii response = self.app.post( base.url('repos'), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=self.REPO_TYPE, repo_description=description, _session_csrf_secret_token=self.session_csrf_secret_token())) ## run the check page that triggers the flash message response = self.app.get( base.url('repo_check_home', repo_name=repo_name)) assert response.json == {'result': True} self.checkSessionFlash( response, 'Created repository <a href="/%s">%s</a>' % (urllib.parse.quote(repo_name), repo_name)) # test if the repo was created in the database new_repo = Session().query(Repository) \ .filter(Repository.repo_name == repo_name).one() assert new_repo.repo_name == repo_name assert new_repo.description == description # test if the repository is visible in the list ? response = self.app.get(base.url('summary_home', repo_name=repo_name)) response.mustcontain(repo_name) response.mustcontain(self.REPO_TYPE) # test if the repository was created on filesystem try: vcs.get_repo( os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name)) except vcs.exceptions.VCSError: pytest.fail('no repo %s in filesystem' % repo_name) response = self.app.post(base.url('delete_repo', repo_name=repo_name), params={ '_session_csrf_secret_token': self.session_csrf_secret_token() }) self.checkSessionFlash(response, 'Deleted repository %s' % (repo_name)) response.follow() # check if repo was deleted from db deleted_repo = Session().query(Repository) \ .filter(Repository.repo_name == repo_name).scalar() assert deleted_repo is None assert os.path.isdir( os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name)) == False
def settings_hooks(self): c.active = 'hooks' if request.POST: if c.visual.allow_custom_hooks_settings: ui_key = request.POST.get('new_hook_ui_key') ui_value = request.POST.get('new_hook_ui_value') hook_id = request.POST.get('hook_id') try: ui_key = ui_key and ui_key.strip() if ui_key in (x.ui_key for x in Ui.get_custom_hooks()): h.flash(_('Hook already exists'), category='error') elif ui_key in (x.ui_key for x in Ui.get_builtin_hooks()): h.flash(_('Builtin hooks are read-only. Please use another hook name.'), category='error') elif ui_value and ui_key: Ui.create_or_update_hook(ui_key, ui_value) h.flash(_('Added new hook'), category='success') elif hook_id: Ui.delete(hook_id) Session().commit() # check for edits update = False _d = request.POST.dict_of_lists() for k, v, ov in zip(_d.get('hook_ui_key', []), _d.get('hook_ui_value_new', []), _d.get('hook_ui_value', [])): if v != ov: Ui.create_or_update_hook(k, v) update = True if update: h.flash(_('Updated hooks'), category='success') Session().commit() except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred during hook creation'), category='error') raise HTTPFound(location=url('admin_settings_hooks')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) c.hooks = Ui.get_builtin_hooks() c.custom_hooks = Ui.get_custom_hooks() return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def test_delete_non_ascii(self): self.log_user() non_ascii = "ąęł" repo_name = "%s%s" % (safe_str(self.NEW_REPO), non_ascii) repo_name_unicode = safe_unicode(repo_name) description = 'description for newly created repo' + non_ascii description_unicode = safe_unicode(description) response = self.app.post(url('repos'), fixture._get_repo_create_params(repo_private=False, repo_name=repo_name, repo_type=self.REPO_TYPE, repo_description=description, _authentication_token=self.authentication_token())) ## run the check page that triggers the flash message response = self.app.get(url('repo_check_home', repo_name=repo_name)) self.assertEqual(response.json, {u'result': True}) self.checkSessionFlash(response, u'Created repository <a href="/%s">%s</a>' % (urllib.quote(repo_name), repo_name_unicode)) # test if the repo was created in the database new_repo = Session().query(Repository) \ .filter(Repository.repo_name == repo_name_unicode).one() self.assertEqual(new_repo.repo_name, repo_name_unicode) self.assertEqual(new_repo.description, description_unicode) # test if the repository is visible in the list ? response = self.app.get(url('summary_home', repo_name=repo_name)) response.mustcontain(repo_name) response.mustcontain(self.REPO_TYPE) # test if the repository was created on filesystem try: vcs.get_repo(safe_str(os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name_unicode))) except vcs.exceptions.VCSError: pytest.fail('no repo %s in filesystem' % repo_name) response = self.app.post(url('delete_repo', repo_name=repo_name), params={'_method': 'delete', '_authentication_token': self.authentication_token()}) self.checkSessionFlash(response, 'Deleted repository %s' % (repo_name_unicode)) response.follow() #check if repo was deleted from db deleted_repo = Session().query(Repository) \ .filter(Repository.repo_name == repo_name_unicode).scalar() self.assertEqual(deleted_repo, None) self.assertEqual(os.path.isdir(os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name_unicode)), False)
def repos_path(self): """ Gets the repositories root path from database """ q = Ui.query().filter(Ui.ui_key == '/').one() return q.ui_value
def fork_create(self, repo_name): self.__load_defaults() c.repo_info = Repository.get_by_repo_name(repo_name) _form = RepoForkForm(old_data={'repo_type': c.repo_info.repo_type}, repo_groups=c.repo_groups, landing_revs=c.landing_revs_choices)() form_result = {} task_id = None try: form_result = _form.to_python(dict(request.POST)) # an approximation that is better than nothing if not Ui.get_by_key('hooks', Ui.HOOK_UPDATE).ui_active: form_result['update_after_clone'] = False # create fork is done sometimes async on celery, db transaction # management is handled there. task = RepoModel().create_fork(form_result, request.authuser.user_id) task_id = task.task_id except formencode.Invalid as errors: return htmlfill.render( render('forks/fork.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except Exception: log.error(traceback.format_exc()) h.flash(_('An error occurred during repository forking %s') % repo_name, category='error') raise HTTPFound(location=h.url('repo_creating_home', repo_name=form_result['repo_name_full'], task_id=task_id))
def fork_create(self, repo_name): self.__load_defaults() c.repo_info = Repository.get_by_repo_name(repo_name) _form = RepoForkForm(old_data={'repo_type': c.repo_info.repo_type}, repo_groups=c.repo_groups_choices, landing_revs=c.landing_revs_choices)() form_result = {} task_id = None try: form_result = _form.to_python(dict(request.POST)) # an approximation that is better than nothing if not Ui.get_by_key(Ui.HOOK_UPDATE).ui_active: form_result['update_after_clone'] = False # create fork is done sometimes async on celery, db transaction # management is handled there. task = RepoModel().create_fork(form_result, self.authuser.user_id) from celery.result import BaseAsyncResult if isinstance(task, BaseAsyncResult): task_id = task.task_id except formencode.Invalid, errors: c.new_repo = errors.value['repo_name'] return htmlfill.render( render('forks/fork.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False)
def repos_path(self): """ Gets the repositories root path from database """ q = Ui.get_by_key('/') return q.ui_value
def test_clone_with_credentials(no_errors=False, repo=HG_REPO, method=METHOD, seq=None, backend='hg'): cwd = path = jn(Ui.get_by_key('paths', '/').ui_value, repo) if seq is None: seq = _RandomNameSequence().next() try: shutil.rmtree(path, ignore_errors=True) os.makedirs(path) #print 'made dirs %s' % jn(path) except OSError: raise clone_url = 'http://%(user)s:%(pass)s@%(host)s/%(cloned_repo)s' % \ {'user': USER, 'pass': PASS, 'host': HOST, 'cloned_repo': repo, } dest = path + seq if method == 'pull': stdout, stderr = Command(cwd).execute(backend, method, '--cwd', dest, clone_url) else: stdout, stderr = Command(cwd).execute(backend, method, clone_url, dest) print stdout,'sdasdsadsa' if not no_errors: if backend == 'hg': assert """adding file changes""" in stdout, 'no messages about cloning' assert """abort""" not in stderr , 'got error from clone' elif backend == 'git': assert """Cloning into""" in stdout, 'no messages about cloning'
def repos_path(self): """ Gets the repositories root path from database """ q = Ui.get_by_key('paths', '/') return q.ui_value
def test_clone_with_credentials(no_errors=False, repo=HG_REPO, method=METHOD, backend='hg'): cwd = path = os.path.join(Ui.get_by_key('paths', '/').ui_value, repo) try: shutil.rmtree(path, ignore_errors=True) os.makedirs(path) #print 'made dirs %s' % os.path.join(path) except OSError: raise clone_url = 'http://%(user)s:%(pass)s@%(host)s/%(cloned_repo)s' % \ {'user': USER, 'pass': PASS, 'host': HOST, 'cloned_repo': repo, } dest = tempfile.mktemp(dir=path, prefix='dest-') if method == 'pull': stdout, stderr = Command(cwd).execute(backend, method, '--cwd', dest, clone_url) else: stdout, stderr = Command(cwd).execute(backend, method, clone_url, dest) if not no_errors: if backend == 'hg': assert """adding file changes""" in stdout, 'no messages about cloning' assert """abort""" not in stderr, 'got error from clone' elif backend == 'git': assert """Cloning into""" in stdout, 'no messages about cloning'
def test_create_in_group(self): self.log_user() ## create GROUP group_name = 'sometest_%s' % self.REPO_TYPE gr = RepoGroupModel().create(group_name=group_name, group_description='test', owner=base.TEST_USER_ADMIN_LOGIN) Session().commit() repo_name = 'ingroup' repo_name_full = db.URL_SEP.join([group_name, repo_name]) description = 'description for newly created repo' response = self.app.post( base.url('repos'), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=self.REPO_TYPE, repo_description=description, repo_group=gr.group_id, _session_csrf_secret_token=self.session_csrf_secret_token())) ## run the check page that triggers the flash message response = self.app.get( base.url('repo_check_home', repo_name=repo_name_full)) assert response.json == {'result': True} self.checkSessionFlash( response, 'Created repository <a href="/%s">%s</a>' % (repo_name_full, repo_name_full)) # test if the repo was created in the database new_repo = Session().query(Repository) \ .filter(Repository.repo_name == repo_name_full).one() new_repo_id = new_repo.repo_id assert new_repo.repo_name == repo_name_full assert new_repo.description == description # test if the repository is visible in the list ? response = self.app.get( base.url('summary_home', repo_name=repo_name_full)) response.mustcontain(repo_name_full) response.mustcontain(self.REPO_TYPE) inherited_perms = UserRepoToPerm.query() \ .filter(UserRepoToPerm.repository_id == new_repo_id).all() assert len(inherited_perms) == 1 # test if the repository was created on filesystem try: vcs.get_repo( os.path.join( Ui.get_by_key('paths', '/').ui_value, repo_name_full)) except vcs.exceptions.VCSError: RepoGroupModel().delete(group_name) Session().commit() pytest.fail('no repo %s in filesystem' % repo_name) RepoModel().delete(repo_name_full) RepoGroupModel().delete(group_name) Session().commit()
def test_delete(self): self.log_user() repo_name = u'vcs_test_new_to_delete_%s' % self.REPO_TYPE description = u'description for newly created repo' response = self.app.post(url('repos'), fixture._get_repo_create_params(repo_private=False, repo_type=self.REPO_TYPE, repo_name=repo_name, repo_description=description, _authentication_token=self.authentication_token())) ## run the check page that triggers the flash message response = self.app.get(url('repo_check_home', repo_name=repo_name)) self.checkSessionFlash(response, 'Created repository <a href="/%s">%s</a>' % (repo_name, repo_name)) # test if the repo was created in the database new_repo = Session().query(Repository) \ .filter(Repository.repo_name == repo_name).one() assert new_repo.repo_name == repo_name assert new_repo.description == description # test if the repository is visible in the list ? response = self.app.get(url('summary_home', repo_name=repo_name)) response.mustcontain(repo_name) response.mustcontain(self.REPO_TYPE) # test if the repository was created on filesystem try: vcs.get_repo(safe_str(os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name))) except vcs.exceptions.VCSError: pytest.fail('no repo %s in filesystem' % repo_name) response = self.app.post(url('delete_repo', repo_name=repo_name), params={'_authentication_token': self.authentication_token()}) self.checkSessionFlash(response, 'Deleted repository %s' % (repo_name)) response.follow() #check if repo was deleted from db deleted_repo = Session().query(Repository) \ .filter(Repository.repo_name == repo_name).scalar() assert deleted_repo == None assert os.path.isdir(os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name)) == False
def __load_defaults(self): acl_groups = RepoGroupList(RepoGroup.query().all(), perm_set=['group.write', 'group.admin']) c.repo_groups = RepoGroup.groups_choices(groups=acl_groups) c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) choices, c.landing_revs = ScmModel().get_repo_landing_revs() c.landing_revs_choices = choices c.can_update = Ui.get_by_key(Ui.HOOK_UPDATE).ui_active
def __load_defaults(self): repo_group_perms = ['group.admin'] if HasPermissionAny('hg.create.write_on_repogroup.true')(): repo_group_perms.append('group.write') c.repo_groups = AvailableRepoGroupChoices(['hg.create.repository'], repo_group_perms) c.landing_revs_choices, c.landing_revs = ScmModel().get_repo_landing_revs() c.can_update = Ui.get_by_key('hooks', Ui.HOOK_UPDATE).ui_active
def set_app_settings(config): """ Updates app config with new settings from database :param config: """ hgsettings = Setting.get_app_settings() for k, v in hgsettings.items(): config[k] = v config['base_path'] = Ui.get_repos_location()
def test_custom_hooks_preoutgoing(self, testhook_cleanup, webserver, testfork, vt): # set prechangegroup to failing hook (returns True) Ui.create_or_update_hook( 'preoutgoing.testhook', 'python:kallithea.tests.fixture.failing_test_hook') Session().commit() # clone repo clone_url = vt.repo_url_param(webserver, testfork[vt.repo_type], username=base.TEST_USER_ADMIN_LOGIN, password=base.TEST_USER_ADMIN_PASS) dest_dir = _get_tmp_dir() stdout, stderr = Command(base.TESTS_TMP_PATH) \ .execute(vt.repo_type, 'clone', clone_url, dest_dir, ignoreReturnCode=True) if vt.repo_type == 'hg': assert 'preoutgoing.testhook hook failed' in stdout elif vt.repo_type == 'git': assert 'error: 406' in stderr
def command(self): #get SqlAlchemy session self._init_session() repos_location = Ui.get_repos_location() to_remove = [] for dn, dirs, f in os.walk(safe_str(repos_location)): alldirs = list(dirs) del dirs[:] if ('.hg' in alldirs or 'objects' in alldirs and ('refs' in alldirs or 'packed-refs' in f)): continue for loc in alldirs: if REMOVED_REPO_PAT.match(loc): to_remove.append( [os.path.join(dn, loc), self._extract_date(loc)]) else: dirs.append(loc) #filter older than (if present)! now = datetime.datetime.now() older_than = self.options.older_than if older_than: to_remove_filtered = [] older_than_date = self._parse_older_than(older_than) for name, date_ in to_remove: repo_age = now - date_ if repo_age > older_than_date: to_remove_filtered.append([name, date_]) to_remove = to_remove_filtered print >> sys.stdout, 'removing %s deleted repos older than %s (%s)' \ % (len(to_remove), older_than, older_than_date) else: print >> sys.stdout, 'removing all [%s] deleted repos' \ % len(to_remove) if self.options.dont_ask or not to_remove: # don't ask just remove ! remove = True else: remove = ask_ok( 'the following repositories will be deleted completely:\n%s\n' 'are you sure you want to remove them [y/n]?' % ', \n'.join([ '%s removed on %s' % (safe_str(x[0]), safe_str(x[1])) for x in to_remove ])) if remove: for path, date_ in to_remove: print >> sys.stdout, 'removing repository %s' % path shutil.rmtree(path) else: print 'nothing done exiting...' sys.exit(0)
def testhook_cleanup(self): yield # remove hook for hook in [ 'prechangegroup', 'pretxnchangegroup', 'preoutgoing', 'changegroup', 'outgoing', 'incoming' ]: entry = Ui.get_by_key('hooks', '%s.testhook' % hook) if entry: Session().delete(entry) Session().commit()
def test_create_in_group(self): self.log_user() ## create GROUP group_name = u'sometest_%s' % self.REPO_TYPE gr = RepoGroupModel().create(group_name=group_name, group_description=u'test', owner=TEST_USER_ADMIN_LOGIN) Session().commit() repo_name = u'ingroup' repo_name_full = RepoGroup.url_sep().join([group_name, repo_name]) description = u'description for newly created repo' response = self.app.post(url('repos'), fixture._get_repo_create_params(repo_private=False, repo_name=repo_name, repo_type=self.REPO_TYPE, repo_description=description, repo_group=gr.group_id, _authentication_token=self.authentication_token())) ## run the check page that triggers the flash message response = self.app.get(url('repo_check_home', repo_name=repo_name_full)) self.assertEqual(response.json, {u'result': True}) self.checkSessionFlash(response, 'Created repository <a href="/%s">%s</a>' % (repo_name_full, repo_name_full)) # test if the repo was created in the database new_repo = Session().query(Repository) \ .filter(Repository.repo_name == repo_name_full).one() new_repo_id = new_repo.repo_id self.assertEqual(new_repo.repo_name, repo_name_full) self.assertEqual(new_repo.description, description) # test if the repository is visible in the list ? response = self.app.get(url('summary_home', repo_name=repo_name_full)) response.mustcontain(repo_name_full) response.mustcontain(self.REPO_TYPE) inherited_perms = UserRepoToPerm.query() \ .filter(UserRepoToPerm.repository_id == new_repo_id).all() self.assertEqual(len(inherited_perms), 1) # test if the repository was created on filesystem try: vcs.get_repo(safe_str(os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name_full))) except vcs.exceptions.VCSError: RepoGroupModel().delete(group_name) Session().commit() pytest.fail('no repo %s in filesystem' % repo_name) RepoModel().delete(repo_name_full) RepoGroupModel().delete(group_name) Session().commit()
def fix_repo_paths(self): """ Fixes a old kallithea version path into new one without a '*' """ paths = Ui.query() \ .filter(Ui.ui_key == '/') \ .scalar() paths.ui_value = paths.ui_value.replace('*', '') self.sa.commit()
def __load_defaults(self): if HasPermissionAny('hg.create.write_on_repogroup.true')(): repo_group_perm_level = 'write' else: repo_group_perm_level = 'admin' c.repo_groups = AvailableRepoGroupChoices(['hg.create.repository'], repo_group_perm_level) c.landing_revs_choices, c.landing_revs = ScmModel( ).get_repo_landing_revs() c.can_update = Ui.get_by_key('hooks', Ui.HOOK_UPDATE).ui_active
def take_action(self, args): repos_location = Ui.get_repos_location() to_remove = [] for dn_, dirs, f in os.walk(safe_str(repos_location)): alldirs = list(dirs) del dirs[:] if ('.hg' in alldirs or '.git' in alldirs or '.svn' in alldirs or 'objects' in alldirs and ('refs' in alldirs or 'packed-refs' in f)): continue for loc in alldirs: if REMOVED_REPO_PAT.match(loc): to_remove.append( [os.path.join(dn_, loc), self._extract_date(loc)]) else: dirs.append(loc) if dirs: print 'Scanning: %s' % dn_ #filter older than (if present)! now = datetime.datetime.now() older_than = args.older_than if older_than: to_remove_filtered = [] older_than_date = self._parse_older_than(older_than) for name, date_ in to_remove: repo_age = now - date_ if repo_age > older_than_date: to_remove_filtered.append([name, date_]) to_remove = to_remove_filtered print 'Removing %s deleted repos older than %s (%s)' \ % (len(to_remove), older_than, older_than_date) else: print 'Removing all %s deleted repos' % len(to_remove) if args.dont_ask or not to_remove: # don't ask just remove ! remove = True else: remove = ask_ok( 'the following repositories will be deleted completely:\n%s\n' 'are you sure you want to remove them [y/n]?' % '\n'.join([ '%s removed on %s' % (safe_str(x[0]), safe_str(x[1])) for x in to_remove ])) if remove: for path, date_ in to_remove: print 'Removing repository %s' % path shutil.rmtree(path) else: print 'Nothing done, exiting...'
def command(self): #get SqlAlchemy session self._init_session() repos_location = Ui.get_repos_location() to_remove = [] for dn, dirs, f in os.walk(safe_str(repos_location)): alldirs = list(dirs) del dirs[:] if ('.hg' in alldirs or 'objects' in alldirs and ('refs' in alldirs or 'packed-refs' in f)): continue for loc in alldirs: if REMOVED_REPO_PAT.match(loc): to_remove.append([os.path.join(dn, loc), self._extract_date(loc)]) else: dirs.append(loc) #filter older than (if present)! now = datetime.datetime.now() older_than = self.options.older_than if older_than: to_remove_filtered = [] older_than_date = self._parse_older_than(older_than) for name, date_ in to_remove: repo_age = now - date_ if repo_age > older_than_date: to_remove_filtered.append([name, date_]) to_remove = to_remove_filtered print >> sys.stdout, 'removing %s deleted repos older than %s (%s)' \ % (len(to_remove), older_than, older_than_date) else: print >> sys.stdout, 'removing all [%s] deleted repos' \ % len(to_remove) if self.options.dont_ask or not to_remove: # don't ask just remove ! remove = True else: remove = ask_ok('the following repositories will be deleted completely:\n%s\n' 'are you sure you want to remove them [y/n]?' % ', \n'.join(['%s removed on %s' % (safe_str(x[0]), safe_str(x[1])) for x in to_remove])) if remove: for path, date_ in to_remove: print >> sys.stdout, 'removing repository %s' % path shutil.rmtree(path) else: print 'nothing done exiting...' sys.exit(0)
def _check_ssl(self, environ): """ Checks the SSL check flag and returns False if SSL is not present and required True otherwise """ #check if we have SSL required ! if not it's a bad request ! if str2bool(Ui.get_by_key('web', 'push_ssl').ui_value): org_proto = environ.get('wsgi._org_proto', environ['wsgi.url_scheme']) if org_proto != 'https': log.debug('proto is %s and SSL is required BAD REQUEST !', org_proto) return False return True
def settings_hooks(self): """GET /admin/settings/hooks: All items in the collection""" # url('admin_settings_hooks') c.active = 'hooks' if request.POST: if c.visual.allow_custom_hooks_settings: ui_key = request.POST.get('new_hook_ui_key') ui_value = request.POST.get('new_hook_ui_value') hook_id = request.POST.get('hook_id') try: ui_key = ui_key and ui_key.strip() if ui_value and ui_key: Ui.create_or_update_hook(ui_key, ui_value) h.flash(_('Added new hook'), category='success') elif hook_id: Ui.delete(hook_id) Session().commit() # check for edits update = False _d = request.POST.dict_of_lists() for k, v in zip(_d.get('hook_ui_key', []), _d.get('hook_ui_value_new', [])): Ui.create_or_update_hook(k, v) update = True if update: h.flash(_('Updated hooks'), category='success') Session().commit() except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred during hook creation'), category='error') raise HTTPFound(location=url('admin_settings_hooks')) defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) c.hooks = Ui.get_builtin_hooks() c.custom_hooks = Ui.get_custom_hooks() return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def take_action(self, args): repos_location = Ui.get_repos_location() to_remove = [] for dn_, dirs, f in os.walk(safe_str(repos_location)): alldirs = list(dirs) del dirs[:] if ('.hg' in alldirs or '.git' in alldirs or '.svn' in alldirs or 'objects' in alldirs and ('refs' in alldirs or 'packed-refs' in f)): continue for loc in alldirs: if REMOVED_REPO_PAT.match(loc): to_remove.append([os.path.join(dn_, loc), self._extract_date(loc)]) else: dirs.append(loc) if dirs: print 'Scanning: %s' % dn_ #filter older than (if present)! now = datetime.datetime.now() older_than = args.older_than if older_than: to_remove_filtered = [] older_than_date = self._parse_older_than(older_than) for name, date_ in to_remove: repo_age = now - date_ if repo_age > older_than_date: to_remove_filtered.append([name, date_]) to_remove = to_remove_filtered print 'Removing %s deleted repos older than %s (%s)' \ % (len(to_remove), older_than, older_than_date) else: print 'Removing all %s deleted repos' % len(to_remove) if args.dont_ask or not to_remove: # don't ask just remove ! remove = True else: remove = ask_ok('the following repositories will be deleted completely:\n%s\n' 'are you sure you want to remove them [y/n]?' % '\n'.join(['%s removed on %s' % (safe_str(x[0]), safe_str(x[1])) for x in to_remove])) if remove: for path, date_ in to_remove: print 'Removing repository %s' % path shutil.rmtree(path) else: print 'Nothing done, exiting...'
def _check_ssl(self, environ): """ Checks the SSL check flag and returns False if SSL is not present and required True otherwise """ #check if we have SSL required ! if not it's a bad request ! if str2bool(Ui.get_by_key('push_ssl').ui_value): org_proto = environ.get('wsgi._org_proto', environ['wsgi.url_scheme']) if org_proto != 'https': log.debug('proto is %s and SSL is required BAD REQUEST !' % org_proto) return False return True
def _get_hg_ui_settings(self): ret = Ui.query().all() settings = {} for each in ret: k = each.ui_section + '_' + each.ui_key v = each.ui_value if k == 'paths_/': k = 'paths_root_path' k = k.replace('.', '_') if each.ui_section in ['hooks', 'extensions']: v = each.ui_active settings[k] = v return settings
def test_create_custom_hook_delete(self): self.log_user() response = self.app.post(url('admin_settings_hooks'), params=dict(new_hook_ui_key='test_hooks_2', new_hook_ui_value='cd /tmp2')) response = response.follow() response.mustcontain('test_hooks_2') response.mustcontain('cd /tmp2') hook_id = Ui.get_by_key('test_hooks_2').ui_id ## delete self.app.post(url('admin_settings_hooks'), params=dict(hook_id=hook_id)) response = self.app.get(url('admin_settings_hooks')) response.mustcontain(no=['test_hooks_2']) response.mustcontain(no=['cd /tmp2'])
def test_create_custom_hook_delete(self): self.log_user() response = self.app.post(url('admin_settings_hooks'), params=dict(new_hook_ui_key='test_hooks_2', new_hook_ui_value='cd %s2' % tempfile.gettempdir(), _authentication_token=self.authentication_token())) response = response.follow() response.mustcontain('test_hooks_2') response.mustcontain('cd %s2' % tempfile.gettempdir()) hook_id = Ui.get_by_key('hooks', 'test_hooks_2').ui_id ## delete self.app.post(url('admin_settings_hooks'), params=dict(hook_id=hook_id, _authentication_token=self.authentication_token())) response = self.app.get(url('admin_settings_hooks')) response.mustcontain(no=['test_hooks_2']) response.mustcontain(no=['cd %s2' % tempfile.gettempdir()])
def test_create_custom_hook_delete(self): self.log_user() response = self.app.post(base.url('admin_settings_hooks'), params=dict(new_hook_ui_key='test_hooks_2', new_hook_ui_value='cd %s2' % base.TESTS_TMP_PATH, _session_csrf_secret_token=self.session_csrf_secret_token())) self.checkSessionFlash(response, 'Added new hook') response = response.follow() response.mustcontain('test_hooks_2') response.mustcontain('cd %s2' % base.TESTS_TMP_PATH) hook_id = Ui.get_by_key('hooks', 'test_hooks_2').ui_id ## delete self.app.post(base.url('admin_settings_hooks'), params=dict(hook_id=hook_id, _session_csrf_secret_token=self.session_csrf_secret_token())) response = self.app.get(base.url('admin_settings_hooks')) response.mustcontain(no=['test_hooks_2']) response.mustcontain(no=['cd %s2' % base.TESTS_TMP_PATH])
def create_settings(self, repo_root_path): ui_config = [ ('paths', '/', repo_root_path, True), #('phases', 'publish', 'false', False) ('hooks', Ui.HOOK_UPDATE, 'hg update >&2', False), ('hooks', Ui.HOOK_REPO_SIZE, 'python:kallithea.lib.hooks.repo_size', True), ('extensions', 'largefiles', '', True), ('largefiles', 'usercache', os.path.join(repo_root_path, '.cache', 'largefiles'), True), ('extensions', 'hgsubversion', '', False), ('extensions', 'hggit', '', False), ] for ui_section, ui_key, ui_value, ui_active in ui_config: ui_conf = Ui( ui_section=ui_section, ui_key=ui_key, ui_value=ui_value, ui_active=ui_active) self.sa.add(ui_conf) settings = [ ('realm', 'Kallithea', 'unicode'), ('title', '', 'unicode'), ('ga_code', '', 'unicode'), ('show_public_icon', True, 'bool'), ('show_private_icon', True, 'bool'), ('stylify_metalabels', False, 'bool'), ('dashboard_items', 100, 'int'), # TODO: call it page_size ('admin_grid_items', 25, 'int'), ('show_version', True, 'bool'), ('use_gravatar', True, 'bool'), ('gravatar_url', User.DEFAULT_GRAVATAR_URL, 'unicode'), ('clone_uri_tmpl', Repository.DEFAULT_CLONE_URI, 'unicode'), ('clone_ssh_tmpl', Repository.DEFAULT_CLONE_SSH, 'unicode'), ] for key, val, type_ in settings: sett = Setting(key, val, type_) self.sa.add(sett) self.create_auth_plugin_options() self.create_default_options() log.info('Populated Ui and Settings defaults')
def create_settings(self, path): self.create_ui_settings(path) ui_config = [ ('web', 'push_ssl', 'false'), ('web', 'allow_archive', 'gz zip bz2'), ('web', 'allow_push', '*'), ('web', 'baseurl', '/'), ('paths', '/', path), #('phases', 'publish', 'false') ] for section, key, value in ui_config: ui_conf = Ui() setattr(ui_conf, 'ui_section', section) setattr(ui_conf, 'ui_key', key) setattr(ui_conf, 'ui_value', value) self.sa.add(ui_conf) settings = [ ('realm', 'Kallithea', 'unicode'), ('title', '', 'unicode'), ('ga_code', '', 'unicode'), ('show_public_icon', True, 'bool'), ('show_private_icon', True, 'bool'), ('stylify_metatags', False, 'bool'), ('dashboard_items', 100, 'int'), ('admin_grid_items', 25, 'int'), ('show_version', True, 'bool'), ('use_gravatar', True, 'bool'), ('gravatar_url', User.DEFAULT_GRAVATAR_URL, 'unicode'), ('clone_uri_tmpl', Repository.DEFAULT_CLONE_URI, 'unicode'), ('update_url', Setting.DEFAULT_UPDATE_URL, 'unicode'), ] for key, val, type_ in settings: sett = Setting(key, val, type_) self.sa.add(sett) self.create_auth_plugin_options() self.create_default_options() log.info('created ui config')
def test_create_repo_when_filesystem_op_fails(self): self.log_user() repo_name = self.NEW_REPO description = 'description for newly created repo' response = self.app.post(url('repos'), fixture._get_repo_create_params(repo_private=False, repo_name=repo_name, repo_type=self.REPO_TYPE, repo_description=description, _authentication_token=self.authentication_token())) self.checkSessionFlash(response, 'Error creating repository %s' % repo_name) # repo must not be in db repo = Repository.get_by_repo_name(repo_name) self.assertEqual(repo, None) # repo must not be in filesystem ! self.assertFalse(os.path.isdir(os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name)))
def test_create_repo_when_filesystem_op_fails(self): self.log_user() repo_name = self.NEW_REPO description = 'description for newly created repo' response = self.app.post(url('repos'), fixture._get_repo_create_params(repo_private=False, repo_name=repo_name, repo_type=self.REPO_TYPE, repo_description=description, _authentication_token=self.authentication_token())) self.checkSessionFlash(response, 'Error creating repository %s' % repo_name) # repo must not be in db repo = Repository.get_by_repo_name(repo_name) assert repo == None # repo must not be in filesystem ! assert not os.path.isdir(os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name))
def test_create(self): self.log_user() repo_name = self.NEW_REPO description = 'description for newly created repo' response = self.app.post( base.url('repos'), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=self.REPO_TYPE, repo_description=description, _session_csrf_secret_token=self.session_csrf_secret_token())) ## run the check page that triggers the flash message response = self.app.get( base.url('repo_check_home', repo_name=repo_name)) assert response.json == {'result': True} self.checkSessionFlash( response, 'Created repository <a href="/%s">%s</a>' % (repo_name, repo_name)) # test if the repo was created in the database new_repo = Session().query(Repository) \ .filter(Repository.repo_name == repo_name).one() assert new_repo.repo_name == repo_name assert new_repo.description == description # test if the repository is visible in the list ? response = self.app.get(base.url('summary_home', repo_name=repo_name)) response.mustcontain(repo_name) response.mustcontain(self.REPO_TYPE) # test if the repository was created on filesystem try: vcs.get_repo( os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name)) except vcs.exceptions.VCSError: pytest.fail('no repo %s in filesystem' % repo_name) RepoModel().delete(repo_name) Session().commit()
def test_create_custom_hook_delete(self): self.log_user() response = self.app.post( url('admin_settings_hooks'), params=dict(new_hook_ui_key='test_hooks_2', new_hook_ui_value='cd %s2' % TESTS_TMP_PATH, _authentication_token=self.authentication_token())) response = response.follow() response.mustcontain('test_hooks_2') response.mustcontain('cd %s2' % TESTS_TMP_PATH) hook_id = Ui.get_by_key('hooks', 'test_hooks_2').ui_id ## delete self.app.post(url('admin_settings_hooks'), params=dict( hook_id=hook_id, _authentication_token=self.authentication_token())) response = self.app.get(url('admin_settings_hooks')) response.mustcontain(no=['test_hooks_2']) response.mustcontain(no=['cd %s2' % TESTS_TMP_PATH])
def _get_hg_ui_settings(self): ret = Ui.query().all() if not ret: raise Exception('Could not get application ui settings !') settings = {} for each in ret: k = each.ui_key v = each.ui_value if k == '/': k = 'root_path' if k == 'push_ssl': v = str2bool(v) if k.find('.') != -1: k = k.replace('.', '_') if each.ui_section in ['hooks', 'extensions']: v = each.ui_active settings[each.ui_section + '_' + k] = v return settings
def test_create(self): self.log_user() repo_name = self.NEW_REPO description = u'description for newly created repo' response = self.app.post(url('repos'), fixture._get_repo_create_params(repo_private=False, repo_name=repo_name, repo_type=self.REPO_TYPE, repo_description=description, _authentication_token=self.authentication_token())) ## run the check page that triggers the flash message response = self.app.get(url('repo_check_home', repo_name=repo_name)) self.assertEqual(response.json, {u'result': True}) self.checkSessionFlash(response, 'Created repository <a href="/%s">%s</a>' % (repo_name, repo_name)) # test if the repo was created in the database new_repo = Session().query(Repository) \ .filter(Repository.repo_name == repo_name).one() self.assertEqual(new_repo.repo_name, repo_name) self.assertEqual(new_repo.description, description) # test if the repository is visible in the list ? response = self.app.get(url('summary_home', repo_name=repo_name)) response.mustcontain(repo_name) response.mustcontain(self.REPO_TYPE) # test if the repository was created on filesystem try: vcs.get_repo(safe_str(os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name))) except vcs.exceptions.VCSError: pytest.fail('no repo %s in filesystem' % repo_name) RepoModel().delete(repo_name) Session().commit()
def fork_create(self, repo_name): self.__load_defaults() c.repo_info = Repository.get_by_repo_name(repo_name) _form = RepoForkForm(old_data={'repo_type': c.repo_info.repo_type}, repo_groups=c.repo_groups, landing_revs=c.landing_revs_choices)() form_result = {} task_id = None try: form_result = _form.to_python(dict(request.POST)) # an approximation that is better than nothing if not Ui.get_by_key('hooks', Ui.HOOK_UPDATE).ui_active: form_result['update_after_clone'] = False # create fork is done sometimes async on celery, db transaction # management is handled there. task = RepoModel().create_fork(form_result, request.authuser.user_id) task_id = task.task_id except formencode.Invalid as errors: return htmlfill.render(render('forks/fork.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except Exception: log.error(traceback.format_exc()) h.flash(_('An error occurred during repository forking %s') % repo_name, category='error') raise HTTPFound(location=h.url('repo_creating_home', repo_name=form_result['repo_name_full'], task_id=task_id))
def create_ui_settings(self, repo_store_path): """ Creates ui settings, fills out hooks """ #HOOKS hooks1_key = Ui.HOOK_UPDATE hooks1_ = Ui.query() \ .filter(Ui.ui_key == hooks1_key).scalar() hooks1 = Ui() if hooks1_ is None else hooks1_ hooks1.ui_section = 'hooks' hooks1.ui_key = hooks1_key hooks1.ui_value = 'hg update >&2' hooks1.ui_active = False self.sa.add(hooks1) hooks2_key = Ui.HOOK_REPO_SIZE hooks2_ = Ui.query() \ .filter(Ui.ui_key == hooks2_key).scalar() hooks2 = Ui() if hooks2_ is None else hooks2_ hooks2.ui_section = 'hooks' hooks2.ui_key = hooks2_key hooks2.ui_value = 'python:kallithea.lib.hooks.repo_size' self.sa.add(hooks2) hooks3 = Ui() hooks3.ui_section = 'hooks' hooks3.ui_key = Ui.HOOK_PUSH hooks3.ui_value = 'python:kallithea.lib.hooks.log_push_action' self.sa.add(hooks3) hooks4 = Ui() hooks4.ui_section = 'hooks' hooks4.ui_key = Ui.HOOK_PRE_PUSH hooks4.ui_value = 'python:kallithea.lib.hooks.pre_push' self.sa.add(hooks4) hooks5 = Ui() hooks5.ui_section = 'hooks' hooks5.ui_key = Ui.HOOK_PULL hooks5.ui_value = 'python:kallithea.lib.hooks.log_pull_action' self.sa.add(hooks5) hooks6 = Ui() hooks6.ui_section = 'hooks' hooks6.ui_key = Ui.HOOK_PRE_PULL hooks6.ui_value = 'python:kallithea.lib.hooks.pre_pull' self.sa.add(hooks6) # enable largefiles largefiles = Ui() largefiles.ui_section = 'extensions' largefiles.ui_key = 'largefiles' largefiles.ui_value = '' self.sa.add(largefiles) # set default largefiles cache dir, defaults to # /repo location/.cache/largefiles largefiles = Ui() largefiles.ui_section = 'largefiles' largefiles.ui_key = 'usercache' largefiles.ui_value = os.path.join(repo_store_path, '.cache', 'largefiles') self.sa.add(largefiles) # enable hgsubversion disabled by default hgsubversion = Ui() hgsubversion.ui_section = 'extensions' hgsubversion.ui_key = 'hgsubversion' hgsubversion.ui_value = '' hgsubversion.ui_active = False self.sa.add(hgsubversion) # enable hggit disabled by default hggit = Ui() hggit.ui_section = 'extensions' hggit.ui_key = 'hggit' hggit.ui_value = '' hggit.ui_active = False self.sa.add(hggit)
def create_ui_settings(self, repo_store_path): """ Creates ui settings, fills out hooks """ #HOOKS hooks1_key = Ui.HOOK_UPDATE hooks1_ = self.sa.query(Ui)\ .filter(Ui.ui_key == hooks1_key).scalar() hooks1 = Ui() if hooks1_ is None else hooks1_ hooks1.ui_section = 'hooks' hooks1.ui_key = hooks1_key hooks1.ui_value = 'hg update >&2' hooks1.ui_active = False self.sa.add(hooks1) hooks2_key = Ui.HOOK_REPO_SIZE hooks2_ = self.sa.query(Ui)\ .filter(Ui.ui_key == hooks2_key).scalar() hooks2 = Ui() if hooks2_ is None else hooks2_ hooks2.ui_section = 'hooks' hooks2.ui_key = hooks2_key hooks2.ui_value = 'python:kallithea.lib.hooks.repo_size' self.sa.add(hooks2) hooks3 = Ui() hooks3.ui_section = 'hooks' hooks3.ui_key = Ui.HOOK_PUSH hooks3.ui_value = 'python:kallithea.lib.hooks.log_push_action' self.sa.add(hooks3) hooks4 = Ui() hooks4.ui_section = 'hooks' hooks4.ui_key = Ui.HOOK_PRE_PUSH hooks4.ui_value = 'python:kallithea.lib.hooks.pre_push' self.sa.add(hooks4) hooks5 = Ui() hooks5.ui_section = 'hooks' hooks5.ui_key = Ui.HOOK_PULL hooks5.ui_value = 'python:kallithea.lib.hooks.log_pull_action' self.sa.add(hooks5) hooks6 = Ui() hooks6.ui_section = 'hooks' hooks6.ui_key = Ui.HOOK_PRE_PULL hooks6.ui_value = 'python:kallithea.lib.hooks.pre_pull' self.sa.add(hooks6) # enable largefiles largefiles = Ui() largefiles.ui_section = 'extensions' largefiles.ui_key = 'largefiles' largefiles.ui_value = '' self.sa.add(largefiles) # set default largefiles cache dir, defaults to # /repo location/.cache/largefiles largefiles = Ui() largefiles.ui_section = 'largefiles' largefiles.ui_key = 'usercache' largefiles.ui_value = os.path.join(repo_store_path, '.cache', 'largefiles') self.sa.add(largefiles) # enable hgsubversion disabled by default hgsubversion = Ui() hgsubversion.ui_section = 'extensions' hgsubversion.ui_key = 'hgsubversion' hgsubversion.ui_value = '' hgsubversion.ui_active = False self.sa.add(hgsubversion) # enable hggit disabled by default hggit = Ui() hggit.ui_section = 'extensions' hggit.ui_key = 'hggit' hggit.ui_value = '' hggit.ui_active = False self.sa.add(hggit)
def settings_vcs(self): """GET /admin/settings: All items in the collection""" # url('admin_settings') c.active = 'vcs' if request.POST: application_form = ApplicationUiSettingsForm()() try: form_result = application_form.to_python(dict(request.POST)) except formencode.Invalid as errors: return htmlfill.render( render('admin/settings/settings.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) try: sett = Ui.get_by_key('web', 'push_ssl') sett.ui_value = form_result['web_push_ssl'] if c.visual.allow_repo_location_change: sett = Ui.get_by_key('paths', '/') sett.ui_value = form_result['paths_root_path'] #HOOKS sett = Ui.get_by_key('hooks', Ui.HOOK_UPDATE) sett.ui_active = form_result['hooks_changegroup_update'] sett = Ui.get_by_key('hooks', Ui.HOOK_REPO_SIZE) sett.ui_active = form_result['hooks_changegroup_repo_size'] sett = Ui.get_by_key('hooks', Ui.HOOK_PUSH) sett.ui_active = form_result['hooks_changegroup_push_logger'] sett = Ui.get_by_key('hooks', Ui.HOOK_PULL) sett.ui_active = form_result['hooks_outgoing_pull_logger'] ## EXTENSIONS sett = Ui.get_or_create('extensions', 'largefiles') sett.ui_active = form_result['extensions_largefiles'] sett = Ui.get_or_create('extensions', 'hgsubversion') sett.ui_active = form_result['extensions_hgsubversion'] if sett.ui_active: try: import hgsubversion # pragma: no cover except ImportError: raise HgsubversionImportError # sett = Ui.get_or_create('extensions', 'hggit') # sett.ui_active = form_result['extensions_hggit'] Session().commit() h.flash(_('Updated VCS settings'), category='success') except HgsubversionImportError: log.error(traceback.format_exc()) h.flash(_('Unable to activate hgsubversion support. ' 'The "hgsubversion" library is missing'), category='error') except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred while updating ' 'application settings'), category='error') defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def test_create_in_group_inherit_permissions(self): self.log_user() ## create GROUP group_name = u'sometest_%s' % self.REPO_TYPE gr = RepoGroupModel().create(group_name=group_name, group_description=u'test', owner=TEST_USER_ADMIN_LOGIN) perm = Permission.get_by_key('repository.write') RepoGroupModel().grant_user_permission(gr, TEST_USER_REGULAR_LOGIN, perm) ## add repo permissions Session().commit() repo_name = u'ingroup_inherited_%s' % self.REPO_TYPE repo_name_full = RepoGroup.url_sep().join([group_name, repo_name]) description = u'description for newly created repo' response = self.app.post(url('repos'), fixture._get_repo_create_params(repo_private=False, repo_name=repo_name, repo_type=self.REPO_TYPE, repo_description=description, repo_group=gr.group_id, repo_copy_permissions=True, _authentication_token=self.authentication_token())) ## run the check page that triggers the flash message response = self.app.get(url('repo_check_home', repo_name=repo_name_full)) self.checkSessionFlash(response, 'Created repository <a href="/%s">%s</a>' % (repo_name_full, repo_name_full)) # test if the repo was created in the database new_repo = Session().query(Repository) \ .filter(Repository.repo_name == repo_name_full).one() new_repo_id = new_repo.repo_id assert new_repo.repo_name == repo_name_full assert new_repo.description == description # test if the repository is visible in the list ? response = self.app.get(url('summary_home', repo_name=repo_name_full)) response.mustcontain(repo_name_full) response.mustcontain(self.REPO_TYPE) # test if the repository was created on filesystem try: vcs.get_repo(safe_str(os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name_full))) except vcs.exceptions.VCSError: RepoGroupModel().delete(group_name) Session().commit() pytest.fail('no repo %s in filesystem' % repo_name) #check if inherited permissiona are applied inherited_perms = UserRepoToPerm.query() \ .filter(UserRepoToPerm.repository_id == new_repo_id).all() assert len(inherited_perms) == 2 assert TEST_USER_REGULAR_LOGIN in [x.user.username for x in inherited_perms] assert 'repository.write' in [x.permission.permission_name for x in inherited_perms] RepoModel().delete(repo_name_full) RepoGroupModel().delete(group_name) Session().commit()
def test_create_in_group_without_needed_permissions(self): usr = self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) # avoid spurious RepoGroup DetachedInstanceError ... authentication_token = self.authentication_token() # revoke user_model = UserModel() # disable fork and create on default user user_model.revoke_perm(User.DEFAULT_USER, 'hg.create.repository') user_model.grant_perm(User.DEFAULT_USER, 'hg.create.none') user_model.revoke_perm(User.DEFAULT_USER, 'hg.fork.repository') user_model.grant_perm(User.DEFAULT_USER, 'hg.fork.none') # disable on regular user user_model.revoke_perm(TEST_USER_REGULAR_LOGIN, 'hg.create.repository') user_model.grant_perm(TEST_USER_REGULAR_LOGIN, 'hg.create.none') user_model.revoke_perm(TEST_USER_REGULAR_LOGIN, 'hg.fork.repository') user_model.grant_perm(TEST_USER_REGULAR_LOGIN, 'hg.fork.none') Session().commit() ## create GROUP group_name = u'reg_sometest_%s' % self.REPO_TYPE gr = RepoGroupModel().create(group_name=group_name, group_description=u'test', owner=TEST_USER_ADMIN_LOGIN) Session().commit() group_name_allowed = u'reg_sometest_allowed_%s' % self.REPO_TYPE gr_allowed = RepoGroupModel().create(group_name=group_name_allowed, group_description=u'test', owner=TEST_USER_REGULAR_LOGIN) Session().commit() repo_name = u'ingroup' repo_name_full = RepoGroup.url_sep().join([group_name, repo_name]) description = u'description for newly created repo' response = self.app.post(url('repos'), fixture._get_repo_create_params(repo_private=False, repo_name=repo_name, repo_type=self.REPO_TYPE, repo_description=description, repo_group=gr.group_id, _authentication_token=authentication_token)) response.mustcontain('Invalid value') # user is allowed to create in this group repo_name = u'ingroup' repo_name_full = RepoGroup.url_sep().join([group_name_allowed, repo_name]) description = u'description for newly created repo' response = self.app.post(url('repos'), fixture._get_repo_create_params(repo_private=False, repo_name=repo_name, repo_type=self.REPO_TYPE, repo_description=description, repo_group=gr_allowed.group_id, _authentication_token=authentication_token)) ## run the check page that triggers the flash message response = self.app.get(url('repo_check_home', repo_name=repo_name_full)) self.assertEqual(response.json, {u'result': True}) self.checkSessionFlash(response, 'Created repository <a href="/%s">%s</a>' % (repo_name_full, repo_name_full)) # test if the repo was created in the database new_repo = Session().query(Repository) \ .filter(Repository.repo_name == repo_name_full).one() new_repo_id = new_repo.repo_id self.assertEqual(new_repo.repo_name, repo_name_full) self.assertEqual(new_repo.description, description) # test if the repository is visible in the list ? response = self.app.get(url('summary_home', repo_name=repo_name_full)) response.mustcontain(repo_name_full) response.mustcontain(self.REPO_TYPE) inherited_perms = UserRepoToPerm.query() \ .filter(UserRepoToPerm.repository_id == new_repo_id).all() self.assertEqual(len(inherited_perms), 1) # test if the repository was created on filesystem try: vcs.get_repo(safe_str(os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name_full))) except vcs.exceptions.VCSError: RepoGroupModel().delete(group_name) Session().commit() pytest.fail('no repo %s in filesystem' % repo_name) RepoModel().delete(repo_name_full) RepoGroupModel().delete(group_name) RepoGroupModel().delete(group_name_allowed) Session().commit()
def test_create_in_group_without_needed_permissions(self): usr = self.log_user(base.TEST_USER_REGULAR_LOGIN, base.TEST_USER_REGULAR_PASS) # avoid spurious RepoGroup DetachedInstanceError ... session_csrf_secret_token = self.session_csrf_secret_token() # revoke user_model = UserModel() # disable fork and create on default user user_model.revoke_perm(User.DEFAULT_USER_NAME, 'hg.create.repository') user_model.grant_perm(User.DEFAULT_USER_NAME, 'hg.create.none') user_model.revoke_perm(User.DEFAULT_USER_NAME, 'hg.fork.repository') user_model.grant_perm(User.DEFAULT_USER_NAME, 'hg.fork.none') # disable on regular user user_model.revoke_perm(base.TEST_USER_REGULAR_LOGIN, 'hg.create.repository') user_model.grant_perm(base.TEST_USER_REGULAR_LOGIN, 'hg.create.none') user_model.revoke_perm(base.TEST_USER_REGULAR_LOGIN, 'hg.fork.repository') user_model.grant_perm(base.TEST_USER_REGULAR_LOGIN, 'hg.fork.none') Session().commit() ## create GROUP group_name = 'reg_sometest_%s' % self.REPO_TYPE gr = RepoGroupModel().create(group_name=group_name, group_description='test', owner=base.TEST_USER_ADMIN_LOGIN) Session().commit() group_name_allowed = 'reg_sometest_allowed_%s' % self.REPO_TYPE gr_allowed = RepoGroupModel().create( group_name=group_name_allowed, group_description='test', owner=base.TEST_USER_REGULAR_LOGIN) Session().commit() repo_name = 'ingroup' repo_name_full = db.URL_SEP.join([group_name, repo_name]) description = 'description for newly created repo' response = self.app.post( base.url('repos'), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=self.REPO_TYPE, repo_description=description, repo_group=gr.group_id, _session_csrf_secret_token=session_csrf_secret_token)) response.mustcontain('Invalid value') # user is allowed to create in this group repo_name = 'ingroup' repo_name_full = db.URL_SEP.join([group_name_allowed, repo_name]) description = 'description for newly created repo' response = self.app.post( base.url('repos'), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=self.REPO_TYPE, repo_description=description, repo_group=gr_allowed.group_id, _session_csrf_secret_token=session_csrf_secret_token)) ## run the check page that triggers the flash message response = self.app.get( base.url('repo_check_home', repo_name=repo_name_full)) assert response.json == {'result': True} self.checkSessionFlash( response, 'Created repository <a href="/%s">%s</a>' % (repo_name_full, repo_name_full)) # test if the repo was created in the database new_repo = Session().query(Repository) \ .filter(Repository.repo_name == repo_name_full).one() new_repo_id = new_repo.repo_id assert new_repo.repo_name == repo_name_full assert new_repo.description == description # test if the repository is visible in the list ? response = self.app.get( base.url('summary_home', repo_name=repo_name_full)) response.mustcontain(repo_name_full) response.mustcontain(self.REPO_TYPE) inherited_perms = UserRepoToPerm.query() \ .filter(UserRepoToPerm.repository_id == new_repo_id).all() assert len(inherited_perms) == 1 # test if the repository was created on filesystem try: vcs.get_repo( os.path.join( Ui.get_by_key('paths', '/').ui_value, repo_name_full)) except vcs.exceptions.VCSError: RepoGroupModel().delete(group_name) Session().commit() pytest.fail('no repo %s in filesystem' % repo_name) RepoModel().delete(repo_name_full) RepoGroupModel().delete(group_name) RepoGroupModel().delete(group_name_allowed) Session().commit()
def settings_vcs(self): c.active = 'vcs' if request.POST: application_form = ApplicationUiSettingsForm()() try: form_result = application_form.to_python(dict(request.POST)) except formencode.Invalid as errors: return htmlfill.render( render('admin/settings/settings.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) try: if c.visual.allow_repo_location_change: sett = Ui.get_by_key('paths', '/') sett.ui_value = form_result['paths_root_path'] # HOOKS sett = Ui.get_by_key('hooks', Ui.HOOK_UPDATE) sett.ui_active = form_result['hooks_changegroup_update'] sett = Ui.get_by_key('hooks', Ui.HOOK_REPO_SIZE) sett.ui_active = form_result['hooks_changegroup_repo_size'] ## EXTENSIONS sett = Ui.get_or_create('extensions', 'largefiles') sett.ui_active = form_result['extensions_largefiles'] sett = Ui.get_or_create('extensions', 'hgsubversion') sett.ui_active = form_result['extensions_hgsubversion'] if sett.ui_active: try: import hgsubversion # pragma: no cover assert hgsubversion except ImportError: raise HgsubversionImportError # sett = Ui.get_or_create('extensions', 'hggit') # sett.ui_active = form_result['extensions_hggit'] Session().commit() h.flash(_('Updated VCS settings'), category='success') except HgsubversionImportError: log.error(traceback.format_exc()) h.flash(_('Unable to activate hgsubversion support. ' 'The "hgsubversion" library is missing'), category='error') except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred while updating ' 'application settings'), category='error') defaults = Setting.get_app_settings() defaults.update(self._get_hg_ui_settings()) return htmlfill.render( render('admin/settings/settings.html'), defaults=defaults, encoding="UTF-8", force_defaults=False)
def test_custom_hooks_prechangegroup(self, testhook_cleanup, webserver, testfork, vt): # set prechangegroup to failing hook (returns exit code 1) Ui.create_or_update_hook( 'prechangegroup.testhook', 'python:kallithea.tests.fixture.failing_test_hook') Session().commit() # clone repo clone_url = vt.repo_url_param(webserver, testfork[vt.repo_type], username=base.TEST_USER_ADMIN_LOGIN, password=base.TEST_USER_ADMIN_PASS) dest_dir = _get_tmp_dir() stdout, stderr = Command(base.TESTS_TMP_PATH).execute( vt.repo_type, 'clone', clone_url, dest_dir) stdout, stderr = _add_files_and_push(webserver, vt, dest_dir, clone_url, ignoreReturnCode=True) assert 'failing_test_hook failed' in stdout + stderr assert 'Traceback' not in stdout + stderr assert 'prechangegroup.testhook hook failed' in stdout + stderr # there are still outgoing changesets stdout, stderr = _check_outgoing(vt.repo_type, dest_dir, clone_url) assert stdout != '' # set prechangegroup hook to exception throwing method Ui.create_or_update_hook( 'prechangegroup.testhook', 'python:kallithea.tests.fixture.exception_test_hook') Session().commit() # re-try to push stdout, stderr = Command(dest_dir).execute('%s push' % vt.repo_type, clone_url, ignoreReturnCode=True) if vt is HgHttpVcsTest: # like with 'hg serve...' 'HTTP Error 500: INTERNAL SERVER ERROR' should be returned assert 'HTTP Error 500: INTERNAL SERVER ERROR' in stderr elif vt is HgSshVcsTest: assert 'remote: Exception: exception_test_hook threw an exception' in stdout else: assert False # there are still outgoing changesets stdout, stderr = _check_outgoing(vt.repo_type, dest_dir, clone_url) assert stdout != '' # set prechangegroup hook to method that returns False Ui.create_or_update_hook( 'prechangegroup.testhook', 'python:kallithea.tests.fixture.passing_test_hook') Session().commit() # re-try to push stdout, stderr = Command(dest_dir).execute('%s push' % vt.repo_type, clone_url, ignoreReturnCode=True) assert 'passing_test_hook succeeded' in stdout + stderr assert 'Traceback' not in stdout + stderr assert 'prechangegroup.testhook hook failed' not in stdout + stderr # no more outgoing changesets stdout, stderr = _check_outgoing(vt.repo_type, dest_dir, clone_url) assert stdout == '' assert stderr == ''