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
Beispiel #2
0
    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)
Beispiel #3
0
    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)
Beispiel #4
0
    def repos_path(self):
        """
        Gets the repositories root path from database
        """

        q = Ui.query().filter(Ui.ui_key == '/').one()
        return q.ui_value
Beispiel #5
0
    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))
Beispiel #6
0
    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)
Beispiel #7
0
    def repos_path(self):
        """
        Gets the repositories root path from database
        """

        q = Ui.get_by_key('/')
        return q.ui_value
Beispiel #8
0
    def repos_path(self):
        """
        Gets the repositories root path from database
        """

        q = Ui.query().filter(Ui.ui_key == '/').one()
        return q.ui_value
Beispiel #9
0
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'
Beispiel #10
0
    def repos_path(self):
        """
        Gets the repositories root path from database
        """

        q = Ui.get_by_key('paths', '/')
        return q.ui_value
Beispiel #11
0
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'
Beispiel #12
0
    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
Beispiel #14
0
 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
Beispiel #15
0
    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
Beispiel #16
0
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
Beispiel #18
0
    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()
Beispiel #20
0
    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()
Beispiel #21
0
    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()
Beispiel #22
0
    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
Beispiel #23
0
    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...'
Beispiel #24
0
    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()
Beispiel #25
0
    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)
Beispiel #26
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
Beispiel #27
0
    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)
Beispiel #28
0
    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...'
Beispiel #29
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('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
Beispiel #30
0
    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
Beispiel #31
0
    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 /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'])
Beispiel #33
0
    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
Beispiel #34
0
    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()])
Beispiel #35
0
    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])
Beispiel #36
0
    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')
Beispiel #37
0
    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')
Beispiel #38
0
    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))
Beispiel #40
0
    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()
Beispiel #41
0
    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])
Beispiel #42
0
    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
Beispiel #43
0
    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()
Beispiel #44
0
    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))
Beispiel #45
0
    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)
Beispiel #46
0
    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)
Beispiel #47
0
    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()
Beispiel #49
0
    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()
Beispiel #50
0
    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()
Beispiel #51
0
    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 == ''