Changeset - 5e46f73f0d1c
[Not reviewed]
default
0 93 0
Mads Kiilerich (mads) - 5 years ago 2020-10-12 11:12:37
mads@kiilerich.com
Grafted from: 314846069ab9
model: always import the whole db module - drop "from" imports
93 files changed with 1447 insertions and 1505 deletions:
0 comments (0 inline, 0 general)
kallithea/alembic/versions/a020f7044fd6_rename_hooks.py
Show inline comments
 
@@ -26,21 +26,21 @@ down_revision = '9358dc3d6828'
 
branch_labels = None
 
depends_on = None
 

	
 
from alembic import op
 
from sqlalchemy import MetaData, Table
 

	
 
from kallithea.model.db import Ui
 
from kallithea.model import db
 

	
 

	
 
meta = MetaData()
 

	
 

	
 
def upgrade():
 
    meta.bind = op.get_bind()
 
    ui = Table(Ui.__tablename__, meta, autoload=True)
 
    ui = Table(db.Ui.__tablename__, meta, autoload=True)
 

	
 
    ui.update(values={
 
        'ui_key': 'prechangegroup.push_lock_handling',
 
        'ui_value': 'python:kallithea.lib.hooks.push_lock_handling',
 
    }).where(ui.c.ui_key == 'prechangegroup.pre_push').execute()
 
    ui.update(values={
 
@@ -48,13 +48,13 @@ def upgrade():
 
        'ui_value': 'python:kallithea.lib.hooks.pull_lock_handling',
 
    }).where(ui.c.ui_key == 'preoutgoing.pre_pull').execute()
 

	
 

	
 
def downgrade():
 
    meta.bind = op.get_bind()
 
    ui = Table(Ui.__tablename__, meta, autoload=True)
 
    ui = Table(db.Ui.__tablename__, meta, autoload=True)
 

	
 
    ui.update(values={
 
        'ui_key': 'prechangegroup.pre_push',
 
        'ui_value': 'python:kallithea.lib.hooks.pre_push',
 
    }).where(ui.c.ui_key == 'prechangegroup.push_lock_handling').execute()
 
    ui.update(values={
kallithea/alembic/versions/ad357ccd9521_drop_locking.py
Show inline comments
 
@@ -27,13 +27,13 @@ branch_labels = None
 
depends_on = None
 

	
 
import sqlalchemy as sa
 
from alembic import op
 
from sqlalchemy import MetaData, Table
 

	
 
from kallithea.model.db import Ui
 
from kallithea.model import db
 

	
 

	
 
meta = MetaData()
 

	
 

	
 
def upgrade():
 
@@ -42,13 +42,13 @@ def upgrade():
 

	
 
    with op.batch_alter_table('repositories', schema=None) as batch_op:
 
        batch_op.drop_column('locked')
 
        batch_op.drop_column('enable_locking')
 

	
 
    meta.bind = op.get_bind()
 
    ui = Table(Ui.__tablename__, meta, autoload=True)
 
    ui = Table(db.Ui.__tablename__, meta, autoload=True)
 
    ui.delete().where(ui.c.ui_key == 'prechangegroup.push_lock_handling').execute()
 
    ui.delete().where(ui.c.ui_key == 'preoutgoing.pull_lock_handling').execute()
 

	
 

	
 
def downgrade():
 
    with op.batch_alter_table('repositories', schema=None) as batch_op:
kallithea/alembic/versions/f62826179f39_add_unique_constraint_on_.py
Show inline comments
 
@@ -26,37 +26,37 @@ down_revision = 'a0a1bf09c143'
 
branch_labels = None
 
depends_on = None
 

	
 
import sqlalchemy as sa
 
from alembic import op
 

	
 
from kallithea.model.db import PullRequestReviewer
 
from kallithea.model import db
 

	
 

	
 
def upgrade():
 
    session = sa.orm.session.Session(bind=op.get_bind())
 

	
 
    # there may be existing duplicates in the database, remove them first
 

	
 
    seen = set()
 
    # duplicate_values contains one copy of each duplicated pair
 
    duplicate_values = (
 
        session
 
        .query(PullRequestReviewer.pull_request_id, PullRequestReviewer.user_id)
 
        .group_by(PullRequestReviewer.pull_request_id, PullRequestReviewer.user_id)
 
        .having(sa.func.count(PullRequestReviewer.pull_request_reviewers_id) > 1)
 
        .query(db.PullRequestReviewer.pull_request_id, db.PullRequestReviewer.user_id)
 
        .group_by(db.PullRequestReviewer.pull_request_id, db.PullRequestReviewer.user_id)
 
        .having(sa.func.count(db.PullRequestReviewer.pull_request_reviewers_id) > 1)
 
    )
 

	
 
    for pull_request_id, user_id in duplicate_values:
 
        # duplicate_occurrences contains all db records of the duplicate_value
 
        # currently being processed
 
        duplicate_occurrences = (
 
            session
 
            .query(PullRequestReviewer)
 
            .filter(PullRequestReviewer.pull_request_id == pull_request_id)
 
            .filter(PullRequestReviewer.user_id == user_id)
 
            .query(db.PullRequestReviewer)
 
            .filter(db.PullRequestReviewer.pull_request_id == pull_request_id)
 
            .filter(db.PullRequestReviewer.user_id == user_id)
 
        )
 
        for prr in duplicate_occurrences:
 
            if (pull_request_id, user_id) in seen:
 
                session.delete(prr)
 
            else:
 
                seen.add((pull_request_id, user_id))
kallithea/bin/kallithea_cli_repo.py
Show inline comments
 
@@ -27,14 +27,13 @@ import shutil
 
import click
 

	
 
import kallithea
 
import kallithea.bin.kallithea_cli_base as cli_base
 
from kallithea.lib.utils import REMOVED_REPO_PAT, repo2db_mapper
 
from kallithea.lib.utils2 import ask_ok
 
from kallithea.model import meta
 
from kallithea.model.db import Repository
 
from kallithea.model import db, meta
 
from kallithea.model.scm import ScmModel
 

	
 

	
 
@cli_base.register_command(config_file_initialize_app=True)
 
@click.option('--remove-missing', is_flag=True,
 
        help='Remove missing repositories from the Kallithea database.')
 
@@ -70,17 +69,17 @@ def repo_update_metadata(repositories):
 
    command to update the repository cache.
 

	
 
    If no repositories are specified, the caches of all repositories are
 
    updated.
 
    """
 
    if not repositories:
 
        repo_list = Repository.query().all()
 
        repo_list = db.Repository.query().all()
 
    else:
 
        repo_names = [n.strip() for n in repositories]
 
        repo_list = list(Repository.query()
 
                        .filter(Repository.repo_name.in_(repo_names)))
 
        repo_list = list(db.Repository.query()
 
                        .filter(db.Repository.repo_name.in_(repo_names)))
 

	
 
    for repo in repo_list:
 
        # update latest revision metadata in database
 
        repo.update_changeset_cache()
 
        # invalidate in-memory VCS object cache... will be repopulated on
 
        # first access
kallithea/config/middleware/simplegit.py
Show inline comments
 
@@ -32,13 +32,13 @@ import logging
 
import re
 

	
 
from kallithea.config.middleware.pygrack import make_wsgi_app
 
from kallithea.lib.base import BaseVCSController, get_path_info
 
from kallithea.lib.hooks import log_pull_action
 
from kallithea.lib.utils import make_ui
 
from kallithea.model.db import Repository
 
from kallithea.model import db
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
GIT_PROTO_PAT = re.compile(r'^/(.+)/(info/refs|git-upload-pack|git-receive-pack)$')
 
@@ -84,13 +84,13 @@ class SimpleGit(BaseVCSController):
 

	
 
        def wrapper_app(environ, start_response):
 
            if (parsed_request.cmd == 'info/refs' and
 
                parsed_request.service == 'git-upload-pack'
 
            ):
 
                baseui = make_ui()
 
                repo = Repository.get_by_repo_name(parsed_request.repo_name)
 
                repo = db.Repository.get_by_repo_name(parsed_request.repo_name)
 
                scm_repo = repo.scm_instance
 
                # Run hooks, like Mercurial outgoing.pull_logger does
 
                log_pull_action(ui=baseui, repo=scm_repo._repo)
 
            # Note: push hooks are handled by post-receive hook
 

	
 
            return pygrack_app(environ, start_response)
kallithea/controllers/admin/admin.py
Show inline comments
 
@@ -38,13 +38,13 @@ from whoosh.qparser.default import Query
 

	
 
from kallithea.lib.auth import HasPermissionAnyDecorator, LoginRequired
 
from kallithea.lib.base import BaseController, render
 
from kallithea.lib.indexers import JOURNAL_SCHEMA
 
from kallithea.lib.page import Page
 
from kallithea.lib.utils2 import remove_prefix, remove_suffix, safe_int
 
from kallithea.model.db import UserLog
 
from kallithea.model import db
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
def _journal_filter(user_log, search_term):
 
@@ -74,21 +74,21 @@ def _journal_filter(user_log, search_ter
 
            wc_term = remove_suffix(wc_term, suffix='*')
 
            return func.lower(col).contains(func.lower(wc_term))
 

	
 
    def get_filterion(field, val, term):
 

	
 
        if field == 'repository':
 
            field = getattr(UserLog, 'repository_name')
 
            field = getattr(db.UserLog, 'repository_name')
 
        elif field == 'ip':
 
            field = getattr(UserLog, 'user_ip')
 
            field = getattr(db.UserLog, 'user_ip')
 
        elif field == 'date':
 
            field = getattr(UserLog, 'action_date')
 
            field = getattr(db.UserLog, 'action_date')
 
        elif field == 'username':
 
            field = getattr(UserLog, 'username')
 
            field = getattr(db.UserLog, 'username')
 
        else:
 
            field = getattr(UserLog, field)
 
            field = getattr(db.UserLog, field)
 
        log.debug('filter field: %s val=>%s', field, val)
 

	
 
        # sql filtering
 
        if isinstance(term, query.Wildcard):
 
            return wildcard_handler(field, val)
 
        elif isinstance(term, query.Prefix):
 
@@ -123,21 +123,21 @@ class AdminController(BaseController):
 
    @LoginRequired(allow_default_user=True)
 
    def _before(self, *args, **kwargs):
 
        super(AdminController, self)._before(*args, **kwargs)
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def index(self):
 
        users_log = UserLog.query() \
 
                .options(joinedload(UserLog.user)) \
 
                .options(joinedload(UserLog.repository))
 
        users_log = db.UserLog.query() \
 
                .options(joinedload(db.UserLog.user)) \
 
                .options(joinedload(db.UserLog.repository))
 

	
 
        # FILTERING
 
        c.search_term = request.GET.get('filter')
 
        users_log = _journal_filter(users_log, c.search_term)
 

	
 
        users_log = users_log.order_by(UserLog.action_date.desc())
 
        users_log = users_log.order_by(db.UserLog.action_date.desc())
 

	
 
        p = safe_int(request.GET.get('page'), 1)
 

	
 
        c.users_log = Page(users_log, page=p, items_per_page=10,
 
                           filter=c.search_term)
 

	
kallithea/controllers/admin/auth_settings.py
Show inline comments
 
@@ -33,15 +33,14 @@ from tg.i18n import ugettext as _
 
from webob.exc import HTTPFound
 

	
 
from kallithea.lib import auth_modules
 
from kallithea.lib import helpers as h
 
from kallithea.lib.auth import HasPermissionAnyDecorator, LoginRequired
 
from kallithea.lib.base import BaseController, render
 
from kallithea.lib.webutils import url
 
from kallithea.model import meta
 
from kallithea.model.db import Setting
 
from kallithea.lib.utils3 import url
 
from kallithea.model import db, meta
 
from kallithea.model.forms import AuthSettingsForm
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
@@ -74,13 +73,13 @@ class AuthSettingsController(BaseControl
 
            c.plugin_settings[module] = plugin.plugin_settings()
 
            for v in c.plugin_settings[module]:
 
                fullname = "auth_%s_%s" % (plugin.name, v["name"])
 
                if "default" in v:
 
                    c.defaults[fullname] = v["default"]
 
                # Current values will be the default on the form, if there are any
 
                setting = Setting.get_by_name(fullname)
 
                setting = db.Setting.get_by_name(fullname)
 
                if setting is not None:
 
                    c.defaults[fullname] = setting.app_settings_value
 
        if defaults:
 
            c.defaults.update(defaults)
 

	
 
        # we want to show , separated list of enabled plugins
 
@@ -128,13 +127,13 @@ class AuthSettingsController(BaseControl
 
            form_result = _form.to_python(dict(request.POST))
 
            for k, v in form_result.items():
 
                if k == 'auth_plugins':
 
                    # we want to store it comma separated inside our settings
 
                    v = ','.join(v)
 
                log.debug("%s = %s", k, str(v))
 
                setting = Setting.create_or_update(k, v)
 
                setting = db.Setting.create_or_update(k, v)
 
            meta.Session().commit()
 
            h.flash(_('Auth settings updated successfully'),
 
                       category='success')
 
        except formencode.Invalid as errors:
 
            log.error(traceback.format_exc())
 
            e = errors.error_dict or {}
kallithea/controllers/admin/defaults.py
Show inline comments
 
@@ -34,15 +34,14 @@ from tg import request
 
from tg.i18n import ugettext as _
 
from webob.exc import HTTPFound
 

	
 
from kallithea.lib import helpers as h
 
from kallithea.lib.auth import HasPermissionAnyDecorator, LoginRequired
 
from kallithea.lib.base import BaseController, render
 
from kallithea.lib.webutils import url
 
from kallithea.model import meta
 
from kallithea.model.db import Setting
 
from kallithea.lib.utils3 import url
 
from kallithea.model import db, meta
 
from kallithea.model.forms import DefaultsForm
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
@@ -51,13 +50,13 @@ class DefaultsController(BaseController)
 
    @LoginRequired()
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def _before(self, *args, **kwargs):
 
        super(DefaultsController, self)._before(*args, **kwargs)
 

	
 
    def index(self, format='html'):
 
        defaults = Setting.get_default_repo_settings()
 
        defaults = db.Setting.get_default_repo_settings()
 

	
 
        return htmlfill.render(
 
            render('admin/defaults/defaults.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
            force_defaults=False
 
@@ -66,13 +65,13 @@ class DefaultsController(BaseController)
 
    def update(self, id):
 
        _form = DefaultsForm()()
 

	
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            for k, v in form_result.items():
 
                setting = Setting.create_or_update(k, v)
 
                setting = db.Setting.create_or_update(k, v)
 
            meta.Session().commit()
 
            h.flash(_('Default settings updated successfully'),
 
                    category='success')
 

	
 
        except formencode.Invalid as errors:
 
            defaults = errors.value
kallithea/controllers/admin/gists.py
Show inline comments
 
@@ -39,14 +39,13 @@ from kallithea.lib import helpers as h
 
from kallithea.lib.auth import LoginRequired
 
from kallithea.lib.base import BaseController, jsonify, render
 
from kallithea.lib.page import Page
 
from kallithea.lib.utils2 import safe_int, safe_str, time_to_datetime
 
from kallithea.lib.vcs.exceptions import NodeNotChangedError, VCSError
 
from kallithea.lib.webutils import url
 
from kallithea.model import meta
 
from kallithea.model.db import Gist
 
from kallithea.model import db, meta
 
from kallithea.model.forms import GistForm
 
from kallithea.model.gist import GistModel
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -73,34 +72,34 @@ class GistsController(BaseController):
 
        url_params = {}
 
        if c.show_public:
 
            url_params['public'] = 1
 
        elif c.show_private:
 
            url_params['private'] = 1
 

	
 
        gists = Gist().query() \
 
        gists = db.Gist().query() \
 
            .filter_by(is_expired=False) \
 
            .order_by(Gist.created_on.desc())
 
            .order_by(db.Gist.created_on.desc())
 

	
 
        # MY private
 
        if c.show_private and not c.show_public:
 
            gists = gists.filter(Gist.gist_type == Gist.GIST_PRIVATE) \
 
                             .filter(Gist.owner_id == request.authuser.user_id)
 
            gists = gists.filter(db.Gist.gist_type == db.Gist.GIST_PRIVATE) \
 
                             .filter(db.Gist.owner_id == request.authuser.user_id)
 
        # MY public
 
        elif c.show_public and not c.show_private:
 
            gists = gists.filter(Gist.gist_type == Gist.GIST_PUBLIC) \
 
                             .filter(Gist.owner_id == request.authuser.user_id)
 
            gists = gists.filter(db.Gist.gist_type == db.Gist.GIST_PUBLIC) \
 
                             .filter(db.Gist.owner_id == request.authuser.user_id)
 

	
 
        # MY public+private
 
        elif c.show_private and c.show_public:
 
            gists = gists.filter(or_(Gist.gist_type == Gist.GIST_PUBLIC,
 
                                     Gist.gist_type == Gist.GIST_PRIVATE)) \
 
                             .filter(Gist.owner_id == request.authuser.user_id)
 
            gists = gists.filter(or_(db.Gist.gist_type == db.Gist.GIST_PUBLIC,
 
                                     db.Gist.gist_type == db.Gist.GIST_PRIVATE)) \
 
                             .filter(db.Gist.owner_id == request.authuser.user_id)
 

	
 
        # default show ALL public gists
 
        if not c.show_public and not c.show_private:
 
            gists = gists.filter(Gist.gist_type == Gist.GIST_PUBLIC)
 
            gists = gists.filter(db.Gist.gist_type == db.Gist.GIST_PUBLIC)
 

	
 
        c.gists = gists
 
        p = safe_int(request.GET.get('page'), 1)
 
        c.gists_pager = Page(c.gists, page=p, items_per_page=10,
 
                             **url_params)
 
        return render('admin/gists/index.html')
 
@@ -109,21 +108,21 @@ class GistsController(BaseController):
 
    def create(self):
 
        self.__load_defaults()
 
        gist_form = GistForm([x[0] for x in c.lifetime_values])()
 
        try:
 
            form_result = gist_form.to_python(dict(request.POST))
 
            # TODO: multiple files support, from the form
 
            filename = form_result['filename'] or Gist.DEFAULT_FILENAME
 
            filename = form_result['filename'] or db.Gist.DEFAULT_FILENAME
 
            nodes = {
 
                filename: {
 
                    'content': form_result['content'],
 
                    'lexer': form_result['mimetype']  # None is autodetect
 
                }
 
            }
 
            _public = form_result['public']
 
            gist_type = Gist.GIST_PUBLIC if _public else Gist.GIST_PRIVATE
 
            gist_type = db.Gist.GIST_PUBLIC if _public else db.Gist.GIST_PRIVATE
 
            gist = GistModel().create(
 
                description=form_result['description'],
 
                owner=request.authuser.user_id,
 
                ip_addr=request.ip_addr,
 
                gist_mapping=nodes,
 
                gist_type=gist_type,
 
@@ -165,13 +164,13 @@ class GistsController(BaseController):
 
            raise HTTPForbidden()
 

	
 
        raise HTTPFound(location=url('gists'))
 

	
 
    @LoginRequired(allow_default_user=True)
 
    def show(self, gist_id, revision='tip', format='html', f_path=None):
 
        c.gist = Gist.get_or_404(gist_id)
 
        c.gist = db.Gist.get_or_404(gist_id)
 

	
 
        if c.gist.is_expired:
 
            log.error('Gist expired at %s',
 
                      time_to_datetime(c.gist.gist_expires))
 
            raise HTTPNotFound()
 
        try:
 
@@ -188,13 +187,13 @@ class GistsController(BaseController):
 
            response.content_type = 'text/plain'
 
            return content
 
        return render('admin/gists/show.html')
 

	
 
    @LoginRequired()
 
    def edit(self, gist_id, format='html'):
 
        c.gist = Gist.get_or_404(gist_id)
 
        c.gist = db.Gist.get_or_404(gist_id)
 

	
 
        if c.gist.is_expired:
 
            log.error('Gist expired at %s',
 
                      time_to_datetime(c.gist.gist_expires))
 
            raise HTTPNotFound()
 
        try:
 
@@ -248,13 +247,13 @@ class GistsController(BaseController):
 

	
 
        return rendered
 

	
 
    @LoginRequired()
 
    @jsonify
 
    def check_revision(self, gist_id):
 
        c.gist = Gist.get_or_404(gist_id)
 
        c.gist = db.Gist.get_or_404(gist_id)
 
        last_rev = c.gist.scm_instance.get_changeset()
 
        success = True
 
        revision = request.POST.get('revision')
 

	
 
        # TODO: maybe move this to model ?
 
        if revision != last_rev.raw_id:
kallithea/controllers/admin/my_account.py
Show inline comments
 
@@ -37,16 +37,15 @@ from webob.exc import HTTPFound
 

	
 
from kallithea.lib import auth_modules
 
from kallithea.lib import helpers as h
 
from kallithea.lib.auth import AuthUser, LoginRequired
 
from kallithea.lib.base import BaseController, IfSshEnabled, render
 
from kallithea.lib.utils2 import generate_api_key, safe_int
 
from kallithea.lib.webutils import url
 
from kallithea.model import meta
 
from kallithea.lib.utils3 import url
 
from kallithea.model import db, meta
 
from kallithea.model.api_key import ApiKeyModel
 
from kallithea.model.db import Repository, User, UserEmailMap, UserFollowing
 
from kallithea.model.forms import PasswordChangeForm, UserForm
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.ssh_key import SshKeyModel, SshKeyModelException
 
from kallithea.model.user import UserModel
 

	
 

	
 
@@ -57,39 +56,39 @@ class MyAccountController(BaseController
 

	
 
    @LoginRequired()
 
    def _before(self, *args, **kwargs):
 
        super(MyAccountController, self)._before(*args, **kwargs)
 

	
 
    def __load_data(self):
 
        c.user = User.get(request.authuser.user_id)
 
        c.user = db.User.get(request.authuser.user_id)
 
        if c.user.is_default_user:
 
            h.flash(_("You can't edit this user since it's"
 
                      " crucial for entire application"), category='warning')
 
            raise HTTPFound(location=url('users'))
 

	
 
    def _load_my_repos_data(self, watched=False):
 
        if watched:
 
            admin = False
 
            repos_list = meta.Session().query(Repository) \
 
                         .join(UserFollowing) \
 
                         .filter(UserFollowing.user_id ==
 
            repos_list = meta.Session().query(db.Repository) \
 
                         .join(db.UserFollowing) \
 
                         .filter(db.UserFollowing.user_id ==
 
                                 request.authuser.user_id).all()
 
        else:
 
            admin = True
 
            repos_list = meta.Session().query(Repository) \
 
                         .filter(Repository.owner_id ==
 
            repos_list = meta.Session().query(db.Repository) \
 
                         .filter(db.Repository.owner_id ==
 
                                 request.authuser.user_id).all()
 

	
 
        return RepoModel().get_repos_as_dict(repos_list, admin=admin)
 

	
 
    def my_account(self):
 
        c.active = 'profile'
 
        self.__load_data()
 
        c.perm_user = AuthUser(user_id=request.authuser.user_id)
 
        managed_fields = auth_modules.get_managed_fields(c.user)
 
        def_user_perms = AuthUser(dbuser=User.get_default_user()).global_permissions
 
        def_user_perms = AuthUser(dbuser=db.User.get_default_user()).global_permissions
 
        if 'hg.register.none' in def_user_perms:
 
            managed_fields.extend(['username', 'firstname', 'lastname', 'email'])
 

	
 
        c.readonly = lambda n: 'readonly' if n in managed_fields else None
 

	
 
        defaults = c.user.get_dict()
 
@@ -188,14 +187,14 @@ class MyAccountController(BaseController
 
        return render('admin/my_account/my_account.html')
 

	
 
    def my_account_emails(self):
 
        c.active = 'emails'
 
        self.__load_data()
 

	
 
        c.user_email_map = UserEmailMap.query() \
 
            .filter(UserEmailMap.user == c.user).all()
 
        c.user_email_map = db.UserEmailMap.query() \
 
            .filter(db.UserEmailMap.user == c.user).all()
 
        return render('admin/my_account/my_account.html')
 

	
 
    def my_account_emails_add(self):
 
        email = request.POST.get('new_email')
 

	
 
        try:
 
@@ -243,13 +242,13 @@ class MyAccountController(BaseController
 
        h.flash(_("API key successfully created"), category='success')
 
        raise HTTPFound(location=url('my_account_api_keys'))
 

	
 
    def my_account_api_keys_delete(self):
 
        api_key = request.POST.get('del_api_key')
 
        if request.POST.get('del_api_key_builtin'):
 
            user = User.get(request.authuser.user_id)
 
            user = db.User.get(request.authuser.user_id)
 
            user.api_key = generate_api_key()
 
            meta.Session().commit()
 
            h.flash(_("API key successfully reset"), category='success')
 
        elif api_key:
 
            ApiKeyModel().delete(api_key, request.authuser.user_id)
 
            meta.Session().commit()
kallithea/controllers/admin/permissions.py
Show inline comments
 
@@ -36,15 +36,14 @@ from tg import tmpl_context as c
 
from tg.i18n import ugettext as _
 
from webob.exc import HTTPFound
 

	
 
from kallithea.lib import helpers as h
 
from kallithea.lib.auth import AuthUser, HasPermissionAnyDecorator, LoginRequired
 
from kallithea.lib.base import BaseController, render
 
from kallithea.lib.webutils import url
 
from kallithea.model import meta
 
from kallithea.model.db import User, UserIpMap
 
from kallithea.lib.utils3 import url
 
from kallithea.model import db, meta
 
from kallithea.model.forms import DefaultPermissionsForm
 
from kallithea.model.permission import PermissionModel
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -131,13 +130,13 @@ class PermissionsController(BaseControll
 
                log.error(traceback.format_exc())
 
                h.flash(_('Error occurred during update of permissions'),
 
                        category='error')
 

	
 
            raise HTTPFound(location=url('admin_permissions'))
 

	
 
        c.user = User.get_default_user()
 
        c.user = db.User.get_default_user()
 
        defaults = {'anonymous': c.user.active}
 

	
 
        for p in c.user.user_perms:
 
            if p.permission.permission_name.startswith('repository.'):
 
                defaults['default_repo_perm'] = p.permission.permission_name
 

	
 
@@ -167,17 +166,17 @@ class PermissionsController(BaseControll
 
            defaults=defaults,
 
            encoding="UTF-8",
 
            force_defaults=False)
 

	
 
    def permission_ips(self):
 
        c.active = 'ips'
 
        c.user = User.get_default_user()
 
        c.user_ip_map = UserIpMap.query() \
 
                        .filter(UserIpMap.user == c.user).all()
 
        c.user = db.User.get_default_user()
 
        c.user_ip_map = db.UserIpMap.query() \
 
                        .filter(db.UserIpMap.user == c.user).all()
 

	
 
        return render('admin/permissions/permissions.html')
 

	
 
    def permission_perms(self):
 
        c.active = 'perms'
 
        c.user = User.get_default_user()
 
        c.user = db.User.get_default_user()
 
        c.perm_user = AuthUser(dbuser=c.user)
 
        return render('admin/permissions/permissions.html')
kallithea/controllers/admin/repo_groups.py
Show inline comments
 
@@ -37,15 +37,14 @@ from tg.i18n import ungettext
 
from webob.exc import HTTPForbidden, HTTPFound, HTTPInternalServerError, HTTPNotFound
 

	
 
from kallithea.lib import helpers as h
 
from kallithea.lib.auth import HasPermissionAny, HasRepoGroupPermissionLevel, HasRepoGroupPermissionLevelDecorator, LoginRequired
 
from kallithea.lib.base import BaseController, render
 
from kallithea.lib.utils2 import safe_int
 
from kallithea.lib.webutils import url
 
from kallithea.model import meta
 
from kallithea.model.db import RepoGroup, Repository
 
from kallithea.lib.utils3 import url
 
from kallithea.model import db, meta
 
from kallithea.model.forms import RepoGroupForm, RepoGroupPermsForm
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.repo_group import RepoGroupModel
 
from kallithea.model.scm import AvailableRepoGroupChoices, RepoGroupList
 

	
 

	
 
@@ -71,13 +70,13 @@ class RepoGroupsController(BaseControlle
 
    def __load_data(self, group_id):
 
        """
 
        Load defaults settings for edit, and update
 

	
 
        :param group_id:
 
        """
 
        repo_group = RepoGroup.get_or_404(group_id)
 
        repo_group = db.RepoGroup.get_or_404(group_id)
 
        data = repo_group.get_dict()
 
        data['group_name'] = repo_group.name
 

	
 
        # fill repository group users
 
        for p in repo_group.repo_group_to_perm:
 
            data.update({'u_perm_%s' % p.user.username:
 
@@ -95,13 +94,13 @@ class RepoGroupsController(BaseControlle
 
        _new = [u for u in form_result['perms_new'] if request.authuser.username == u[0]]
 
        if _new and _new[0][1] != 'group.admin' or _up and _up[0][1] != 'group.admin':
 
            return True
 
        return False
 

	
 
    def index(self, format='html'):
 
        _list = RepoGroup.query(sorted=True).all()
 
        _list = db.RepoGroup.query(sorted=True).all()
 
        group_iter = RepoGroupList(_list, perm_level='admin')
 
        repo_groups_data = []
 
        _tmpl_lookup = app_globals.mako_lookup
 
        template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
 

	
 
        def repo_group_name(repo_group_name, children_groups):
 
@@ -178,25 +177,25 @@ class RepoGroupsController(BaseControlle
 
            # we're global admin, we're ok and we can create TOP level groups
 
            pass
 
        else:
 
            # we pass in parent group into creation form, thus we know
 
            # what would be the group, we can check perms here !
 
            group_id = safe_int(request.GET.get('parent_group'))
 
            group = RepoGroup.get(group_id) if group_id else None
 
            group = db.RepoGroup.get(group_id) if group_id else None
 
            group_name = group.group_name if group else None
 
            if HasRepoGroupPermissionLevel('admin')(group_name, 'group create'):
 
                pass
 
            else:
 
                raise HTTPForbidden()
 

	
 
        self.__load_defaults()
 
        return render('admin/repo_groups/repo_group_add.html')
 

	
 
    @HasRepoGroupPermissionLevelDecorator('admin')
 
    def update(self, group_name):
 
        c.repo_group = RepoGroup.guess_instance(group_name)
 
        c.repo_group = db.RepoGroup.guess_instance(group_name)
 
        self.__load_defaults(extras=[c.repo_group.parent_group],
 
                             exclude=[c.repo_group])
 

	
 
        # TODO: kill allow_empty_group - it is only used for redundant form validation!
 
        if HasPermissionAny('hg.admin')('group edit'):
 
            # we're global admin, we're ok and we can create TOP level groups
 
@@ -236,13 +235,13 @@ class RepoGroupsController(BaseControlle
 
                    % request.POST.get('group_name'), category='error')
 

	
 
        raise HTTPFound(location=url('edit_repo_group', group_name=group_name))
 

	
 
    @HasRepoGroupPermissionLevelDecorator('admin')
 
    def delete(self, group_name):
 
        gr = c.repo_group = RepoGroup.guess_instance(group_name)
 
        gr = c.repo_group = db.RepoGroup.guess_instance(group_name)
 
        repos = gr.repositories.all()
 
        if repos:
 
            h.flash(_('This group contains %s repositories and cannot be '
 
                      'deleted') % len(repos), category='warning')
 
            raise HTTPFound(location=url('repos_groups'))
 

	
 
@@ -270,38 +269,38 @@ class RepoGroupsController(BaseControlle
 
    def show_by_name(self, group_name):
 
        """
 
        This is a proxy that does a lookup group_name -> id, and shows
 
        the group by id view instead
 
        """
 
        group_name = group_name.rstrip('/')
 
        id_ = RepoGroup.get_by_group_name(group_name)
 
        id_ = db.RepoGroup.get_by_group_name(group_name)
 
        if id_:
 
            return self.show(group_name)
 
        raise HTTPNotFound
 

	
 
    @HasRepoGroupPermissionLevelDecorator('read')
 
    def show(self, group_name):
 
        c.active = 'settings'
 

	
 
        c.group = c.repo_group = RepoGroup.guess_instance(group_name)
 
        c.group = c.repo_group = db.RepoGroup.guess_instance(group_name)
 

	
 
        groups = RepoGroup.query(sorted=True).filter_by(parent_group=c.group).all()
 
        groups = db.RepoGroup.query(sorted=True).filter_by(parent_group=c.group).all()
 
        repo_groups_list = self.scm_model.get_repo_groups(groups)
 

	
 
        repos_list = Repository.query(sorted=True).filter_by(group=c.group).all()
 
        repos_list = db.Repository.query(sorted=True).filter_by(group=c.group).all()
 
        c.data = RepoModel().get_repos_as_dict(repos_list,
 
                                               repo_groups_list=repo_groups_list,
 
                                               short_name=True)
 

	
 
        return render('admin/repo_groups/repo_group_show.html')
 

	
 
    @HasRepoGroupPermissionLevelDecorator('admin')
 
    def edit(self, group_name):
 
        c.active = 'settings'
 

	
 
        c.repo_group = RepoGroup.guess_instance(group_name)
 
        c.repo_group = db.RepoGroup.guess_instance(group_name)
 
        self.__load_defaults(extras=[c.repo_group.parent_group],
 
                             exclude=[c.repo_group])
 
        defaults = self.__load_data(c.repo_group.group_id)
 

	
 
        return htmlfill.render(
 
            render('admin/repo_groups/repo_group_edit.html'),
 
@@ -310,20 +309,20 @@ class RepoGroupsController(BaseControlle
 
            force_defaults=False
 
        )
 

	
 
    @HasRepoGroupPermissionLevelDecorator('admin')
 
    def edit_repo_group_advanced(self, group_name):
 
        c.active = 'advanced'
 
        c.repo_group = RepoGroup.guess_instance(group_name)
 
        c.repo_group = db.RepoGroup.guess_instance(group_name)
 

	
 
        return render('admin/repo_groups/repo_group_edit.html')
 

	
 
    @HasRepoGroupPermissionLevelDecorator('admin')
 
    def edit_repo_group_perms(self, group_name):
 
        c.active = 'perms'
 
        c.repo_group = RepoGroup.guess_instance(group_name)
 
        c.repo_group = db.RepoGroup.guess_instance(group_name)
 
        self.__load_defaults()
 
        defaults = self.__load_data(c.repo_group.group_id)
 

	
 
        return htmlfill.render(
 
            render('admin/repo_groups/repo_group_edit.html'),
 
            defaults=defaults,
 
@@ -336,13 +335,13 @@ class RepoGroupsController(BaseControlle
 
        """
 
        Update permissions for given repository group
 

	
 
        :param group_name:
 
        """
 

	
 
        c.repo_group = RepoGroup.guess_instance(group_name)
 
        c.repo_group = db.RepoGroup.guess_instance(group_name)
 
        valid_recursive_choices = ['none', 'repos', 'groups', 'all']
 
        form_result = RepoGroupPermsForm(valid_recursive_choices)().to_python(request.POST)
 
        if not request.authuser.is_admin:
 
            if self._revoke_perms_on_yourself(form_result):
 
                msg = _('Cannot revoke permission for yourself as admin')
 
                h.flash(msg, category='warning')
kallithea/controllers/admin/repos.py
Show inline comments
 
@@ -42,14 +42,13 @@ from kallithea.lib.auth import HasRepoPe
 
from kallithea.lib.base import BaseRepoController, jsonify, render
 
from kallithea.lib.exceptions import AttachedForksError
 
from kallithea.lib.utils import action_logger
 
from kallithea.lib.utils2 import safe_int
 
from kallithea.lib.vcs import RepositoryError
 
from kallithea.lib.webutils import url
 
from kallithea.model import meta
 
from kallithea.model.db import RepoGroup, Repository, RepositoryField, Setting, UserFollowing
 
from kallithea.model import db, meta
 
from kallithea.model.forms import RepoFieldForm, RepoForm, RepoPermsForm
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.scm import AvailableRepoGroupChoices, RepoList, ScmModel
 

	
 

	
 
log = logging.getLogger(__name__)
 
@@ -88,13 +87,13 @@ class ReposController(BaseRepoController
 
        defaults['clone_uri'] = c.repo_info.clone_uri_hidden # don't show password
 
        defaults['permanent_url'] = c.repo_info.clone_url(clone_uri_tmpl=c.clone_uri_tmpl, with_id=True)
 

	
 
        return defaults
 

	
 
    def index(self, format='html'):
 
        repos_list = RepoList(Repository.query(sorted=True).all(), perm_level='admin')
 
        repos_list = RepoList(db.Repository.query(sorted=True).all(), perm_level='admin')
 
        # the repo list will be filtered to only show repos where the user has read permissions
 
        repos_data = RepoModel().get_repos_as_dict(repos_list, admin=True)
 
        # data used to render the grid
 
        c.data = repos_data
 

	
 
        return render('admin/repos/repos.html')
 
@@ -138,15 +137,15 @@ class ReposController(BaseRepoController
 
        self.__load_defaults()
 
        if not c.repo_groups:
 
            raise HTTPForbidden
 
        parent_group = request.GET.get('parent_group')
 

	
 
        ## apply the defaults from defaults page
 
        defaults = Setting.get_default_repo_settings(strip_prefix=True)
 
        defaults = db.Setting.get_default_repo_settings(strip_prefix=True)
 
        if parent_group:
 
            prg = RepoGroup.get(parent_group)
 
            prg = db.RepoGroup.get(parent_group)
 
            if prg is None or not any(rgc[0] == prg.group_id
 
                                      for rgc in c.repo_groups):
 
                raise HTTPForbidden
 
            defaults.update({'repo_group': parent_group})
 

	
 
        return htmlfill.render(
 
@@ -174,14 +173,14 @@ class ReposController(BaseRepoController
 
        if task_id and task_id not in ['None']:
 
            if kallithea.CELERY_APP:
 
                task_result = celery.result.AsyncResult(task_id, app=kallithea.CELERY_APP)
 
                if task_result.failed():
 
                    raise HTTPInternalServerError(task_result.traceback)
 

	
 
        repo = Repository.get_by_repo_name(repo_name)
 
        if repo and repo.repo_state == Repository.STATE_CREATED:
 
        repo = db.Repository.get_by_repo_name(repo_name)
 
        if repo and repo.repo_state == db.Repository.STATE_CREATED:
 
            if repo.clone_uri:
 
                h.flash(_('Created repository %s from %s')
 
                        % (repo.repo_name, repo.clone_uri_hidden), category='success')
 
            else:
 
                repo_url = h.link_to(repo.repo_name,
 
                                     h.url('summary_home',
 
@@ -199,18 +198,18 @@ class ReposController(BaseRepoController
 

	
 
    @HasRepoPermissionLevelDecorator('admin')
 
    def update(self, repo_name):
 
        c.repo_info = self._load_repo()
 
        self.__load_defaults(c.repo_info)
 
        c.active = 'settings'
 
        c.repo_fields = RepositoryField.query() \
 
            .filter(RepositoryField.repository == c.repo_info).all()
 
        c.repo_fields = db.RepositoryField.query() \
 
            .filter(db.RepositoryField.repository == c.repo_info).all()
 

	
 
        repo_model = RepoModel()
 
        changed_name = repo_name
 
        repo = Repository.get_by_repo_name(repo_name)
 
        repo = db.Repository.get_by_repo_name(repo_name)
 
        old_data = {
 
            'repo_name': repo_name,
 
            'repo_group': repo.group.get_dict() if repo.group else {},
 
            'repo_type': repo.repo_type,
 
        }
 
        _form = RepoForm(edit=True, old_data=old_data,
 
@@ -282,14 +281,14 @@ class ReposController(BaseRepoController
 
            raise HTTPFound(location=url('repos_group_home', group_name=repo.group.group_name))
 
        raise HTTPFound(location=url('repos'))
 

	
 
    @HasRepoPermissionLevelDecorator('admin')
 
    def edit(self, repo_name):
 
        defaults = self.__load_data()
 
        c.repo_fields = RepositoryField.query() \
 
            .filter(RepositoryField.repository == c.repo_info).all()
 
        c.repo_fields = db.RepositoryField.query() \
 
            .filter(db.RepositoryField.repository == c.repo_info).all()
 
        c.active = 'settings'
 
        return htmlfill.render(
 
            render('admin/repos/repo_edit.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
            force_defaults=False)
 
@@ -349,26 +348,26 @@ class ReposController(BaseRepoController
 
            raise HTTPInternalServerError()
 
        return []
 

	
 
    @HasRepoPermissionLevelDecorator('admin')
 
    def edit_fields(self, repo_name):
 
        c.repo_info = self._load_repo()
 
        c.repo_fields = RepositoryField.query() \
 
            .filter(RepositoryField.repository == c.repo_info).all()
 
        c.repo_fields = db.RepositoryField.query() \
 
            .filter(db.RepositoryField.repository == c.repo_info).all()
 
        c.active = 'fields'
 
        if request.POST:
 

	
 
            raise HTTPFound(location=url('repo_edit_fields'))
 
        return render('admin/repos/repo_edit.html')
 

	
 
    @HasRepoPermissionLevelDecorator('admin')
 
    def create_repo_field(self, repo_name):
 
        try:
 
            form_result = RepoFieldForm()().to_python(dict(request.POST))
 
            new_field = RepositoryField()
 
            new_field.repository = Repository.get_by_repo_name(repo_name)
 
            new_field = db.RepositoryField()
 
            new_field.repository = db.Repository.get_by_repo_name(repo_name)
 
            new_field.field_key = form_result['new_field_key']
 
            new_field.field_type = form_result['new_field_type']  # python type
 
            new_field.field_value = form_result['new_field_value']  # set initial blank value
 
            new_field.field_desc = form_result['new_field_desc']
 
            new_field.field_label = form_result['new_field_label']
 
            meta.Session().add(new_field)
 
@@ -379,13 +378,13 @@ class ReposController(BaseRepoController
 
            log.error(traceback.format_exc())
 
            h.flash(_('An error occurred during creation of field: %r') % e, category='error')
 
        raise HTTPFound(location=url('edit_repo_fields', repo_name=repo_name))
 

	
 
    @HasRepoPermissionLevelDecorator('admin')
 
    def delete_repo_field(self, repo_name, field_id):
 
        field = RepositoryField.get_or_404(field_id)
 
        field = db.RepositoryField.get_or_404(field_id)
 
        try:
 
            meta.Session().delete(field)
 
            meta.Session().commit()
 
        except Exception as e:
 
            log.error(traceback.format_exc())
 
            msg = _('An error occurred during removal of field')
 
@@ -393,17 +392,17 @@ class ReposController(BaseRepoController
 
        raise HTTPFound(location=url('edit_repo_fields', repo_name=repo_name))
 

	
 
    @HasRepoPermissionLevelDecorator('admin')
 
    def edit_advanced(self, repo_name):
 
        c.repo_info = self._load_repo()
 
        c.default_user_id = kallithea.DEFAULT_USER_ID
 
        c.in_public_journal = UserFollowing.query() \
 
            .filter(UserFollowing.user_id == c.default_user_id) \
 
            .filter(UserFollowing.follows_repository == c.repo_info).scalar()
 
        c.in_public_journal = db.UserFollowing.query() \
 
            .filter(db.UserFollowing.user_id == c.default_user_id) \
 
            .filter(db.UserFollowing.follows_repository == c.repo_info).scalar()
 

	
 
        _repos = Repository.query(sorted=True).all()
 
        _repos = db.Repository.query(sorted=True).all()
 
        read_access_repos = RepoList(_repos, perm_level='read')
 
        c.repos_list = [(None, _('-- Not a fork --'))]
 
        c.repos_list += [(x.repo_id, x.repo_name)
 
                         for x in read_access_repos
 
                         if x.repo_id != c.repo_info.repo_id
 
                         and x.repo_type == c.repo_info.repo_type]
 
@@ -428,13 +427,13 @@ class ReposController(BaseRepoController
 
        in other words asking default user to follow this repo
 

	
 
        :param repo_name:
 
        """
 

	
 
        try:
 
            repo_id = Repository.get_by_repo_name(repo_name).repo_id
 
            repo_id = db.Repository.get_by_repo_name(repo_name).repo_id
 
            user_id = kallithea.DEFAULT_USER_ID
 
            self.scm_model.toggle_following_repo(repo_id, user_id)
 
            h.flash(_('Updated repository visibility in public journal'),
 
                    category='success')
 
            meta.Session().commit()
 
        except Exception:
kallithea/controllers/admin/settings.py
Show inline comments
 
@@ -40,14 +40,13 @@ from kallithea.lib.auth import HasPermis
 
from kallithea.lib.base import BaseController, render
 
from kallithea.lib.celerylib import tasks
 
from kallithea.lib.utils import repo2db_mapper, set_app_settings
 
from kallithea.lib.utils2 import safe_str
 
from kallithea.lib.vcs import VCSError
 
from kallithea.lib.webutils import url
 
from kallithea.model import meta
 
from kallithea.model.db import Repository, Setting, Ui
 
from kallithea.model import db, meta
 
from kallithea.model.forms import ApplicationSettingsForm, ApplicationUiSettingsForm, ApplicationVisualisationForm
 
from kallithea.model.notification import EmailNotificationModel
 
from kallithea.model.scm import ScmModel
 

	
 

	
 
log = logging.getLogger(__name__)
 
@@ -57,13 +56,13 @@ class SettingsController(BaseController)
 

	
 
    @LoginRequired(allow_default_user=True)
 
    def _before(self, *args, **kwargs):
 
        super(SettingsController, self)._before(*args, **kwargs)
 

	
 
    def _get_hg_ui_settings(self):
 
        ret = Ui.query().all()
 
        ret = db.Ui.query().all()
 

	
 
        settings = {}
 
        for each in ret:
 
            k = each.ui_section + '_' + each.ui_key
 
            v = each.ui_value
 
            if k == 'paths_/':
 
@@ -92,39 +91,39 @@ class SettingsController(BaseController)
 
                     prefix_error=False,
 
                     encoding="UTF-8",
 
                     force_defaults=False)
 

	
 
            try:
 
                if c.visual.allow_repo_location_change:
 
                    sett = Ui.get_by_key('paths', '/')
 
                    sett = db.Ui.get_by_key('paths', '/')
 
                    sett.ui_value = form_result['paths_root_path']
 

	
 
                # HOOKS
 
                sett = Ui.get_by_key('hooks', Ui.HOOK_UPDATE)
 
                sett = db.Ui.get_by_key('hooks', db.Ui.HOOK_UPDATE)
 
                sett.ui_active = form_result['hooks_changegroup_update']
 

	
 
                sett = Ui.get_by_key('hooks', Ui.HOOK_REPO_SIZE)
 
                sett = db.Ui.get_by_key('hooks', db.Ui.HOOK_REPO_SIZE)
 
                sett.ui_active = form_result['hooks_changegroup_repo_size']
 

	
 
                ## EXTENSIONS
 
                sett = Ui.get_or_create('extensions', 'largefiles')
 
                sett = db.Ui.get_or_create('extensions', 'largefiles')
 
                sett.ui_active = form_result['extensions_largefiles']
 

	
 
#                sett = Ui.get_or_create('extensions', 'hggit')
 
#                sett = db.Ui.get_or_create('extensions', 'hggit')
 
#                sett.ui_active = form_result['extensions_hggit']
 

	
 
                meta.Session().commit()
 

	
 
                h.flash(_('Updated VCS settings'), category='success')
 

	
 
            except Exception:
 
                log.error(traceback.format_exc())
 
                h.flash(_('Error occurred while updating '
 
                          'application settings'), category='error')
 

	
 
        defaults = Setting.get_app_settings()
 
        defaults = db.Setting.get_app_settings()
 
        defaults.update(self._get_hg_ui_settings())
 

	
 
        return htmlfill.render(
 
            render('admin/settings/settings.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
@@ -156,23 +155,23 @@ class SettingsController(BaseController)
 
            h.flash(h.HTML(_('Repositories successfully rescanned. Added: %s. Removed: %s.')) %
 
                    (added_msg, removed_msg), category='success')
 

	
 
            if invalidate_cache:
 
                log.debug('invalidating all repositories cache')
 
                i = 0
 
                for repo in Repository.query():
 
                for repo in db.Repository.query():
 
                    try:
 
                        ScmModel().mark_for_invalidation(repo.repo_name)
 
                        i += 1
 
                    except VCSError as e:
 
                        log.warning('VCS error invalidating %s: %s', repo.repo_name, e)
 
                h.flash(_('Invalidated %s repositories') % i, category='success')
 

	
 
            raise HTTPFound(location=url('admin_settings_mapping'))
 

	
 
        defaults = Setting.get_app_settings()
 
        defaults = db.Setting.get_app_settings()
 
        defaults.update(self._get_hg_ui_settings())
 

	
 
        return htmlfill.render(
 
            render('admin/settings/settings.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
@@ -199,13 +198,13 @@ class SettingsController(BaseController)
 
                    'title',
 
                    'realm',
 
                    'ga_code',
 
                    'captcha_public_key',
 
                    'captcha_private_key',
 
                ):
 
                    Setting.create_or_update(setting, form_result[setting])
 
                    db.Setting.create_or_update(setting, form_result[setting])
 

	
 
                meta.Session().commit()
 
                set_app_settings(config)
 
                h.flash(_('Updated application settings'), category='success')
 

	
 
            except Exception:
 
@@ -213,13 +212,13 @@ class SettingsController(BaseController)
 
                h.flash(_('Error occurred while updating '
 
                          'application settings'),
 
                          category='error')
 

	
 
            raise HTTPFound(location=url('admin_settings_global'))
 

	
 
        defaults = Setting.get_app_settings()
 
        defaults = db.Setting.get_app_settings()
 
        defaults.update(self._get_hg_ui_settings())
 

	
 
        return htmlfill.render(
 
            render('admin/settings/settings.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
@@ -253,13 +252,13 @@ class SettingsController(BaseController)
 
                    ('use_gravatar', 'use_gravatar', 'bool'),
 
                    ('gravatar_url', 'gravatar_url', 'unicode'),
 
                    ('clone_uri_tmpl', 'clone_uri_tmpl', 'unicode'),
 
                    ('clone_ssh_tmpl', 'clone_ssh_tmpl', 'unicode'),
 
                ]
 
                for setting, form_key, type_ in settings:
 
                    Setting.create_or_update(setting, form_result[form_key], type_)
 
                    db.Setting.create_or_update(setting, form_result[form_key], type_)
 

	
 
                meta.Session().commit()
 
                set_app_settings(config)
 
                h.flash(_('Updated visualisation settings'),
 
                        category='success')
 

	
 
@@ -268,13 +267,13 @@ class SettingsController(BaseController)
 
                h.flash(_('Error occurred during updating '
 
                          'visualisation settings'),
 
                        category='error')
 

	
 
            raise HTTPFound(location=url('admin_settings_visual'))
 

	
 
        defaults = Setting.get_app_settings()
 
        defaults = db.Setting.get_app_settings()
 
        defaults.update(self._get_hg_ui_settings())
 

	
 
        return htmlfill.render(
 
            render('admin/settings/settings.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
@@ -304,13 +303,13 @@ class SettingsController(BaseController)
 
            tasks.send_email(recipients, test_email_subj,
 
                             test_email_txt_body, test_email_html_body)
 

	
 
            h.flash(_('Send email task created'), category='success')
 
            raise HTTPFound(location=url('admin_settings_email'))
 

	
 
        defaults = Setting.get_app_settings()
 
        defaults = db.Setting.get_app_settings()
 
        defaults.update(self._get_hg_ui_settings())
 

	
 
        import kallithea
 
        c.ini = kallithea.CONFIG
 

	
 
        return htmlfill.render(
 
@@ -328,48 +327,48 @@ class SettingsController(BaseController)
 
                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()):
 
                    if ui_key in (x.ui_key for x in db.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()):
 
                    elif ui_key in (x.ui_key for x in db.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)
 
                        db.Ui.create_or_update_hook(ui_key, ui_value)
 
                        h.flash(_('Added new hook'), category='success')
 
                    elif hook_id:
 
                        Ui.delete(hook_id)
 
                        db.Ui.delete(hook_id)
 
                        meta.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)
 
                            db.Ui.create_or_update_hook(k, v)
 
                            update = True
 

	
 
                    if update:
 
                        h.flash(_('Updated hooks'), category='success')
 
                    meta.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 = db.Setting.get_app_settings()
 
        defaults.update(self._get_hg_ui_settings())
 

	
 
        c.hooks = Ui.get_builtin_hooks()
 
        c.custom_hooks = Ui.get_custom_hooks()
 
        c.hooks = db.Ui.get_builtin_hooks()
 
        c.custom_hooks = db.Ui.get_custom_hooks()
 

	
 
        return htmlfill.render(
 
            render('admin/settings/settings.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
            force_defaults=False)
 
@@ -381,31 +380,31 @@ class SettingsController(BaseController)
 
            repo_location = self._get_hg_ui_settings()['paths_root_path']
 
            full_index = request.POST.get('full_index', False)
 
            tasks.whoosh_index(repo_location, full_index)
 
            h.flash(_('Whoosh reindex task scheduled'), category='success')
 
            raise HTTPFound(location=url('admin_settings_search'))
 

	
 
        defaults = Setting.get_app_settings()
 
        defaults = db.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)
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def settings_system(self):
 
        c.active = 'system'
 

	
 
        defaults = Setting.get_app_settings()
 
        defaults = db.Setting.get_app_settings()
 
        defaults.update(self._get_hg_ui_settings())
 

	
 
        import kallithea
 
        c.ini = kallithea.CONFIG
 
        server_info = Setting.get_server_info()
 
        server_info = db.Setting.get_server_info()
 
        for key, val in server_info.items():
 
            setattr(c, key, val)
 

	
 
        return htmlfill.render(
 
            render('admin/settings/settings.html'),
 
            defaults=defaults,
kallithea/controllers/admin/user_groups.py
Show inline comments
 
@@ -40,15 +40,14 @@ from webob.exc import HTTPFound, HTTPInt
 
from kallithea.lib import helpers as h
 
from kallithea.lib.auth import HasPermissionAnyDecorator, HasUserGroupPermissionLevelDecorator, LoginRequired
 
from kallithea.lib.base import BaseController, render
 
from kallithea.lib.exceptions import RepoGroupAssignmentError, UserGroupsAssignedException
 
from kallithea.lib.utils import action_logger
 
from kallithea.lib.utils2 import safe_int, safe_str
 
from kallithea.lib.webutils import url
 
from kallithea.model import meta
 
from kallithea.model.db import User, UserGroup, UserGroupRepoGroupToPerm, UserGroupRepoToPerm, UserGroupToPerm
 
from kallithea.lib.utils3 import url
 
from kallithea.model import db, meta
 
from kallithea.model.forms import CustomDefaultPermissionsForm, UserGroupForm, UserGroupPermsForm
 
from kallithea.model.scm import UserGroupList
 
from kallithea.model.user_group import UserGroupModel
 

	
 

	
 
log = logging.getLogger(__name__)
 
@@ -63,28 +62,28 @@ class UserGroupsController(BaseControlle
 
    def __load_data(self, user_group_id):
 
        c.group_members_obj = sorted((x.user for x in c.user_group.members),
 
                                     key=lambda u: u.username.lower())
 

	
 
        c.group_members = [(x.user_id, x.username) for x in c.group_members_obj]
 
        c.available_members = sorted(((x.user_id, x.username) for x in
 
                                      User.query().all()),
 
                                      db.User.query().all()),
 
                                     key=lambda u: u[1].lower())
 

	
 
    def __load_defaults(self, user_group_id):
 
        """
 
        Load defaults settings for edit, and update
 

	
 
        :param user_group_id:
 
        """
 
        user_group = UserGroup.get_or_404(user_group_id)
 
        user_group = db.UserGroup.get_or_404(user_group_id)
 
        data = user_group.get_dict()
 
        return data
 

	
 
    def index(self, format='html'):
 
        _list = UserGroup.query() \
 
                        .order_by(func.lower(UserGroup.users_group_name)) \
 
        _list = db.UserGroup.query() \
 
                        .order_by(func.lower(db.UserGroup.users_group_name)) \
 
                        .all()
 
        group_iter = UserGroupList(_list, perm_level='admin')
 
        user_groups_data = []
 
        _tmpl_lookup = app_globals.mako_lookup
 
        template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
 

	
 
@@ -151,13 +150,13 @@ class UserGroupsController(BaseControlle
 
    @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
 
    def new(self, format='html'):
 
        return render('admin/user_groups/user_group_add.html')
 

	
 
    @HasUserGroupPermissionLevelDecorator('admin')
 
    def update(self, id):
 
        c.user_group = UserGroup.get_or_404(id)
 
        c.user_group = db.UserGroup.get_or_404(id)
 
        c.active = 'settings'
 
        self.__load_data(id)
 

	
 
        available_members = [safe_str(x[0]) for x in c.available_members]
 

	
 
        users_group_form = UserGroupForm(edit=True,
 
@@ -197,13 +196,13 @@ class UserGroupsController(BaseControlle
 
                    % request.POST.get('users_group_name'), category='error')
 

	
 
        raise HTTPFound(location=url('edit_users_group', id=id))
 

	
 
    @HasUserGroupPermissionLevelDecorator('admin')
 
    def delete(self, id):
 
        usr_gr = UserGroup.get_or_404(id)
 
        usr_gr = db.UserGroup.get_or_404(id)
 
        try:
 
            UserGroupModel().delete(usr_gr)
 
            meta.Session().commit()
 
            h.flash(_('Successfully deleted user group'), category='success')
 
        except UserGroupsAssignedException as e:
 
            h.flash(e, category='error')
 
@@ -212,13 +211,13 @@ class UserGroupsController(BaseControlle
 
            h.flash(_('An error occurred during deletion of user group'),
 
                    category='error')
 
        raise HTTPFound(location=url('users_groups'))
 

	
 
    @HasUserGroupPermissionLevelDecorator('admin')
 
    def edit(self, id, format='html'):
 
        c.user_group = UserGroup.get_or_404(id)
 
        c.user_group = db.UserGroup.get_or_404(id)
 
        c.active = 'settings'
 
        self.__load_data(id)
 

	
 
        defaults = self.__load_defaults(id)
 

	
 
        return htmlfill.render(
 
@@ -227,13 +226,13 @@ class UserGroupsController(BaseControlle
 
            encoding="UTF-8",
 
            force_defaults=False
 
        )
 

	
 
    @HasUserGroupPermissionLevelDecorator('admin')
 
    def edit_perms(self, id):
 
        c.user_group = UserGroup.get_or_404(id)
 
        c.user_group = db.UserGroup.get_or_404(id)
 
        c.active = 'perms'
 

	
 
        defaults = {}
 
        # fill user group users
 
        for p in c.user_group.user_user_group_to_perm:
 
            defaults.update({'u_perm_%s' % p.user.username:
 
@@ -254,13 +253,13 @@ class UserGroupsController(BaseControlle
 
    def update_perms(self, id):
 
        """
 
        grant permission for given usergroup
 

	
 
        :param id:
 
        """
 
        user_group = UserGroup.get_or_404(id)
 
        user_group = db.UserGroup.get_or_404(id)
 
        form = UserGroupPermsForm()().to_python(request.POST)
 

	
 
        # set the permissions !
 
        try:
 
            UserGroupModel()._update_permissions(user_group, form['perms_new'],
 
                                                 form['perms_updates'])
 
@@ -301,33 +300,33 @@ class UserGroupsController(BaseControlle
 
            h.flash(_('An error occurred during revoking of permission'),
 
                    category='error')
 
            raise HTTPInternalServerError()
 

	
 
    @HasUserGroupPermissionLevelDecorator('admin')
 
    def edit_default_perms(self, id):
 
        c.user_group = UserGroup.get_or_404(id)
 
        c.user_group = db.UserGroup.get_or_404(id)
 
        c.active = 'default_perms'
 

	
 
        permissions = {
 
            'repositories': {},
 
            'repositories_groups': {}
 
        }
 
        ugroup_repo_perms = UserGroupRepoToPerm.query() \
 
            .options(joinedload(UserGroupRepoToPerm.permission)) \
 
            .options(joinedload(UserGroupRepoToPerm.repository)) \
 
            .filter(UserGroupRepoToPerm.users_group_id == id) \
 
        ugroup_repo_perms = db.UserGroupRepoToPerm.query() \
 
            .options(joinedload(db.UserGroupRepoToPerm.permission)) \
 
            .options(joinedload(db.UserGroupRepoToPerm.repository)) \
 
            .filter(db.UserGroupRepoToPerm.users_group_id == id) \
 
            .all()
 

	
 
        for gr in ugroup_repo_perms:
 
            permissions['repositories'][gr.repository.repo_name]  \
 
                = gr.permission.permission_name
 

	
 
        ugroup_group_perms = UserGroupRepoGroupToPerm.query() \
 
            .options(joinedload(UserGroupRepoGroupToPerm.permission)) \
 
            .options(joinedload(UserGroupRepoGroupToPerm.group)) \
 
            .filter(UserGroupRepoGroupToPerm.users_group_id == id) \
 
        ugroup_group_perms = db.UserGroupRepoGroupToPerm.query() \
 
            .options(joinedload(db.UserGroupRepoGroupToPerm.permission)) \
 
            .options(joinedload(db.UserGroupRepoGroupToPerm.group)) \
 
            .filter(db.UserGroupRepoGroupToPerm.users_group_id == id) \
 
            .all()
 

	
 
        for gr in ugroup_group_perms:
 
            permissions['repositories_groups'][gr.group.group_name] \
 
                = gr.permission.permission_name
 
        c.permissions = permissions
 
@@ -350,22 +349,22 @@ class UserGroupsController(BaseControlle
 
            encoding="UTF-8",
 
            force_defaults=False
 
        )
 

	
 
    @HasUserGroupPermissionLevelDecorator('admin')
 
    def update_default_perms(self, id):
 
        user_group = UserGroup.get_or_404(id)
 
        user_group = db.UserGroup.get_or_404(id)
 

	
 
        try:
 
            form = CustomDefaultPermissionsForm()()
 
            form_result = form.to_python(request.POST)
 

	
 
            usergroup_model = UserGroupModel()
 

	
 
            defs = UserGroupToPerm.query() \
 
                .filter(UserGroupToPerm.users_group == user_group) \
 
            defs = db.UserGroupToPerm.query() \
 
                .filter(db.UserGroupToPerm.users_group == user_group) \
 
                .all()
 
            for ug in defs:
 
                meta.Session().delete(ug)
 

	
 
            if form_result['create_repo_perm']:
 
                usergroup_model.grant_perm(id, 'hg.create.repository')
 
@@ -388,21 +387,21 @@ class UserGroupsController(BaseControlle
 
                    category='error')
 

	
 
        raise HTTPFound(location=url('edit_user_group_default_perms', id=id))
 

	
 
    @HasUserGroupPermissionLevelDecorator('admin')
 
    def edit_advanced(self, id):
 
        c.user_group = UserGroup.get_or_404(id)
 
        c.user_group = db.UserGroup.get_or_404(id)
 
        c.active = 'advanced'
 
        c.group_members_obj = sorted((x.user for x in c.user_group.members),
 
                                     key=lambda u: u.username.lower())
 
        return render('admin/user_groups/user_group_edit.html')
 

	
 
    @HasUserGroupPermissionLevelDecorator('admin')
 
    def edit_members(self, id):
 
        c.user_group = UserGroup.get_or_404(id)
 
        c.user_group = db.UserGroup.get_or_404(id)
 
        c.active = 'members'
 
        c.group_members_obj = sorted((x.user for x in c.user_group.members),
 
                                     key=lambda u: u.username.lower())
 

	
 
        c.group_members = [(x.user_id, x.username) for x in c.group_members_obj]
 
        return render('admin/user_groups/user_group_edit.html')
kallithea/controllers/admin/users.py
Show inline comments
 
@@ -41,16 +41,15 @@ from kallithea.lib import auth_modules
 
from kallithea.lib import helpers as h
 
from kallithea.lib.auth import AuthUser, HasPermissionAnyDecorator, LoginRequired
 
from kallithea.lib.base import BaseController, IfSshEnabled, render
 
from kallithea.lib.exceptions import DefaultUserException, UserCreationError, UserOwnsReposException
 
from kallithea.lib.utils import action_logger
 
from kallithea.lib.utils2 import datetime_to_time, generate_api_key, safe_int
 
from kallithea.lib.webutils import url
 
from kallithea.model import meta
 
from kallithea.lib.utils3 import url
 
from kallithea.model import db, meta
 
from kallithea.model.api_key import ApiKeyModel
 
from kallithea.model.db import User, UserEmailMap, UserIpMap, UserToPerm
 
from kallithea.model.forms import CustomDefaultPermissionsForm, UserForm
 
from kallithea.model.ssh_key import SshKeyModel, SshKeyModelException
 
from kallithea.model.user import UserModel
 

	
 

	
 
log = logging.getLogger(__name__)
 
@@ -61,15 +60,15 @@ class UsersController(BaseController):
 
    @LoginRequired()
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def _before(self, *args, **kwargs):
 
        super(UsersController, self)._before(*args, **kwargs)
 

	
 
    def index(self, format='html'):
 
        c.users_list = User.query().order_by(User.username) \
 
        c.users_list = db.User.query().order_by(db.User.username) \
 
                        .filter_by(is_default_user=False) \
 
                        .order_by(func.lower(User.username)) \
 
                        .order_by(func.lower(db.User.username)) \
 
                        .all()
 

	
 
        users_data = []
 
        _tmpl_lookup = app_globals.mako_lookup
 
        template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
 

	
 
@@ -105,13 +104,13 @@ class UsersController(BaseController):
 
            "records": users_data
 
        }
 

	
 
        return render('admin/users/users.html')
 

	
 
    def create(self):
 
        c.default_extern_type = User.DEFAULT_AUTH_TYPE
 
        c.default_extern_type = db.User.DEFAULT_AUTH_TYPE
 
        c.default_extern_name = ''
 
        user_model = UserModel()
 
        user_form = UserForm()()
 
        try:
 
            form_result = user_form.to_python(dict(request.POST))
 
            user = user_model.create(form_result)
 
@@ -134,13 +133,13 @@ class UsersController(BaseController):
 
            log.error(traceback.format_exc())
 
            h.flash(_('Error occurred during creation of user %s')
 
                    % request.POST.get('username'), category='error')
 
        raise HTTPFound(location=url('edit_user', id=user.user_id))
 

	
 
    def new(self, format='html'):
 
        c.default_extern_type = User.DEFAULT_AUTH_TYPE
 
        c.default_extern_type = db.User.DEFAULT_AUTH_TYPE
 
        c.default_extern_name = ''
 
        return render('admin/users/user_add.html')
 

	
 
    def update(self, id):
 
        user_model = UserModel()
 
        user = user_model.get(id)
 
@@ -177,13 +176,13 @@ class UsersController(BaseController):
 
            log.error(traceback.format_exc())
 
            h.flash(_('Error occurred during update of user %s')
 
                    % form_result.get('username'), category='error')
 
        raise HTTPFound(location=url('edit_user', id=id))
 

	
 
    def delete(self, id):
 
        usr = User.get_or_404(id)
 
        usr = db.User.get_or_404(id)
 
        has_ssh_keys = bool(usr.ssh_keys)
 
        try:
 
            UserModel().delete(usr)
 
            meta.Session().commit()
 
            h.flash(_('Successfully deleted user'), category='success')
 
        except (UserOwnsReposException, DefaultUserException) as e:
 
@@ -196,13 +195,13 @@ class UsersController(BaseController):
 
            if has_ssh_keys:
 
                SshKeyModel().write_authorized_keys()
 
        raise HTTPFound(location=url('users'))
 

	
 
    def _get_user_or_raise_if_default(self, id):
 
        try:
 
            return User.get_or_404(id, allow_default=False)
 
            return db.User.get_or_404(id, allow_default=False)
 
        except DefaultUserException:
 
            h.flash(_("The default user cannot be edited"), category='warning')
 
            raise HTTPNotFound
 

	
 
    def _render_edit_profile(self, user):
 
        c.user = user
 
@@ -315,14 +314,14 @@ class UsersController(BaseController):
 
        try:
 
            form = CustomDefaultPermissionsForm()()
 
            form_result = form.to_python(request.POST)
 

	
 
            user_model = UserModel()
 

	
 
            defs = UserToPerm.query() \
 
                .filter(UserToPerm.user == user) \
 
            defs = db.UserToPerm.query() \
 
                .filter(db.UserToPerm.user == user) \
 
                .all()
 
            for ug in defs:
 
                meta.Session().delete(ug)
 

	
 
            if form_result['create_repo_perm']:
 
                user_model.grant_perm(id, 'hg.create.repository')
 
@@ -344,14 +343,14 @@ class UsersController(BaseController):
 
                    category='error')
 
        raise HTTPFound(location=url('edit_user_perms', id=id))
 

	
 
    def edit_emails(self, id):
 
        c.user = self._get_user_or_raise_if_default(id)
 
        c.active = 'emails'
 
        c.user_email_map = UserEmailMap.query() \
 
            .filter(UserEmailMap.user == c.user).all()
 
        c.user_email_map = db.UserEmailMap.query() \
 
            .filter(db.UserEmailMap.user == c.user).all()
 

	
 
        defaults = c.user.get_dict()
 
        return htmlfill.render(
 
            render('admin/users/user_edit.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
@@ -384,17 +383,17 @@ class UsersController(BaseController):
 
        h.flash(_("Removed email from user"), category='success')
 
        raise HTTPFound(location=url('edit_user_emails', id=id))
 

	
 
    def edit_ips(self, id):
 
        c.user = self._get_user_or_raise_if_default(id)
 
        c.active = 'ips'
 
        c.user_ip_map = UserIpMap.query() \
 
            .filter(UserIpMap.user == c.user).all()
 
        c.user_ip_map = db.UserIpMap.query() \
 
            .filter(db.UserIpMap.user == c.user).all()
 

	
 
        c.default_user_ip_map = UserIpMap.query() \
 
            .filter(UserIpMap.user_id == kallithea.DEFAULT_USER_ID).all()
 
        c.default_user_ip_map = db.UserIpMap.query() \
 
            .filter(db.UserIpMap.user_id == kallithea.DEFAULT_USER_ID).all()
 

	
 
        defaults = c.user.get_dict()
 
        return htmlfill.render(
 
            render('admin/users/user_edit.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
kallithea/controllers/api/__init__.py
Show inline comments
 
@@ -37,13 +37,13 @@ from webob.exc import HTTPError, HTTPExc
 

	
 
from kallithea.lib import ext_json
 
from kallithea.lib.auth import AuthUser
 
from kallithea.lib.base import _get_ip_addr as _get_ip
 
from kallithea.lib.base import get_path_info
 
from kallithea.lib.utils2 import ascii_bytes
 
from kallithea.model.db import User
 
from kallithea.model import db
 

	
 

	
 
log = logging.getLogger('JSONRPC')
 

	
 

	
 
class JSONRPCError(BaseException):
 
@@ -142,13 +142,13 @@ class JSONRPCController(TGController):
 
        except KeyError as e:
 
            raise JSONRPCErrorResponse(retid=self._req_id,
 
                                       message='Incorrect JSON query missing %s' % e)
 

	
 
        # check if we can find this session using api_key
 
        try:
 
            u = User.get_by_api_key(self._req_api_key)
 
            u = db.User.get_by_api_key(self._req_api_key)
 
            auth_user = AuthUser.make(dbuser=u, ip_addr=ip_addr)
 
            if auth_user is None:
 
                raise JSONRPCErrorResponse(retid=self._req_id,
 
                                           message='Invalid API key')
 
        except Exception as e:
 
            raise JSONRPCErrorResponse(retid=self._req_id,
kallithea/controllers/api/api.py
Show inline comments
 
@@ -35,16 +35,15 @@ from kallithea.controllers.api import JS
 
from kallithea.lib.auth import (AuthUser, HasPermissionAny, HasPermissionAnyDecorator, HasRepoGroupPermissionLevel, HasRepoPermissionLevel,
 
                                HasUserGroupPermissionLevel)
 
from kallithea.lib.exceptions import DefaultUserException, UserGroupsAssignedException
 
from kallithea.lib.utils import action_logger, repo2db_mapper
 
from kallithea.lib.vcs.backends.base import EmptyChangeset
 
from kallithea.lib.vcs.exceptions import EmptyRepositoryError
 
from kallithea.model import meta
 
from kallithea.model import db, meta
 
from kallithea.model.changeset_status import ChangesetStatusModel
 
from kallithea.model.comment import ChangesetCommentsModel
 
from kallithea.model.db import ChangesetStatus, Gist, Permission, PullRequest, RepoGroup, Repository, Setting, User, UserGroup, UserIpMap
 
from kallithea.model.gist import GistModel
 
from kallithea.model.pull_request import PullRequestModel
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.repo_group import RepoGroupModel
 
from kallithea.model.scm import ScmModel, UserGroupList
 
from kallithea.model.user import UserModel
 
@@ -90,13 +89,13 @@ def get_repo_or_error(repoid):
 
def get_repo_group_or_error(repogroupid):
 
    """
 
    Get repo group by id or name or return JsonRPCError if not found
 

	
 
    :param repogroupid:
 
    """
 
    repo_group = RepoGroup.guess_instance(repogroupid)
 
    repo_group = db.RepoGroup.guess_instance(repogroupid)
 
    if repo_group is None:
 
        raise JSONRPCError(
 
            'repository group `%s` does not exist' % (repogroupid,))
 
    return repo_group
 

	
 

	
 
@@ -115,13 +114,13 @@ def get_user_group_or_error(usergroupid)
 
def get_perm_or_error(permid, prefix=None):
 
    """
 
    Get permission by id or name or return JsonRPCError if not found
 

	
 
    :param permid:
 
    """
 
    perm = Permission.get_by_key(permid)
 
    perm = db.Permission.get_by_key(permid)
 
    if perm is None:
 
        raise JSONRPCError('permission `%s` does not exist' % (permid,))
 
    if prefix:
 
        if not perm.permission_name.startswith(prefix):
 
            raise JSONRPCError('permission `%s` is invalid, '
 
                               'should start with %s' % (permid, prefix))
 
@@ -320,13 +319,13 @@ class ApiController(JSONRPCController):
 
            }
 

	
 
        """
 
        if userid is None:
 
            userid = request.authuser.user_id
 
        user = get_user_or_error(userid)
 
        ips = UserIpMap.query().filter(UserIpMap.user == user).all()
 
        ips = db.UserIpMap.query().filter(db.UserIpMap.user == user).all()
 
        return dict(
 
            server_ip_addr=request.ip_addr,
 
            user_ips=ips
 
        )
 

	
 
    # alias for old
 
@@ -346,13 +345,13 @@ class ApiController(JSONRPCController):
 
            'py_version': <python version>,
 
            'platform': <platform type>,
 
            'kallithea_version': <kallithea version>
 
          }
 
          error :  null
 
        """
 
        return Setting.get_server_info()
 
        return db.Setting.get_server_info()
 

	
 
    def get_user(self, userid=None):
 
        """
 
        Gets a user by username or user_id, Returns empty result if user is
 
        not found. If userid param is skipped it is set to id of user who is
 
        calling this method. This command can be executed only using api_key
 
@@ -422,22 +421,22 @@ class ApiController(JSONRPCController):
 
            result: [<user_object>, ...]
 
            error:  null
 
        """
 

	
 
        return [
 
            user.get_api_data()
 
            for user in User.query()
 
                .order_by(User.username)
 
            for user in db.User.query()
 
                .order_by(db.User.username)
 
                .filter_by(is_default_user=False)
 
        ]
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def create_user(self, username, email, password='',
 
                    firstname='', lastname='',
 
                    active=True, admin=False,
 
                    extern_type=User.DEFAULT_AUTH_TYPE,
 
                    extern_type=db.User.DEFAULT_AUTH_TYPE,
 
                    extern_name=''):
 
        """
 
        Creates new user. Returns new user object. This command can
 
        be executed only using api_key belonging to user with admin rights.
 

	
 
        :param username: new username
 
@@ -480,16 +479,16 @@ class ApiController(JSONRPCController):
 
            or
 
            "failed to create user `<username>`"
 
          }
 

	
 
        """
 

	
 
        if User.get_by_username(username):
 
        if db.User.get_by_username(username):
 
            raise JSONRPCError("user `%s` already exist" % (username,))
 

	
 
        if User.get_by_email(email):
 
        if db.User.get_by_email(email):
 
            raise JSONRPCError("email `%s` already exist" % (email,))
 

	
 
        try:
 
            user = UserModel().create_or_update(
 
                username=username,
 
                password=password,
 
@@ -678,13 +677,13 @@ class ApiController(JSONRPCController):
 
            result : [<user_group_obj>,...]
 
            error : null
 
        """
 

	
 
        return [
 
            user_group.get_api_data()
 
            for user_group in UserGroupList(UserGroup.query().all(), perm_level='read')
 
            for user_group in UserGroupList(db.UserGroup.query().all(), perm_level='read')
 
        ]
 

	
 
    @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
 
    def create_user_group(self, group_name, description='',
 
                          owner=None, active=True):
 
        """
 
@@ -1097,13 +1096,13 @@ class ApiController(JSONRPCController):
 
                    ]
 
            error:  null
 
        """
 
        if not HasPermissionAny('hg.admin')():
 
            repos = RepoModel().get_all_user_repos(user=request.authuser.user_id)
 
        else:
 
            repos = Repository.query()
 
            repos = db.Repository.query()
 

	
 
        return [
 
            repo.get_api_data()
 
            for repo in repos
 
        ]
 

	
 
@@ -1232,13 +1231,13 @@ class ApiController(JSONRPCController):
 

	
 
        owner = get_user_or_error(owner)
 

	
 
        if RepoModel().get_by_repo_name(repo_name):
 
            raise JSONRPCError("repo `%s` already exist" % repo_name)
 

	
 
        defs = Setting.get_default_repo_settings(strip_prefix=True)
 
        defs = db.Setting.get_default_repo_settings(strip_prefix=True)
 
        if private is None:
 
            private = defs.get('repo_private') or False
 
        if repo_type is None:
 
            repo_type = defs.get('repo_type')
 
        if enable_statistics is None:
 
            enable_statistics = defs.get('repo_enable_statistics')
 
@@ -1247,13 +1246,13 @@ class ApiController(JSONRPCController):
 

	
 
        try:
 
            repo_name_parts = repo_name.split('/')
 
            repo_group = None
 
            if len(repo_name_parts) > 1:
 
                group_name = '/'.join(repo_name_parts[:-1])
 
                repo_group = RepoGroup.get_by_group_name(group_name)
 
                repo_group = db.RepoGroup.get_by_group_name(group_name)
 
                if repo_group is None:
 
                    raise JSONRPCError("repo group `%s` not found" % group_name)
 
            data = dict(
 
                repo_name=repo_name_parts[-1],
 
                repo_name_full=repo_name,
 
                repo_type=repo_type,
 
@@ -1423,13 +1422,13 @@ class ApiController(JSONRPCController):
 

	
 
        try:
 
            fork_name_parts = fork_name.split('/')
 
            repo_group = None
 
            if len(fork_name_parts) > 1:
 
                group_name = '/'.join(fork_name_parts[:-1])
 
                repo_group = RepoGroup.get_by_group_name(group_name)
 
                repo_group = db.RepoGroup.get_by_group_name(group_name)
 
                if repo_group is None:
 
                    raise JSONRPCError("repo group `%s` not found" % group_name)
 

	
 
            form_data = dict(
 
                repo_name=fork_name_parts[-1],
 
                repo_name_full=fork_name,
 
@@ -1753,13 +1752,13 @@ class ApiController(JSONRPCController):
 
        """
 
        Returns all repository groups
 

	
 
        """
 
        return [
 
            repo_group.get_api_data()
 
            for repo_group in RepoGroup.query()
 
            for repo_group in db.RepoGroup.query()
 
        ]
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def create_repo_group(self, group_name, description='',
 
                          owner=None,
 
                          parent=None,
 
@@ -1794,13 +1793,13 @@ class ApiController(JSONRPCController):
 
          result : null
 
          error :  {
 
            failed to create repo group `<repogroupid>`
 
          }
 

	
 
        """
 
        if RepoGroup.get_by_group_name(group_name):
 
        if db.RepoGroup.get_by_group_name(group_name):
 
            raise JSONRPCError("repo group `%s` already exist" % (group_name,))
 

	
 
        if owner is None:
 
            owner = request.authuser.user_id
 
        group_description = description
 
        parent_group = None
 
@@ -2187,20 +2186,20 @@ class ApiController(JSONRPCController):
 
            user_id = request.authuser.user_id
 
        else:
 
            user_id = get_user_or_error(userid).user_id
 

	
 
        return [
 
            gist.get_api_data()
 
            for gist in Gist().query()
 
            for gist in db.Gist().query()
 
                .filter_by(is_expired=False)
 
                .filter(Gist.owner_id == user_id)
 
                .order_by(Gist.created_on.desc())
 
                .filter(db.Gist.owner_id == user_id)
 
                .order_by(db.Gist.created_on.desc())
 
        ]
 

	
 
    def create_gist(self, files, owner=None,
 
                    gist_type=Gist.GIST_PUBLIC, lifetime=-1,
 
                    gist_type=db.Gist.GIST_PUBLIC, lifetime=-1,
 
                    description=''):
 

	
 
        """
 
        Creates new Gist
 

	
 
        :param files: files to be added to gist
 
@@ -2337,26 +2336,26 @@ class ApiController(JSONRPCController):
 

	
 
    # permission check inside
 
    def get_pullrequest(self, pullrequest_id):
 
        """
 
        Get given pull request by id
 
        """
 
        pull_request = PullRequest.get(pullrequest_id)
 
        pull_request = db.PullRequest.get(pullrequest_id)
 
        if pull_request is None:
 
            raise JSONRPCError('pull request `%s` does not exist' % (pullrequest_id,))
 
        if not HasRepoPermissionLevel('read')(pull_request.org_repo.repo_name):
 
            raise JSONRPCError('not allowed')
 
        return pull_request.get_api_data()
 

	
 
    # permission check inside
 
    def comment_pullrequest(self, pull_request_id, comment_msg='', status=None, close_pr=False):
 
        """
 
        Add comment, close and change status of pull request.
 
        """
 
        apiuser = get_user_or_error(request.authuser.user_id)
 
        pull_request = PullRequest.get(pull_request_id)
 
        pull_request = db.PullRequest.get(pull_request_id)
 
        if pull_request is None:
 
            raise JSONRPCError('pull request `%s` does not exist' % (pull_request_id,))
 
        if (not HasRepoPermissionLevel('read')(pull_request.org_repo.repo_name)):
 
            raise JSONRPCError('No permission to add comment. User needs at least reading permissions'
 
                               ' to the source repository.')
 
        owner = apiuser.user_id == pull_request.owner_id
 
@@ -2372,13 +2371,13 @@ class ApiController(JSONRPCController):
 
            text=comment_msg,
 
            repo=pull_request.org_repo.repo_id,
 
            author=apiuser.user_id,
 
            pull_request=pull_request.pull_request_id,
 
            f_path=None,
 
            line_no=None,
 
            status_change=ChangesetStatus.get_status_lbl(status),
 
            status_change=db.ChangesetStatus.get_status_lbl(status),
 
            closing_pr=close_pr
 
        )
 
        action_logger(apiuser,
 
                      'user_commented_pull_request:%s' % pull_request_id,
 
                      pull_request.org_repo, request.ip_addr)
 
        if status:
 
@@ -2404,13 +2403,13 @@ class ApiController(JSONRPCController):
 
        or user ID. Reviewers are specified either as a single-user string or
 
        as a JSON list of one or more strings.
 
        """
 
        if add is None and remove is None:
 
            raise JSONRPCError('''Invalid request. Neither 'add' nor 'remove' is specified.''')
 

	
 
        pull_request = PullRequest.get(pull_request_id)
 
        pull_request = db.PullRequest.get(pull_request_id)
 
        if pull_request is None:
 
            raise JSONRPCError('pull request `%s` does not exist' % (pull_request_id,))
 

	
 
        apiuser = get_user_or_error(request.authuser.user_id)
 
        is_owner = apiuser.user_id == pull_request.owner_id
 
        is_repo_admin = HasRepoPermissionLevel('admin')(pull_request.other_repo.repo_name)
kallithea/controllers/changeset.py
Show inline comments
 
@@ -41,16 +41,15 @@ from kallithea.lib.auth import HasRepoPe
 
from kallithea.lib.base import BaseRepoController, jsonify, render
 
from kallithea.lib.graphmod import graph_data
 
from kallithea.lib.utils import action_logger
 
from kallithea.lib.utils2 import ascii_str, safe_str
 
from kallithea.lib.vcs.backends.base import EmptyChangeset
 
from kallithea.lib.vcs.exceptions import ChangesetDoesNotExistError, EmptyRepositoryError, RepositoryError
 
from kallithea.model import meta
 
from kallithea.model import db, meta
 
from kallithea.model.changeset_status import ChangesetStatusModel
 
from kallithea.model.comment import ChangesetCommentsModel
 
from kallithea.model.db import ChangesetComment, ChangesetStatus
 
from kallithea.model.pull_request import PullRequestModel
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
@@ -112,13 +111,13 @@ def create_cs_pr_comment(repo_name, revi
 
        repo=c.db_repo.repo_id,
 
        author=request.authuser.user_id,
 
        revision=revision,
 
        pull_request=pull_request_id,
 
        f_path=f_path or None,
 
        line_no=line_no or None,
 
        status_change=ChangesetStatus.get_status_lbl(status) if status else None,
 
        status_change=db.ChangesetStatus.get_status_lbl(status) if status else None,
 
        closing_pr=close_pr,
 
    )
 

	
 
    if status:
 
        ChangesetStatusModel().set_status(
 
            c.db_repo.repo_id,
 
@@ -153,13 +152,13 @@ def create_cs_pr_comment(repo_name, revi
 
                     render('changeset/changeset_comment_block.html')})
 

	
 
    return data
 

	
 
def delete_cs_pr_comment(repo_name, comment_id):
 
    """Delete a comment from a changeset or pull request"""
 
    co = ChangesetComment.get_or_404(comment_id)
 
    co = db.ChangesetComment.get_or_404(comment_id)
 
    if co.repo.repo_name != repo_name:
 
        raise HTTPNotFound()
 
    if co.pull_request and co.pull_request.is_closed():
 
        # don't allow deleting comments on closed pull request
 
        raise HTTPForbidden()
 

	
 
@@ -207,13 +206,13 @@ class ChangesetController(BaseRepoContro
 

	
 
        c.changes = OrderedDict()
 

	
 
        c.lines_added = 0  # count of lines added
 
        c.lines_deleted = 0  # count of lines removes
 

	
 
        c.changeset_statuses = ChangesetStatus.STATUSES
 
        c.changeset_statuses = db.ChangesetStatus.STATUSES
 
        comments = dict()
 
        c.statuses = []
 
        c.inline_comments = []
 
        c.inline_cnt = 0
 

	
 
        # Iterate over ranges (default changeset view is always one changeset)
kallithea/controllers/compare.py
Show inline comments
 
@@ -36,14 +36,14 @@ from webob.exc import HTTPBadRequest, HT
 

	
 
from kallithea.lib import diffs
 
from kallithea.lib import helpers as h
 
from kallithea.lib.auth import HasRepoPermissionLevelDecorator, LoginRequired
 
from kallithea.lib.base import BaseRepoController, render
 
from kallithea.lib.graphmod import graph_data
 
from kallithea.lib.webutils import url
 
from kallithea.model.db import Repository
 
from kallithea.lib.utils3 import url
 
from kallithea.model import db
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class CompareController(BaseRepoController):
 
@@ -56,13 +56,13 @@ class CompareController(BaseRepoControll
 

	
 
        # Retrieve the "changeset" repository (default: same as base).
 
        other_repo = request.GET.get('other_repo', None)
 
        if other_repo is None:
 
            c.cs_repo = c.a_repo
 
        else:
 
            c.cs_repo = Repository.get_by_repo_name(other_repo)
 
            c.cs_repo = db.Repository.get_by_repo_name(other_repo)
 
            if c.cs_repo is None:
 
                msg = _('Could not find other repository %s') % other_repo
 
                h.flash(msg, category='error')
 
                raise HTTPFound(location=url('compare_home', repo_name=c.a_repo.repo_name))
 

	
 
        # Verify that it's even possible to compare these two repositories.
kallithea/controllers/followers.py
Show inline comments
 
@@ -31,27 +31,27 @@ from tg import request
 
from tg import tmpl_context as c
 

	
 
from kallithea.lib.auth import HasRepoPermissionLevelDecorator, LoginRequired
 
from kallithea.lib.base import BaseRepoController, render
 
from kallithea.lib.page import Page
 
from kallithea.lib.utils2 import safe_int
 
from kallithea.model.db import UserFollowing
 
from kallithea.model import db
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class FollowersController(BaseRepoController):
 

	
 
    @LoginRequired(allow_default_user=True)
 
    @HasRepoPermissionLevelDecorator('read')
 
    def followers(self, repo_name):
 
        p = safe_int(request.GET.get('page'), 1)
 
        repo_id = c.db_repo.repo_id
 
        d = UserFollowing.get_repo_followers(repo_id) \
 
            .order_by(UserFollowing.follows_from)
 
        d = db.UserFollowing.get_repo_followers(repo_id) \
 
            .order_by(db.UserFollowing.follows_from)
 
        c.followers_pager = Page(d, page=p, items_per_page=20)
 

	
 
        if request.environ.get('HTTP_X_PARTIAL_XHR'):
 
            return render('/followers/followers_data.html')
 

	
 
        return render('/followers/followers.html')
kallithea/controllers/forks.py
Show inline comments
 
@@ -38,14 +38,14 @@ from webob.exc import HTTPFound
 
import kallithea
 
import kallithea.lib.helpers as h
 
from kallithea.lib.auth import HasPermissionAnyDecorator, HasRepoPermissionLevel, HasRepoPermissionLevelDecorator, LoginRequired
 
from kallithea.lib.base import BaseRepoController, render
 
from kallithea.lib.page import Page
 
from kallithea.lib.utils2 import safe_int
 
from kallithea.lib.webutils import url
 
from kallithea.model.db import Repository, Ui, UserFollowing
 
from kallithea.lib.utils3 import url
 
from kallithea.model import db
 
from kallithea.model.forms import RepoForkForm
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.scm import AvailableRepoGroupChoices, ScmModel
 

	
 

	
 
log = logging.getLogger(__name__)
 
@@ -55,13 +55,13 @@ class ForksController(BaseRepoController
 

	
 
    def __load_defaults(self):
 
        c.repo_groups = AvailableRepoGroupChoices('write')
 

	
 
        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
 
        c.can_update = db.Ui.get_by_key('hooks', db.Ui.HOOK_UPDATE).ui_active
 

	
 
    def __load_data(self):
 
        """
 
        Load defaults settings for edit, and update
 
        """
 
        self.__load_defaults()
 
@@ -71,15 +71,15 @@ class ForksController(BaseRepoController
 

	
 
        if c.repo_info is None:
 
            h.not_mapped_error(c.repo_name)
 
            raise HTTPFound(location=url('repos'))
 

	
 
        c.default_user_id = kallithea.DEFAULT_USER_ID
 
        c.in_public_journal = UserFollowing.query() \
 
            .filter(UserFollowing.user_id == c.default_user_id) \
 
            .filter(UserFollowing.follows_repository == c.repo_info).scalar()
 
        c.in_public_journal = db.UserFollowing.query() \
 
            .filter(db.UserFollowing.user_id == c.default_user_id) \
 
            .filter(db.UserFollowing.follows_repository == c.repo_info).scalar()
 

	
 
        if c.repo_info.stats:
 
            last_rev = c.repo_info.stats.stat_on_revision + 1
 
        else:
 
            last_rev = 0
 
        c.stats_revision = last_rev
 
@@ -105,13 +105,13 @@ class ForksController(BaseRepoController
 
    @LoginRequired(allow_default_user=True)
 
    @HasRepoPermissionLevelDecorator('read')
 
    def forks(self, repo_name):
 
        p = safe_int(request.GET.get('page'), 1)
 
        repo_id = c.db_repo.repo_id
 
        d = []
 
        for r in Repository.get_repo_forks(repo_id):
 
        for r in db.Repository.get_repo_forks(repo_id):
 
            if not HasRepoPermissionLevel('read')(r.repo_name, 'get forks check'):
 
                continue
 
            d.append(r)
 
        c.forks_pager = Page(d, page=p, items_per_page=20)
 

	
 
        if request.environ.get('HTTP_X_PARTIAL_XHR'):
 
@@ -120,13 +120,13 @@ class ForksController(BaseRepoController
 
        return render('/forks/forks.html')
 

	
 
    @LoginRequired()
 
    @HasPermissionAnyDecorator('hg.admin', 'hg.fork.repository')
 
    @HasRepoPermissionLevelDecorator('read')
 
    def fork(self, repo_name):
 
        c.repo_info = Repository.get_by_repo_name(repo_name)
 
        c.repo_info = db.Repository.get_by_repo_name(repo_name)
 
        if not c.repo_info:
 
            h.not_mapped_error(repo_name)
 
            raise HTTPFound(location=url('home'))
 

	
 
        defaults = self.__load_data()
 

	
 
@@ -138,23 +138,23 @@ class ForksController(BaseRepoController
 

	
 
    @LoginRequired()
 
    @HasPermissionAnyDecorator('hg.admin', 'hg.fork.repository')
 
    @HasRepoPermissionLevelDecorator('read')
 
    def fork_create(self, repo_name):
 
        self.__load_defaults()
 
        c.repo_info = Repository.get_by_repo_name(repo_name)
 
        c.repo_info = db.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:
 
            if not db.Ui.get_by_key('hooks', db.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
kallithea/controllers/home.py
Show inline comments
 
@@ -35,13 +35,13 @@ from tg.i18n import ugettext as _
 
from webob.exc import HTTPBadRequest
 

	
 
from kallithea.lib import helpers as h
 
from kallithea.lib.auth import HasRepoPermissionLevelDecorator, LoginRequired
 
from kallithea.lib.base import BaseController, jsonify, render
 
from kallithea.lib.utils2 import safe_str
 
from kallithea.model.db import RepoGroup, Repository, User, UserGroup
 
from kallithea.model import db
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.scm import UserGroupList
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -53,27 +53,27 @@ class HomeController(BaseController):
 

	
 
    @LoginRequired(allow_default_user=True)
 
    def index(self):
 
        c.group = None
 

	
 
        repo_groups_list = self.scm_model.get_repo_groups()
 
        repos_list = Repository.query(sorted=True).filter_by(group=None).all()
 
        repos_list = db.Repository.query(sorted=True).filter_by(group=None).all()
 

	
 
        c.data = RepoModel().get_repos_as_dict(repos_list,
 
                                               repo_groups_list=repo_groups_list,
 
                                               short_name=True)
 

	
 
        return render('/index.html')
 

	
 
    @LoginRequired(allow_default_user=True)
 
    @jsonify
 
    def repo_switcher_data(self):
 
        if request.is_xhr:
 
            all_repos = Repository.query(sorted=True).all()
 
            all_repos = db.Repository.query(sorted=True).all()
 
            repo_iter = self.scm_model.get_repos(all_repos)
 
            all_groups = RepoGroup.query(sorted=True).all()
 
            all_groups = db.RepoGroup.query(sorted=True).all()
 
            repo_groups_iter = self.scm_model.get_repo_groups(all_groups)
 

	
 
            res = [{
 
                    'text': _('Groups'),
 
                    'children': [
 
                       {'id': obj.group_name,
 
@@ -108,13 +108,13 @@ class HomeController(BaseController):
 
            raise HTTPBadRequest()
 

	
 
    @LoginRequired(allow_default_user=True)
 
    @HasRepoPermissionLevelDecorator('read')
 
    @jsonify
 
    def repo_refs_data(self, repo_name):
 
        repo = Repository.get_by_repo_name(repo_name).scm_instance
 
        repo = db.Repository.get_by_repo_name(repo_name).scm_instance
 
        res = []
 
        _branches = repo.branches.items()
 
        if _branches:
 
            res.append({
 
                'text': _('Branch'),
 
                'children': [{'id': safe_str(rev), 'text': safe_str(name), 'type': 'branch'} for name, rev in _branches]
 
@@ -160,26 +160,26 @@ class HomeController(BaseController):
 
        key = request.GET.get('key', '')
 
        query = request.GET.get('query', '')
 
        results = []
 
        if 'users' in types:
 
            user_list = []
 
            if key:
 
                u = User.get_by_username(key)
 
                u = db.User.get_by_username(key)
 
                if u:
 
                    user_list = [u]
 
            elif query:
 
                user_list = User.query() \
 
                    .filter(User.is_default_user == False) \
 
                    .filter(User.active == True) \
 
                user_list = db.User.query() \
 
                    .filter(db.User.is_default_user == False) \
 
                    .filter(db.User.active == True) \
 
                    .filter(or_(
 
                        User.username.ilike("%%" + query + "%%"),
 
                        User.name.concat(' ').concat(User.lastname).ilike("%%" + query + "%%"),
 
                        User.lastname.concat(' ').concat(User.name).ilike("%%" + query + "%%"),
 
                        User.email.ilike("%%" + query + "%%"),
 
                        db.User.username.ilike("%%" + query + "%%"),
 
                        db.User.name.concat(' ').concat(db.User.lastname).ilike("%%" + query + "%%"),
 
                        db.User.lastname.concat(' ').concat(db.User.name).ilike("%%" + query + "%%"),
 
                        db.User.email.ilike("%%" + query + "%%"),
 
                    )) \
 
                    .order_by(User.username) \
 
                    .order_by(db.User.username) \
 
                    .limit(500) \
 
                    .all()
 
            for u in user_list:
 
                results.append({
 
                    'type': 'user',
 
                    'id': u.user_id,
 
@@ -189,20 +189,20 @@ class HomeController(BaseController):
 
                    'gravatar_lnk': h.gravatar_url(u.email, size=28, default='default'),
 
                    'gravatar_size': 14,
 
                })
 
        if 'groups' in types:
 
            grp_list = []
 
            if key:
 
                grp = UserGroup.get_by_group_name(key)
 
                grp = db.UserGroup.get_by_group_name(key)
 
                if grp:
 
                    grp_list = [grp]
 
            elif query:
 
                grp_list = UserGroup.query() \
 
                    .filter(UserGroup.users_group_name.ilike("%%" + query + "%%")) \
 
                    .filter(UserGroup.users_group_active == True) \
 
                    .order_by(UserGroup.users_group_name) \
 
                grp_list = db.UserGroup.query() \
 
                    .filter(db.UserGroup.users_group_name.ilike("%%" + query + "%%")) \
 
                    .filter(db.UserGroup.users_group_active == True) \
 
                    .order_by(db.UserGroup.users_group_name) \
 
                    .limit(500) \
 
                    .all()
 
            for g in UserGroupList(grp_list, perm_level='read'):
 
                results.append({
 
                    'type': 'group',
 
                    'id': g.users_group_id,
kallithea/controllers/journal.py
Show inline comments
 
@@ -40,14 +40,13 @@ import kallithea.lib.helpers as h
 
from kallithea.controllers.admin.admin import _journal_filter
 
from kallithea.lib import feeds
 
from kallithea.lib.auth import LoginRequired
 
from kallithea.lib.base import BaseController, render
 
from kallithea.lib.page import Page
 
from kallithea.lib.utils2 import AttributeDict, safe_int
 
from kallithea.model import meta
 
from kallithea.model.db import Repository, User, UserFollowing, UserLog
 
from kallithea.model import db, meta
 
from kallithea.model.repo import RepoModel
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
@@ -81,26 +80,26 @@ class JournalController(BaseController):
 
        user_ids = [x.follows_user_id for x in following_repos
 
                    if x.follows_user_id is not None]
 

	
 
        filtering_criterion = None
 

	
 
        if repo_ids and user_ids:
 
            filtering_criterion = or_(UserLog.repository_id.in_(repo_ids),
 
                        UserLog.user_id.in_(user_ids))
 
            filtering_criterion = or_(db.UserLog.repository_id.in_(repo_ids),
 
                        db.UserLog.user_id.in_(user_ids))
 
        if repo_ids and not user_ids:
 
            filtering_criterion = UserLog.repository_id.in_(repo_ids)
 
            filtering_criterion = db.UserLog.repository_id.in_(repo_ids)
 
        if not repo_ids and user_ids:
 
            filtering_criterion = UserLog.user_id.in_(user_ids)
 
            filtering_criterion = db.UserLog.user_id.in_(user_ids)
 
        if filtering_criterion is not None:
 
            journal = UserLog.query() \
 
                .options(joinedload(UserLog.user)) \
 
                .options(joinedload(UserLog.repository))
 
            journal = db.UserLog.query() \
 
                .options(joinedload(db.UserLog.user)) \
 
                .options(joinedload(db.UserLog.repository))
 
            # filter
 
            journal = _journal_filter(journal, c.search_term)
 
            journal = journal.filter(filtering_criterion) \
 
                        .order_by(UserLog.action_date.desc())
 
                        .order_by(db.UserLog.action_date.desc())
 
        else:
 
            journal = []
 

	
 
        return journal
 

	
 
    def _feed(self, repos, feeder, link, desc):
 
@@ -163,51 +162,51 @@ class JournalController(BaseController):
 
        return self._feed(repos, feeds.RssFeed, link, desc)
 

	
 
    @LoginRequired()
 
    def index(self):
 
        # Return a rendered template
 
        p = safe_int(request.GET.get('page'), 1)
 
        c.user = User.get(request.authuser.user_id)
 
        c.following = UserFollowing.query() \
 
            .filter(UserFollowing.user_id == request.authuser.user_id) \
 
            .options(joinedload(UserFollowing.follows_repository)) \
 
        c.user = db.User.get(request.authuser.user_id)
 
        c.following = db.UserFollowing.query() \
 
            .filter(db.UserFollowing.user_id == request.authuser.user_id) \
 
            .options(joinedload(db.UserFollowing.follows_repository)) \
 
            .all()
 

	
 
        journal = self._get_journal_data(c.following)
 

	
 
        c.journal_pager = Page(journal, page=p, items_per_page=20,
 
                               filter=c.search_term)
 
        c.journal_day_aggregate = self._get_daily_aggregate(c.journal_pager)
 

	
 
        if request.environ.get('HTTP_X_PARTIAL_XHR'):
 
            return render('journal/journal_data.html')
 

	
 
        repos_list = Repository.query(sorted=True) \
 
        repos_list = db.Repository.query(sorted=True) \
 
            .filter_by(owner_id=request.authuser.user_id).all()
 

	
 
        repos_data = RepoModel().get_repos_as_dict(repos_list, admin=True)
 
        # data used to render the grid
 
        c.data = repos_data
 

	
 
        return render('journal/journal.html')
 

	
 
    @LoginRequired()
 
    def journal_atom(self):
 
        """Produce a simple atom-1.0 feed"""
 
        following = UserFollowing.query() \
 
            .filter(UserFollowing.user_id == request.authuser.user_id) \
 
            .options(joinedload(UserFollowing.follows_repository)) \
 
        following = db.UserFollowing.query() \
 
            .filter(db.UserFollowing.user_id == request.authuser.user_id) \
 
            .options(joinedload(db.UserFollowing.follows_repository)) \
 
            .all()
 
        return self._atom_feed(following, public=False)
 

	
 
    @LoginRequired()
 
    def journal_rss(self):
 
        """Produce a simple rss2 feed"""
 
        following = UserFollowing.query() \
 
            .filter(UserFollowing.user_id == request.authuser.user_id) \
 
            .options(joinedload(UserFollowing.follows_repository)) \
 
        following = db.UserFollowing.query() \
 
            .filter(db.UserFollowing.user_id == request.authuser.user_id) \
 
            .options(joinedload(db.UserFollowing.follows_repository)) \
 
            .all()
 
        return self._rss_feed(following, public=False)
 

	
 
    @LoginRequired()
 
    def toggle_following(self):
 
        user_id = request.POST.get('follows_user_id')
 
@@ -236,15 +235,15 @@ class JournalController(BaseController):
 

	
 
    @LoginRequired(allow_default_user=True)
 
    def public_journal(self):
 
        # Return a rendered template
 
        p = safe_int(request.GET.get('page'), 1)
 

	
 
        c.following = UserFollowing.query() \
 
            .filter(UserFollowing.user_id == request.authuser.user_id) \
 
            .options(joinedload(UserFollowing.follows_repository)) \
 
        c.following = db.UserFollowing.query() \
 
            .filter(db.UserFollowing.user_id == request.authuser.user_id) \
 
            .options(joinedload(db.UserFollowing.follows_repository)) \
 
            .all()
 

	
 
        journal = self._get_journal_data(c.following)
 

	
 
        c.journal_pager = Page(journal, page=p, items_per_page=20)
 

	
 
@@ -255,22 +254,22 @@ class JournalController(BaseController):
 

	
 
        return render('journal/public_journal.html')
 

	
 
    @LoginRequired(allow_default_user=True)
 
    def public_journal_atom(self):
 
        """Produce a simple atom-1.0 feed"""
 
        c.following = UserFollowing.query() \
 
            .filter(UserFollowing.user_id == request.authuser.user_id) \
 
            .options(joinedload(UserFollowing.follows_repository)) \
 
        c.following = db.UserFollowing.query() \
 
            .filter(db.UserFollowing.user_id == request.authuser.user_id) \
 
            .options(joinedload(db.UserFollowing.follows_repository)) \
 
            .all()
 

	
 
        return self._atom_feed(c.following)
 

	
 
    @LoginRequired(allow_default_user=True)
 
    def public_journal_rss(self):
 
        """Produce a simple rss2 feed"""
 
        c.following = UserFollowing.query() \
 
            .filter(UserFollowing.user_id == request.authuser.user_id) \
 
            .options(joinedload(UserFollowing.follows_repository)) \
 
        c.following = db.UserFollowing.query() \
 
            .filter(db.UserFollowing.user_id == request.authuser.user_id) \
 
            .options(joinedload(db.UserFollowing.follows_repository)) \
 
            .all()
 

	
 
        return self._rss_feed(c.following)
kallithea/controllers/login.py
Show inline comments
 
@@ -37,15 +37,14 @@ from tg.i18n import ugettext as _
 
from webob.exc import HTTPBadRequest, HTTPFound
 

	
 
import kallithea.lib.helpers as h
 
from kallithea.lib.auth import AuthUser, HasPermissionAnyDecorator
 
from kallithea.lib.base import BaseController, log_in_user, render
 
from kallithea.lib.exceptions import UserCreationError
 
from kallithea.lib.webutils import url
 
from kallithea.model import meta
 
from kallithea.model.db import Setting, User
 
from kallithea.lib.utils3 import url
 
from kallithea.model import db, meta
 
from kallithea.model.forms import LoginForm, PasswordResetConfirmationForm, PasswordResetRequestForm, RegisterForm
 
from kallithea.model.user import UserModel
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -79,13 +78,13 @@ class LoginController(BaseController):
 
            # import Login Form validator class
 
            login_form = LoginForm()()
 
            try:
 
                # login_form will check username/password using ValidAuth and report failure to the user
 
                c.form_result = login_form.to_python(dict(request.POST))
 
                username = c.form_result['username']
 
                user = User.get_by_username_or_email(username)
 
                user = db.User.get_by_username_or_email(username)
 
                assert user is not None  # the same user get just passed in the form validation
 
            except formencode.Invalid as errors:
 
                defaults = errors.value
 
                # remove password from filling in form again
 
                defaults.pop('password', None)
 
                return htmlfill.render(
 
@@ -115,16 +114,16 @@ class LoginController(BaseController):
 

	
 
        return render('/login.html')
 

	
 
    @HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate',
 
                               'hg.register.manual_activate')
 
    def register(self):
 
        def_user_perms = AuthUser(dbuser=User.get_default_user()).global_permissions
 
        def_user_perms = AuthUser(dbuser=db.User.get_default_user()).global_permissions
 
        c.auto_active = 'hg.register.auto_activate' in def_user_perms
 

	
 
        settings = Setting.get_app_settings()
 
        settings = db.Setting.get_app_settings()
 
        captcha_private_key = settings.get('captcha_private_key')
 
        c.captcha_active = bool(captcha_private_key)
 
        c.captcha_public_key = settings.get('captcha_public_key')
 

	
 
        if request.POST:
 
            register_form = RegisterForm()()
 
@@ -165,13 +164,13 @@ class LoginController(BaseController):
 
                # Exception itself
 
                h.flash(e, 'error')
 

	
 
        return render('/register.html')
 

	
 
    def password_reset(self):
 
        settings = Setting.get_app_settings()
 
        settings = db.Setting.get_app_settings()
 
        captcha_private_key = settings.get('captcha_private_key')
 
        c.captcha_active = bool(captcha_private_key)
 
        c.captcha_public_key = settings.get('captcha_public_key')
 

	
 
        if request.POST:
 
            password_reset_form = PasswordResetRequestForm()()
kallithea/controllers/pullrequests.py
Show inline comments
 
@@ -42,27 +42,26 @@ from kallithea.lib.auth import HasRepoPe
 
from kallithea.lib.base import BaseRepoController, jsonify, render
 
from kallithea.lib.graphmod import graph_data
 
from kallithea.lib.page import Page
 
from kallithea.lib.utils2 import ascii_bytes, safe_bytes, safe_int
 
from kallithea.lib.vcs.exceptions import ChangesetDoesNotExistError, EmptyRepositoryError
 
from kallithea.lib.webutils import url
 
from kallithea.model import meta
 
from kallithea.model import db, meta
 
from kallithea.model.changeset_status import ChangesetStatusModel
 
from kallithea.model.comment import ChangesetCommentsModel
 
from kallithea.model.db import ChangesetStatus, PullRequest, PullRequestReviewer, Repository, User
 
from kallithea.model.forms import PullRequestForm, PullRequestPostForm
 
from kallithea.model.pull_request import CreatePullRequestAction, CreatePullRequestIterationAction, PullRequestModel
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
def _get_reviewer(user_id):
 
    """Look up user by ID and validate it as a potential reviewer."""
 
    try:
 
        user = User.get(int(user_id))
 
        user = db.User.get(int(user_id))
 
    except ValueError:
 
        user = None
 

	
 
    if user is None or user.is_default_user:
 
        h.flash(_('Invalid reviewer "%s" specified') % user_id, category='error')
 
        raise HTTPBadRequest()
 
@@ -180,15 +179,15 @@ class PullrequestsController(BaseRepoCon
 

	
 
    def _is_allowed_to_change_status(self, pull_request):
 
        if pull_request.is_closed():
 
            return False
 

	
 
        owner = request.authuser.user_id == pull_request.owner_id
 
        reviewer = PullRequestReviewer.query() \
 
            .filter(PullRequestReviewer.pull_request == pull_request) \
 
            .filter(PullRequestReviewer.user_id == request.authuser.user_id) \
 
        reviewer = db.PullRequestReviewer.query() \
 
            .filter(db.PullRequestReviewer.pull_request == pull_request) \
 
            .filter(db.PullRequestReviewer.user_id == request.authuser.user_id) \
 
            .count() != 0
 

	
 
        return request.authuser.admin or owner or reviewer
 

	
 
    @LoginRequired(allow_default_user=True)
 
    @HasRepoPermissionLevelDecorator('read')
 
@@ -199,13 +198,13 @@ class PullrequestsController(BaseRepoCon
 
        if c.from_:
 
            url_params['from_'] = 1
 
        if c.closed:
 
            url_params['closed'] = 1
 
        p = safe_int(request.GET.get('page'), 1)
 

	
 
        q = PullRequest.query(include_closed=c.closed, sorted=True)
 
        q = db.PullRequest.query(include_closed=c.closed, sorted=True)
 
        if c.from_:
 
            q = q.filter_by(org_repo=c.db_repo)
 
        else:
 
            q = q.filter_by(other_repo=c.db_repo)
 
        c.pull_requests = q.all()
 

	
 
@@ -214,21 +213,21 @@ class PullrequestsController(BaseRepoCon
 
        return render('/pullrequests/pullrequest_show_all.html')
 

	
 
    @LoginRequired()
 
    def show_my(self):
 
        c.closed = request.GET.get('closed') or ''
 

	
 
        c.my_pull_requests = PullRequest.query(
 
        c.my_pull_requests = db.PullRequest.query(
 
            include_closed=c.closed,
 
            sorted=True,
 
        ).filter_by(owner_id=request.authuser.user_id).all()
 

	
 
        c.participate_in_pull_requests = []
 
        c.participate_in_pull_requests_todo = []
 
        done_status = set([ChangesetStatus.STATUS_APPROVED, ChangesetStatus.STATUS_REJECTED])
 
        for pr in PullRequest.query(
 
        done_status = set([db.ChangesetStatus.STATUS_APPROVED, db.ChangesetStatus.STATUS_REJECTED])
 
        for pr in db.PullRequest.query(
 
            include_closed=c.closed,
 
            reviewer_id=request.authuser.user_id,
 
            sorted=True,
 
        ):
 
            status = pr.user_review_status(request.authuser.user_id) # very inefficient!!!
 
            if status in done_status:
 
@@ -317,22 +316,22 @@ class PullrequestsController(BaseRepoCon
 
            msg = _('Error creating pull request: %s') % errors.msg
 
            h.flash(msg, 'error')
 
            raise HTTPBadRequest
 

	
 
        # heads up: org and other might seem backward here ...
 
        org_ref = _form['org_ref'] # will have merge_rev as rev but symbolic name
 
        org_repo = Repository.guess_instance(_form['org_repo'])
 
        org_repo = db.Repository.guess_instance(_form['org_repo'])
 

	
 
        other_ref = _form['other_ref'] # will have symbolic name and head revision
 
        other_repo = Repository.guess_instance(_form['other_repo'])
 
        other_repo = db.Repository.guess_instance(_form['other_repo'])
 

	
 
        reviewers = []
 

	
 
        title = _form['pullrequest_title']
 
        description = _form['pullrequest_desc'].strip()
 
        owner = User.get(request.authuser.user_id)
 
        owner = db.User.get(request.authuser.user_id)
 

	
 
        try:
 
            cmd = CreatePullRequestAction(org_repo, other_repo, org_ref, other_ref, title, description, owner, reviewers)
 
        except CreatePullRequestAction.ValidationError as e:
 
            h.flash(e, category='error', logf=log.error)
 
            raise HTTPNotFound
 
@@ -348,13 +347,13 @@ class PullrequestsController(BaseRepoCon
 

	
 
        h.flash(_('Successfully opened new pull request'),
 
                category='success')
 
        raise HTTPFound(location=pull_request.url())
 

	
 
    def create_new_iteration(self, old_pull_request, new_rev, title, description, reviewers):
 
        owner = User.get(request.authuser.user_id)
 
        owner = db.User.get(request.authuser.user_id)
 
        new_org_rev = self._get_ref_rev(old_pull_request.org_repo, 'rev', new_rev)
 
        new_other_rev = self._get_ref_rev(old_pull_request.other_repo, old_pull_request.other_ref_parts[0], old_pull_request.other_ref_parts[1])
 
        try:
 
            cmd = CreatePullRequestIterationAction(old_pull_request, new_org_rev, new_other_rev, title, description, owner, reviewers)
 
        except CreatePullRequestAction.ValidationError as e:
 
            h.flash(e, category='error', logf=log.error)
 
@@ -374,13 +373,13 @@ class PullrequestsController(BaseRepoCon
 
        raise HTTPFound(location=pull_request.url())
 

	
 
    # pullrequest_post for PR editing
 
    @LoginRequired()
 
    @HasRepoPermissionLevelDecorator('read')
 
    def post(self, repo_name, pull_request_id):
 
        pull_request = PullRequest.get_or_404(pull_request_id)
 
        pull_request = db.PullRequest.get_or_404(pull_request_id)
 
        if pull_request.is_closed():
 
            raise HTTPForbidden()
 
        assert pull_request.other_repo.repo_name == repo_name
 
        # only owner or admin can update it
 
        owner = pull_request.owner_id == request.authuser.user_id
 
        repo_admin = h.HasRepoPermissionLevel('admin')(c.repo_name)
 
@@ -415,14 +414,14 @@ class PullrequestsController(BaseRepoCon
 
        added_reviewers = new_reviewers - old_reviewers - cur_reviewers
 
        removed_reviewers = (old_reviewers - new_reviewers) & cur_reviewers
 

	
 
        old_description = pull_request.description
 
        pull_request.title = _form['pullrequest_title']
 
        pull_request.description = _form['pullrequest_desc'].strip() or _('No description')
 
        pull_request.owner = User.get_by_username(_form['owner'])
 
        user = User.get(request.authuser.user_id)
 
        pull_request.owner = db.User.get_by_username(_form['owner'])
 
        user = db.User.get(request.authuser.user_id)
 

	
 
        PullRequestModel().mention_from_description(user, pull_request, old_description)
 
        PullRequestModel().add_reviewers(user, pull_request, added_reviewers)
 
        PullRequestModel().remove_reviewers(user, pull_request, removed_reviewers)
 

	
 
        meta.Session().commit()
 
@@ -431,26 +430,26 @@ class PullrequestsController(BaseRepoCon
 
        raise HTTPFound(location=pull_request.url())
 

	
 
    @LoginRequired()
 
    @HasRepoPermissionLevelDecorator('read')
 
    @jsonify
 
    def delete(self, repo_name, pull_request_id):
 
        pull_request = PullRequest.get_or_404(pull_request_id)
 
        pull_request = db.PullRequest.get_or_404(pull_request_id)
 
        # only owner can delete it !
 
        if pull_request.owner_id == request.authuser.user_id:
 
            PullRequestModel().delete(pull_request)
 
            meta.Session().commit()
 
            h.flash(_('Successfully deleted pull request'),
 
                    category='success')
 
            raise HTTPFound(location=url('my_pullrequests'))
 
        raise HTTPForbidden()
 

	
 
    @LoginRequired(allow_default_user=True)
 
    @HasRepoPermissionLevelDecorator('read')
 
    def show(self, repo_name, pull_request_id, extra=None):
 
        c.pull_request = PullRequest.get_or_404(pull_request_id)
 
        c.pull_request = db.PullRequest.get_or_404(pull_request_id)
 
        c.allowed_to_change_status = self._is_allowed_to_change_status(c.pull_request)
 
        cc_model = ChangesetCommentsModel()
 
        cs_model = ChangesetStatusModel()
 

	
 
        # pull_requests repo_name we opened it against
 
        # ie. other_repo must match
 
@@ -613,23 +612,23 @@ class PullrequestsController(BaseRepoCon
 

	
 
        # (badly named) pull-request status calculation based on reviewer votes
 
        (c.pull_request_reviewers,
 
         c.pull_request_pending_reviewers,
 
         c.current_voting_result,
 
         ) = cs_model.calculate_pull_request_result(c.pull_request)
 
        c.changeset_statuses = ChangesetStatus.STATUSES
 
        c.changeset_statuses = db.ChangesetStatus.STATUSES
 

	
 
        c.is_ajax_preview = False
 
        c.ancestors = None # [c.a_rev] ... but that is shown in an other way
 
        return render('/pullrequests/pullrequest_show.html')
 

	
 
    @LoginRequired()
 
    @HasRepoPermissionLevelDecorator('read')
 
    @jsonify
 
    def comment(self, repo_name, pull_request_id):
 
        pull_request = PullRequest.get_or_404(pull_request_id)
 
        pull_request = db.PullRequest.get_or_404(pull_request_id)
 
        allowed_to_change_status = self._is_allowed_to_change_status(pull_request)
 
        return create_cs_pr_comment(repo_name, pull_request=pull_request,
 
                allowed_to_change_status=allowed_to_change_status)
 

	
 
    @LoginRequired()
 
    @HasRepoPermissionLevelDecorator('read')
kallithea/controllers/summary.py
Show inline comments
 
@@ -47,13 +47,13 @@ from kallithea.lib.conf import ALL_EXTS,
 
from kallithea.lib.markup_renderer import MarkupRenderer
 
from kallithea.lib.page import Page
 
from kallithea.lib.utils2 import safe_int, safe_str
 
from kallithea.lib.vcs.backends.base import EmptyChangeset
 
from kallithea.lib.vcs.exceptions import ChangesetError, EmptyRepositoryError, NodeDoesNotExistError
 
from kallithea.lib.vcs.nodes import FileNode
 
from kallithea.model.db import Statistics
 
from kallithea.model import db
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 
README_FILES = [''.join([x[0][0], x[1][0]]) for x in
 
                    sorted(list(itertools.product(ALL_READMES, ALL_EXTS)),
 
@@ -128,14 +128,14 @@ class SummaryController(BaseRepoControll
 

	
 
        if c.db_repo.enable_statistics:
 
            c.show_stats = True
 
        else:
 
            c.show_stats = False
 

	
 
        stats = Statistics.query() \
 
            .filter(Statistics.repository == c.db_repo) \
 
        stats = db.Statistics.query() \
 
            .filter(db.Statistics.repository == c.db_repo) \
 
            .scalar()
 

	
 
        c.stats_percentage = 0
 

	
 
        if stats and stats.languages:
 
            lang_stats_d = ext_json.loads(stats.languages)
 
@@ -178,14 +178,14 @@ class SummaryController(BaseRepoControll
 
        ts_min_m = mktime(td_1m.timetuple())
 
        ts_min_y = mktime(td_1y.timetuple())
 
        ts_max_y = mktime(td.timetuple())
 
        c.ts_min = ts_min_m
 
        c.ts_max = ts_max_y
 

	
 
        stats = Statistics.query() \
 
            .filter(Statistics.repository == c.db_repo) \
 
        stats = db.Statistics.query() \
 
            .filter(db.Statistics.repository == c.db_repo) \
 
            .scalar()
 
        c.stats_percentage = 0
 
        if stats and stats.languages:
 
            c.commit_data = ext_json.loads(stats.commit_activity)
 
            c.overview_data = ext_json.loads(stats.commit_activity_combined)
 

	
kallithea/lib/auth.py
Show inline comments
 
@@ -41,15 +41,13 @@ from webob.exc import HTTPForbidden, HTT
 

	
 
import kallithea
 
from kallithea.lib.utils import get_repo_group_slug, get_repo_slug, get_user_group_slug
 
from kallithea.lib.utils2 import ascii_bytes, ascii_str, safe_bytes
 
from kallithea.lib.vcs.utils.lazy import LazyProperty
 
from kallithea.lib.webutils import url
 
from kallithea.model import meta
 
from kallithea.model.db import (Permission, UserApiKeys, UserGroup, UserGroupMember, UserGroupRepoGroupToPerm, UserGroupRepoToPerm, UserGroupToPerm,
 
                                UserGroupUserGroupToPerm, UserIpMap, UserToPerm)
 
from kallithea.model import db, meta
 
from kallithea.model.user import UserModel
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
@@ -114,13 +112,13 @@ def check_password(password, hashed):
 
        log.error('error from bcrypt checking password: %s', e)
 
        return False
 
    log.error('check_password failed - no method found for hash length %s', len(hashed))
 
    return False
 

	
 

	
 
PERM_WEIGHTS = Permission.PERM_WEIGHTS
 
PERM_WEIGHTS = db.Permission.PERM_WEIGHTS
 

	
 
def bump_permission(permissions, key, new_perm):
 
    """Add a new permission for key to permissions.
 
    Assuming the permissions are comparable, set the new permission if it
 
    has higher weight, else drop it and keep the old permission.
 
    """
 
@@ -222,42 +220,42 @@ class AuthUser(object):
 
        if self.is_admin:
 
            return set(['hg.admin'])
 

	
 
        global_permissions = set()
 

	
 
        # default global permissions from the default user
 
        default_global_perms = UserToPerm.query() \
 
            .filter(UserToPerm.user_id == kallithea.DEFAULT_USER_ID) \
 
            .options(joinedload(UserToPerm.permission))
 
        default_global_perms = db.UserToPerm.query() \
 
            .filter(db.UserToPerm.user_id == kallithea.DEFAULT_USER_ID) \
 
            .options(joinedload(db.UserToPerm.permission))
 
        for perm in default_global_perms:
 
            global_permissions.add(perm.permission.permission_name)
 

	
 
        # user group global permissions
 
        user_perms_from_users_groups = meta.Session().query(UserGroupToPerm) \
 
            .options(joinedload(UserGroupToPerm.permission)) \
 
            .join((UserGroupMember, UserGroupToPerm.users_group_id ==
 
                   UserGroupMember.users_group_id)) \
 
            .filter(UserGroupMember.user_id == self.user_id) \
 
            .join((UserGroup, UserGroupMember.users_group_id ==
 
                   UserGroup.users_group_id)) \
 
            .filter(UserGroup.users_group_active == True) \
 
            .order_by(UserGroupToPerm.users_group_id) \
 
        user_perms_from_users_groups = meta.Session().query(db.UserGroupToPerm) \
 
            .options(joinedload(db.UserGroupToPerm.permission)) \
 
            .join((db.UserGroupMember, db.UserGroupToPerm.users_group_id ==
 
                   db.UserGroupMember.users_group_id)) \
 
            .filter(db.UserGroupMember.user_id == self.user_id) \
 
            .join((db.UserGroup, db.UserGroupMember.users_group_id ==
 
                   db.UserGroup.users_group_id)) \
 
            .filter(db.UserGroup.users_group_active == True) \
 
            .order_by(db.UserGroupToPerm.users_group_id) \
 
            .all()
 
        # need to group here by groups since user can be in more than
 
        # one group
 
        _grouped = [[x, list(y)] for x, y in
 
                    itertools.groupby(user_perms_from_users_groups,
 
                                      lambda x:x.users_group)]
 
        for gr, perms in _grouped:
 
            for perm in perms:
 
                global_permissions.add(perm.permission.permission_name)
 

	
 
        # user specific global permissions
 
        user_perms = meta.Session().query(UserToPerm) \
 
                .options(joinedload(UserToPerm.permission)) \
 
                .filter(UserToPerm.user_id == self.user_id).all()
 
        user_perms = meta.Session().query(db.UserToPerm) \
 
                .options(joinedload(db.UserToPerm.permission)) \
 
                .filter(db.UserToPerm.user_id == self.user_id).all()
 
        for perm in user_perms:
 
            global_permissions.add(perm.permission.permission_name)
 

	
 
        # for each kind of global permissions, only keep the one with heighest weight
 
        kind_max_perm = {}
 
        for perm in sorted(global_permissions, key=lambda n: PERM_WEIGHTS.get(n, -1)):
 
@@ -266,13 +264,13 @@ class AuthUser(object):
 
        return set(kind_max_perm.values())
 

	
 
    @LazyProperty
 
    def repository_permissions(self):
 
        log.debug('Getting repository permissions for %s', self)
 
        repository_permissions = {}
 
        default_repo_perms = Permission.get_default_perms(kallithea.DEFAULT_USER_ID)
 
        default_repo_perms = db.Permission.get_default_perms(kallithea.DEFAULT_USER_ID)
 

	
 
        if self.is_admin:
 
            for perm in default_repo_perms:
 
                r_k = perm.repository.repo_name
 
                p = 'repository.admin'
 
                repository_permissions[r_k] = p
 
@@ -288,41 +286,41 @@ class AuthUser(object):
 
                else:
 
                    p = perm.permission.permission_name
 
                repository_permissions[r_k] = p
 

	
 
            # user group repository permissions
 
            user_repo_perms_from_users_groups = \
 
             meta.Session().query(UserGroupRepoToPerm) \
 
                .join((UserGroup, UserGroupRepoToPerm.users_group_id ==
 
                       UserGroup.users_group_id)) \
 
                .filter(UserGroup.users_group_active == True) \
 
                .join((UserGroupMember, UserGroupRepoToPerm.users_group_id ==
 
                       UserGroupMember.users_group_id)) \
 
                .filter(UserGroupMember.user_id == self.user_id) \
 
                .options(joinedload(UserGroupRepoToPerm.repository)) \
 
                .options(joinedload(UserGroupRepoToPerm.permission)) \
 
             meta.Session().query(db.UserGroupRepoToPerm) \
 
                .join((db.UserGroup, db.UserGroupRepoToPerm.users_group_id ==
 
                       db.UserGroup.users_group_id)) \
 
                .filter(db.UserGroup.users_group_active == True) \
 
                .join((db.UserGroupMember, db.UserGroupRepoToPerm.users_group_id ==
 
                       db.UserGroupMember.users_group_id)) \
 
                .filter(db.UserGroupMember.user_id == self.user_id) \
 
                .options(joinedload(db.UserGroupRepoToPerm.repository)) \
 
                .options(joinedload(db.UserGroupRepoToPerm.permission)) \
 
                .all()
 
            for perm in user_repo_perms_from_users_groups:
 
                bump_permission(repository_permissions,
 
                    perm.repository.repo_name,
 
                    perm.permission.permission_name)
 

	
 
            # user permissions for repositories
 
            user_repo_perms = Permission.get_default_perms(self.user_id)
 
            user_repo_perms = db.Permission.get_default_perms(self.user_id)
 
            for perm in user_repo_perms:
 
                bump_permission(repository_permissions,
 
                    perm.repository.repo_name,
 
                    perm.permission.permission_name)
 

	
 
        return repository_permissions
 

	
 
    @LazyProperty
 
    def repository_group_permissions(self):
 
        log.debug('Getting repository group permissions for %s', self)
 
        repository_group_permissions = {}
 
        default_repo_groups_perms = Permission.get_default_group_perms(kallithea.DEFAULT_USER_ID)
 
        default_repo_groups_perms = db.Permission.get_default_group_perms(kallithea.DEFAULT_USER_ID)
 

	
 
        if self.is_admin:
 
            for perm in default_repo_groups_perms:
 
                rg_k = perm.group.group_name
 
                p = 'group.admin'
 
                repository_group_permissions[rg_k] = p
 
@@ -334,40 +332,40 @@ class AuthUser(object):
 
                rg_k = perm.group.group_name
 
                p = perm.permission.permission_name
 
                repository_group_permissions[rg_k] = p
 

	
 
            # user group for repo groups permissions
 
            user_repo_group_perms_from_users_groups = \
 
                meta.Session().query(UserGroupRepoGroupToPerm) \
 
                .join((UserGroup, UserGroupRepoGroupToPerm.users_group_id ==
 
                       UserGroup.users_group_id)) \
 
                .filter(UserGroup.users_group_active == True) \
 
                .join((UserGroupMember, UserGroupRepoGroupToPerm.users_group_id
 
                       == UserGroupMember.users_group_id)) \
 
                .filter(UserGroupMember.user_id == self.user_id) \
 
                .options(joinedload(UserGroupRepoGroupToPerm.permission)) \
 
                meta.Session().query(db.UserGroupRepoGroupToPerm) \
 
                .join((db.UserGroup, db.UserGroupRepoGroupToPerm.users_group_id ==
 
                       db.UserGroup.users_group_id)) \
 
                .filter(db.UserGroup.users_group_active == True) \
 
                .join((db.UserGroupMember, db.UserGroupRepoGroupToPerm.users_group_id
 
                       == db.UserGroupMember.users_group_id)) \
 
                .filter(db.UserGroupMember.user_id == self.user_id) \
 
                .options(joinedload(db.UserGroupRepoGroupToPerm.permission)) \
 
                .all()
 
            for perm in user_repo_group_perms_from_users_groups:
 
                bump_permission(repository_group_permissions,
 
                    perm.group.group_name,
 
                    perm.permission.permission_name)
 

	
 
            # user explicit permissions for repository groups
 
            user_repo_groups_perms = Permission.get_default_group_perms(self.user_id)
 
            user_repo_groups_perms = db.Permission.get_default_group_perms(self.user_id)
 
            for perm in user_repo_groups_perms:
 
                bump_permission(repository_group_permissions,
 
                    perm.group.group_name,
 
                    perm.permission.permission_name)
 

	
 
        return repository_group_permissions
 

	
 
    @LazyProperty
 
    def user_group_permissions(self):
 
        log.debug('Getting user group permissions for %s', self)
 
        user_group_permissions = {}
 
        default_user_group_perms = Permission.get_default_user_group_perms(kallithea.DEFAULT_USER_ID)
 
        default_user_group_perms = db.Permission.get_default_user_group_perms(kallithea.DEFAULT_USER_ID)
 

	
 
        if self.is_admin:
 
            for perm in default_user_group_perms:
 
                u_k = perm.user_group.users_group_name
 
                p = 'usergroup.admin'
 
                user_group_permissions[u_k] = p
 
@@ -379,30 +377,30 @@ class AuthUser(object):
 
                u_k = perm.user_group.users_group_name
 
                p = perm.permission.permission_name
 
                user_group_permissions[u_k] = p
 

	
 
            # user group for user group permissions
 
            user_group_user_groups_perms = \
 
                meta.Session().query(UserGroupUserGroupToPerm) \
 
                .join((UserGroup, UserGroupUserGroupToPerm.target_user_group_id
 
                       == UserGroup.users_group_id)) \
 
                .join((UserGroupMember, UserGroupUserGroupToPerm.user_group_id
 
                       == UserGroupMember.users_group_id)) \
 
                .filter(UserGroupMember.user_id == self.user_id) \
 
                .join((UserGroup, UserGroupMember.users_group_id ==
 
                       UserGroup.users_group_id), aliased=True, from_joinpoint=True) \
 
                .filter(UserGroup.users_group_active == True) \
 
                .options(joinedload(UserGroupUserGroupToPerm.permission)) \
 
                meta.Session().query(db.UserGroupUserGroupToPerm) \
 
                .join((db.UserGroup, db.UserGroupUserGroupToPerm.target_user_group_id
 
                       == db.UserGroup.users_group_id)) \
 
                .join((db.UserGroupMember, db.UserGroupUserGroupToPerm.user_group_id
 
                       == db.UserGroupMember.users_group_id)) \
 
                .filter(db.UserGroupMember.user_id == self.user_id) \
 
                .join((db.UserGroup, db.UserGroupMember.users_group_id ==
 
                       db.UserGroup.users_group_id), aliased=True, from_joinpoint=True) \
 
                .filter(db.UserGroup.users_group_active == True) \
 
                .options(joinedload(db.UserGroupUserGroupToPerm.permission)) \
 
                .all()
 
            for perm in user_group_user_groups_perms:
 
                bump_permission(user_group_permissions,
 
                    perm.target_user_group.users_group_name,
 
                    perm.permission.permission_name)
 

	
 
            # user explicit permission for user groups
 
            user_user_groups_perms = Permission.get_default_user_group_perms(self.user_id)
 
            user_user_groups_perms = db.Permission.get_default_user_group_perms(self.user_id)
 
            for perm in user_user_groups_perms:
 
                bump_permission(user_group_permissions,
 
                    perm.user_group.users_group_name,
 
                    perm.permission.permission_name)
 

	
 
        return user_group_permissions
 
@@ -456,13 +454,13 @@ class AuthUser(object):
 
    @property
 
    def api_keys(self):
 
        return self._get_api_keys()
 

	
 
    def _get_api_keys(self):
 
        api_keys = [self.api_key]
 
        for api_key in UserApiKeys.query() \
 
        for api_key in db.UserApiKeys.query() \
 
                .filter_by(user_id=self.user_id, is_expired=False):
 
            api_keys.append(api_key.api_key)
 

	
 
        return api_keys
 

	
 
    @property
 
@@ -515,22 +513,22 @@ class AuthUser(object):
 
        )
 

	
 
    @classmethod
 
    def get_allowed_ips(cls, user_id):
 
        _set = set()
 

	
 
        default_ips = UserIpMap.query().filter(UserIpMap.user_id == kallithea.DEFAULT_USER_ID)
 
        default_ips = db.UserIpMap.query().filter(db.UserIpMap.user_id == kallithea.DEFAULT_USER_ID)
 
        for ip in default_ips:
 
            try:
 
                _set.add(ip.ip_addr)
 
            except ObjectDeletedError:
 
                # since we use heavy caching sometimes it happens that we get
 
                # deleted objects here, we just skip them
 
                pass
 

	
 
        user_ips = UserIpMap.query().filter(UserIpMap.user_id == user_id)
 
        user_ips = db.UserIpMap.query().filter(db.UserIpMap.user_id == user_id)
 
        for ip in user_ips:
 
            try:
 
                _set.add(ip.ip_addr)
 
            except ObjectDeletedError:
 
                # since we use heavy caching sometimes it happens that we get
 
                # deleted objects here, we just skip them
kallithea/lib/auth_modules/__init__.py
Show inline comments
 
@@ -20,14 +20,13 @@ import logging
 
import traceback
 
from inspect import isfunction
 

	
 
from kallithea.lib.auth import AuthUser, PasswordGenerator
 
from kallithea.lib.compat import hybrid_property
 
from kallithea.lib.utils2 import asbool
 
from kallithea.model import meta, validators
 
from kallithea.model.db import Setting, User
 
from kallithea.model import db, meta, validators
 
from kallithea.model.user import UserModel
 
from kallithea.model.user_group import UserGroupModel
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -131,13 +130,13 @@ class KallitheaAuthPluginBase(object):
 
        :param kwargs: extra arguments needed for user fetching.
 
        """
 
        user = None
 
        log.debug('Trying to fetch user `%s` from Kallithea database',
 
                  username)
 
        if username:
 
            user = User.get_by_username_or_email(username)
 
            user = db.User.get_by_username_or_email(username)
 
        else:
 
            log.debug('provided username:`%s` is empty skipping...', username)
 
        return user
 

	
 
    def settings(self):
 
        """
 
@@ -236,13 +235,13 @@ class KallitheaExternalAuthPlugin(Kallit
 

	
 
    def _authenticate(self, userobj, username, passwd, settings, **kwargs):
 
        user_data = super(KallitheaExternalAuthPlugin, self)._authenticate(
 
            userobj, username, passwd, settings, **kwargs)
 
        if user_data is not None:
 
            if userobj is None: # external authentication of unknown user that will be created soon
 
                def_user_perms = AuthUser(dbuser=User.get_default_user()).global_permissions
 
                def_user_perms = AuthUser(dbuser=db.User.get_default_user()).global_permissions
 
                active = 'hg.extern_activate.auto' in def_user_perms
 
            else:
 
                active = userobj.active
 

	
 
            if self.use_fake_password():
 
                # Randomize the PW because we don't need it, but don't want
 
@@ -312,13 +311,13 @@ def loadplugin(plugin):
 
    return plugin
 

	
 

	
 
def get_auth_plugins():
 
    """Return a list of instances of plugins that are available and enabled"""
 
    auth_plugins = []
 
    for plugin_name in Setting.get_by_name("auth_plugins").app_settings_value:
 
    for plugin_name in db.Setting.get_by_name("auth_plugins").app_settings_value:
 
        try:
 
            plugin = loadplugin(plugin_name)
 
        except Exception:
 
            log.exception('Failed to load authentication module %s' % (plugin_name))
 
        else:
 
            auth_plugins.append(plugin)
 
@@ -342,13 +341,13 @@ def authenticate(username, password, env
 
        log.debug('Trying authentication using %s', module)
 
        # load plugin settings from Kallithea database
 
        plugin_name = plugin.name
 
        plugin_settings = {}
 
        for v in plugin.plugin_settings():
 
            conf_key = "auth_%s_%s" % (plugin_name, v["name"])
 
            setting = Setting.get_by_name(conf_key)
 
            setting = db.Setting.get_by_name(conf_key)
 
            plugin_settings[v["name"]] = setting.app_settings_value if setting else None
 
        log.debug('Settings for auth plugin %s: %s', plugin_name, plugin_settings)
 

	
 
        if not asbool(plugin_settings["enabled"]):
 
            log.info("Authentication plugin %s is disabled, skipping for %s",
 
                     module, username)
kallithea/lib/auth_modules/auth_container.py
Show inline comments
 
@@ -27,13 +27,13 @@ Original author and date, and relevant c
 

	
 
import logging
 

	
 
from kallithea.lib import auth_modules
 
from kallithea.lib.compat import hybrid_property
 
from kallithea.lib.utils2 import asbool
 
from kallithea.model.db import Setting
 
from kallithea.model import db
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class KallitheaAuthPlugin(auth_modules.KallitheaExternalAuthPlugin):
 
@@ -209,13 +209,13 @@ class KallitheaAuthPlugin(auth_modules.K
 

	
 
        log.info('user `%s` authenticated correctly', user_data['username'])
 
        return user_data
 

	
 
    def get_managed_fields(self):
 
        fields = ['username', 'password']
 
        if(Setting.get_by_name('auth_container_email_header').app_settings_value):
 
        if(db.Setting.get_by_name('auth_container_email_header').app_settings_value):
 
            fields.append('email')
 
        if(Setting.get_by_name('auth_container_firstname_header').app_settings_value):
 
        if(db.Setting.get_by_name('auth_container_firstname_header').app_settings_value):
 
            fields.append('firstname')
 
        if(Setting.get_by_name('auth_container_lastname_header').app_settings_value):
 
        if(db.Setting.get_by_name('auth_container_lastname_header').app_settings_value):
 
            fields.append('lastname')
 
        return fields
kallithea/lib/base.py
Show inline comments
 
@@ -48,14 +48,13 @@ from kallithea.lib import auth_modules, 
 
from kallithea.lib.auth import AuthUser, HasPermissionAnyMiddleware
 
from kallithea.lib.exceptions import UserCreationError
 
from kallithea.lib.utils import get_repo_slug, is_valid_repo
 
from kallithea.lib.utils2 import AttributeDict, asbool, ascii_bytes, safe_int, safe_str, set_hook_environment
 
from kallithea.lib.vcs.exceptions import ChangesetDoesNotExistError, EmptyRepositoryError, RepositoryError
 
from kallithea.lib.webutils import url
 
from kallithea.model import meta
 
from kallithea.model.db import PullRequest, Repository, Setting, User
 
from kallithea.model import db, meta
 
from kallithea.model.scm import ScmModel
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
@@ -220,13 +219,13 @@ class BaseVCSController(object):
 
        authentication to the web server.
 

	
 
        Returns (user, None) on successful authentication and authorization.
 
        Returns (None, wsgi_app) to send the wsgi_app response to the client.
 
        """
 
        # Use anonymous access if allowed for action on repo.
 
        default_user = User.get_default_user()
 
        default_user = db.User.get_default_user()
 
        default_authuser = AuthUser.make(dbuser=default_user, ip_addr=ip_addr)
 
        if default_authuser is None:
 
            log.debug('No anonymous access at all') # move on to proper user auth
 
        else:
 
            if self._check_permission(action, default_authuser, repo_name):
 
                return default_authuser, None
 
@@ -257,13 +256,13 @@ class BaseVCSController(object):
 
                return None, result.wsgi_application
 

	
 
        #==============================================================
 
        # CHECK PERMISSIONS FOR THIS REQUEST USING GIVEN USERNAME
 
        #==============================================================
 
        try:
 
            user = User.get_by_username_or_email(username)
 
            user = db.User.get_by_username_or_email(username)
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            return None, webob.exc.HTTPInternalServerError()
 

	
 
        authuser = AuthUser.make(dbuser=user, ip_addr=ip_addr)
 
        if authuser is None:
 
@@ -366,13 +365,13 @@ class BaseController(TGController):
 
            token = request.POST.get(h.session_csrf_secret_name)
 
            if not token or token != h.session_csrf_secret_token():
 
                log.error('CSRF check failed')
 
                raise webob.exc.HTTPForbidden()
 

	
 
        c.kallithea_version = kallithea.__version__
 
        rc_config = Setting.get_app_settings()
 
        rc_config = db.Setting.get_app_settings()
 

	
 
        # Visual options
 
        c.visual = AttributeDict({})
 

	
 
        ## DB stored
 
        c.visual.show_public_icon = asbool(rc_config.get('show_public_icon'))
 
@@ -397,14 +396,14 @@ class BaseController(TGController):
 
                    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
 
                    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
 
                    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
 
                    })();
 
            </script>''' % c.ga_code
 
        c.site_name = rc_config.get('title')
 
        c.clone_uri_tmpl = rc_config.get('clone_uri_tmpl') or Repository.DEFAULT_CLONE_URI
 
        c.clone_ssh_tmpl = rc_config.get('clone_ssh_tmpl') or Repository.DEFAULT_CLONE_SSH
 
        c.clone_uri_tmpl = rc_config.get('clone_uri_tmpl') or db.Repository.DEFAULT_CLONE_URI
 
        c.clone_ssh_tmpl = rc_config.get('clone_ssh_tmpl') or db.Repository.DEFAULT_CLONE_SSH
 

	
 
        ## INI stored
 
        c.visual.allow_repo_location_change = asbool(config.get('allow_repo_location_change', True))
 
        c.visual.allow_custom_hooks_settings = asbool(config.get('allow_custom_hooks_settings', True))
 
        c.ssh_enabled = asbool(config.get('ssh_enabled', False))
 

	
 
@@ -414,13 +413,13 @@ class BaseController(TGController):
 

	
 
        c.repo_name = get_repo_slug(request)  # can be empty
 
        c.backends = list(kallithea.BACKENDS)
 

	
 
        self.cut_off_limit = safe_int(config.get('cut_off_limit'))
 

	
 
        c.my_pr_count = PullRequest.query(reviewer_id=request.authuser.user_id, include_closed=False).count()
 
        c.my_pr_count = db.PullRequest.query(reviewer_id=request.authuser.user_id, include_closed=False).count()
 

	
 
        self.scm_model = ScmModel()
 

	
 
    @staticmethod
 
    def _determine_auth_user(session_authuser, ip_addr):
 
        """
 
@@ -447,17 +446,17 @@ class BaseController(TGController):
 
            except UserCreationError as e:
 
                from kallithea.lib import helpers as h
 
                h.flash(e, 'error', logf=log.error)
 
            else:
 
                if user_info is not None:
 
                    username = user_info['username']
 
                    user = User.get_by_username(username, case_insensitive=True)
 
                    user = db.User.get_by_username(username, case_insensitive=True)
 
                    return log_in_user(user, remember=False, is_external_auth=True, ip_addr=ip_addr)
 

	
 
        # User is default user (if active) or anonymous
 
        default_user = User.get_default_user()
 
        default_user = db.User.get_default_user()
 
        authuser = AuthUser.make(dbuser=default_user, ip_addr=ip_addr)
 
        if authuser is None: # fall back to anonymous
 
            authuser = AuthUser(dbuser=default_user) # TODO: somehow use .make?
 
        return authuser
 

	
 
    @staticmethod
 
@@ -510,13 +509,13 @@ class BaseController(TGController):
 
                    session.get('authuser'),
 
                    ip_addr=ip_addr,
 
                )
 
                needs_csrf_check = request.method not in ['GET', 'HEAD']
 

	
 
            else:
 
                dbuser = User.get_by_api_key(api_key)
 
                dbuser = db.User.get_by_api_key(api_key)
 
                if dbuser is None:
 
                    log.info('No db user found for authentication with API key ****%s from %s',
 
                             api_key[-4:], ip_addr)
 
                authuser = AuthUser.make(dbuser=dbuser, is_external_auth=True, ip_addr=ip_addr)
 
                needs_csrf_check = False # API key provides CSRF protection
 

	
 
@@ -550,25 +549,25 @@ class BaseRepoController(BaseController)
 
    c.repository_following: weather the current user is following the current repo
 
    """
 

	
 
    def _before(self, *args, **kwargs):
 
        super(BaseRepoController, self)._before(*args, **kwargs)
 
        if c.repo_name:  # extracted from request by base-base BaseController._before
 
            _dbr = Repository.get_by_repo_name(c.repo_name)
 
            _dbr = db.Repository.get_by_repo_name(c.repo_name)
 
            if not _dbr:
 
                return
 

	
 
            log.debug('Found repository in database %s with state `%s`',
 
                      _dbr, _dbr.repo_state)
 
            route = getattr(request.environ.get('routes.route'), 'name', '')
 

	
 
            # allow to delete repos that are somehow damages in filesystem
 
            if route in ['delete_repo']:
 
                return
 

	
 
            if _dbr.repo_state in [Repository.STATE_PENDING]:
 
            if _dbr.repo_state in [db.Repository.STATE_PENDING]:
 
                if route in ['repo_creating_home']:
 
                    return
 
                check_url = url('repo_creating_home', repo_name=c.repo_name)
 
                raise webob.exc.HTTPFound(location=check_url)
 

	
 
            dbr = c.db_repo = _dbr
kallithea/lib/celerylib/tasks.py
Show inline comments
 
@@ -42,13 +42,13 @@ from kallithea.lib.helpers import person
 
from kallithea.lib.hooks import log_create_repository
 
from kallithea.lib.indexers.daemon import WhooshIndexingDaemon
 
from kallithea.lib.rcmail.smtp_mailer import SmtpMailer
 
from kallithea.lib.utils import action_logger
 
from kallithea.lib.utils2 import asbool, ascii_bytes
 
from kallithea.lib.vcs.utils import author_email
 
from kallithea.model.db import RepoGroup, Repository, Setting, Statistics, User
 
from kallithea.model import db
 
from kallithea.model.repo import RepoModel
 

	
 

	
 
__all__ = ['whoosh_index', 'get_commits_stats', 'send_email']
 

	
 

	
 
@@ -84,13 +84,13 @@ def get_commits_stats(repo_name, ts_min_
 

	
 
    try:
 
        lock = celerylib.DaemonLock(os.path.join(lockkey_path, lockkey))
 

	
 
        co_day_auth_aggr = {}
 
        commits_by_day_aggregate = {}
 
        repo = Repository.get_by_repo_name(repo_name)
 
        repo = db.Repository.get_by_repo_name(repo_name)
 
        if repo is None:
 
            return True
 

	
 
        repo = repo.scm_instance
 
        repo_size = repo.count()
 
        # return if repo have no revisions
 
@@ -101,16 +101,16 @@ def get_commits_stats(repo_name, ts_min_
 
        skip_date_limit = True
 
        parse_limit = int(config.get('commit_parse_limit'))
 
        last_rev = None
 
        last_cs = None
 
        timegetter = itemgetter('time')
 

	
 
        dbrepo = DBS.query(Repository) \
 
            .filter(Repository.repo_name == repo_name).scalar()
 
        cur_stats = DBS.query(Statistics) \
 
            .filter(Statistics.repository == dbrepo).scalar()
 
        dbrepo = DBS.query(db.Repository) \
 
            .filter(db.Repository.repo_name == repo_name).scalar()
 
        cur_stats = DBS.query(db.Statistics) \
 
            .filter(db.Statistics.repository == dbrepo).scalar()
 

	
 
        if cur_stats is not None:
 
            last_rev = cur_stats.stat_on_revision
 

	
 
        if last_rev == repo.get_changeset().revision and repo_size > 1:
 
            # pass silently without any work if we're not on first revision or
 
@@ -191,13 +191,13 @@ def get_commits_stats(repo_name, ts_min_
 
            co_day_auth_aggr[akc(repo.contact)] = {
 
                "label": akc(repo.contact),
 
                "data": [0, 1],
 
                "schema": ["commits"],
 
            }
 

	
 
        stats = cur_stats if cur_stats else Statistics()
 
        stats = cur_stats if cur_stats else db.Statistics()
 
        stats.commit_activity = ascii_bytes(ext_json.dumps(co_day_auth_aggr))
 
        stats.commit_activity_combined = ascii_bytes(ext_json.dumps(overview_data))
 

	
 
        log.debug('last revision %s', last_rev)
 
        leftovers = len(repo.revisions[last_rev:])
 
        log.debug('revisions to parse %s', leftovers)
 
@@ -258,14 +258,14 @@ def send_email(recipients, subject, body
 
    email_prefix = email_config.get('email_prefix', '')
 
    if email_prefix:
 
        subject = "%s %s" % (email_prefix, subject)
 

	
 
    if not recipients:
 
        # if recipients are not defined we send to email_config + all admins
 
        recipients = [u.email for u in User.query()
 
                      .filter(User.admin == True).all()]
 
        recipients = [u.email for u in db.User.query()
 
                      .filter(db.User.admin == True).all()]
 
        if email_config.get('email_to') is not None:
 
            recipients += email_config.get('email_to').split(',')
 

	
 
        # If there are still no recipients, there are no admins and no address
 
        # configured in email_to, so return.
 
        if not recipients:
 
@@ -323,13 +323,13 @@ def send_email(recipients, subject, body
 

	
 
@celerylib.task
 
@celerylib.dbsession
 
def create_repo(form_data, cur_user):
 
    DBS = celerylib.get_session()
 

	
 
    cur_user = User.guess_instance(cur_user)
 
    cur_user = db.User.guess_instance(cur_user)
 

	
 
    owner = cur_user
 
    repo_name = form_data['repo_name']
 
    repo_name_full = form_data['repo_name_full']
 
    repo_type = form_data['repo_type']
 
    description = form_data['repo_description']
 
@@ -337,16 +337,16 @@ def create_repo(form_data, cur_user):
 
    clone_uri = form_data.get('clone_uri')
 
    repo_group = form_data['repo_group']
 
    landing_rev = form_data['repo_landing_rev']
 
    copy_fork_permissions = form_data.get('copy_permissions')
 
    copy_group_permissions = form_data.get('repo_copy_permissions')
 
    fork_of = form_data.get('fork_parent_id')
 
    state = form_data.get('repo_state', Repository.STATE_PENDING)
 
    state = form_data.get('repo_state', db.Repository.STATE_PENDING)
 

	
 
    # repo creation defaults, private and repo_type are filled in form
 
    defs = Setting.get_default_repo_settings(strip_prefix=True)
 
    defs = db.Setting.get_default_repo_settings(strip_prefix=True)
 
    enable_statistics = defs.get('repo_enable_statistics')
 
    enable_downloads = defs.get('repo_enable_downloads')
 

	
 
    try:
 
        repo = RepoModel()._create_repo(
 
            repo_name=repo_name_full,
 
@@ -370,31 +370,31 @@ def create_repo(form_data, cur_user):
 

	
 
        DBS.commit()
 
        # now create this repo on Filesystem
 
        RepoModel()._create_filesystem_repo(
 
            repo_name=repo_name,
 
            repo_type=repo_type,
 
            repo_group=RepoGroup.guess_instance(repo_group),
 
            repo_group=db.RepoGroup.guess_instance(repo_group),
 
            clone_uri=clone_uri,
 
        )
 
        repo = Repository.get_by_repo_name(repo_name_full)
 
        repo = db.Repository.get_by_repo_name(repo_name_full)
 
        log_create_repository(repo.get_dict(), created_by=owner.username)
 

	
 
        # update repo changeset caches initially
 
        repo.update_changeset_cache()
 

	
 
        # set new created state
 
        repo.set_state(Repository.STATE_CREATED)
 
        repo.set_state(db.Repository.STATE_CREATED)
 
        DBS.commit()
 
    except Exception as e:
 
        log.warning('Exception %s occurred when forking repository, '
 
                    'doing cleanup...' % e)
 
        # rollback things manually !
 
        repo = Repository.get_by_repo_name(repo_name_full)
 
        repo = db.Repository.get_by_repo_name(repo_name_full)
 
        if repo:
 
            Repository.delete(repo.repo_id)
 
            db.Repository.delete(repo.repo_id)
 
            DBS.commit()
 
            RepoModel()._delete_filesystem_repo(repo)
 
        raise
 

	
 
    return True
 

	
 
@@ -408,13 +408,13 @@ def create_repo_fork(form_data, cur_user
 
    :param form_data:
 
    :param cur_user:
 
    """
 
    DBS = celerylib.get_session()
 

	
 
    base_path = kallithea.CONFIG['base_path']
 
    cur_user = User.guess_instance(cur_user)
 
    cur_user = db.User.guess_instance(cur_user)
 

	
 
    repo_name = form_data['repo_name']  # fork in this case
 
    repo_name_full = form_data['repo_name_full']
 

	
 
    repo_type = form_data['repo_type']
 
    owner = cur_user
 
@@ -422,13 +422,13 @@ def create_repo_fork(form_data, cur_user
 
    clone_uri = form_data.get('clone_uri')
 
    repo_group = form_data['repo_group']
 
    landing_rev = form_data['landing_rev']
 
    copy_fork_permissions = form_data.get('copy_permissions')
 

	
 
    try:
 
        fork_of = Repository.guess_instance(form_data.get('fork_parent_id'))
 
        fork_of = db.Repository.guess_instance(form_data.get('fork_parent_id'))
 

	
 
        RepoModel()._create_repo(
 
            repo_name=repo_name_full,
 
            repo_type=repo_type,
 
            description=form_data['description'],
 
            owner=owner,
 
@@ -446,40 +446,40 @@ def create_repo_fork(form_data, cur_user
 
        source_repo_path = os.path.join(base_path, fork_of.repo_name)
 

	
 
        # now create this repo on Filesystem
 
        RepoModel()._create_filesystem_repo(
 
            repo_name=repo_name,
 
            repo_type=repo_type,
 
            repo_group=RepoGroup.guess_instance(repo_group),
 
            repo_group=db.RepoGroup.guess_instance(repo_group),
 
            clone_uri=source_repo_path,
 
        )
 
        repo = Repository.get_by_repo_name(repo_name_full)
 
        repo = db.Repository.get_by_repo_name(repo_name_full)
 
        log_create_repository(repo.get_dict(), created_by=owner.username)
 

	
 
        # update repo changeset caches initially
 
        repo.update_changeset_cache()
 

	
 
        # set new created state
 
        repo.set_state(Repository.STATE_CREATED)
 
        repo.set_state(db.Repository.STATE_CREATED)
 
        DBS.commit()
 
    except Exception as e:
 
        log.warning('Exception %s occurred when forking repository, '
 
                    'doing cleanup...' % e)
 
        # rollback things manually !
 
        repo = Repository.get_by_repo_name(repo_name_full)
 
        repo = db.Repository.get_by_repo_name(repo_name_full)
 
        if repo:
 
            Repository.delete(repo.repo_id)
 
            db.Repository.delete(repo.repo_id)
 
            DBS.commit()
 
            RepoModel()._delete_filesystem_repo(repo)
 
        raise
 

	
 
    return True
 

	
 

	
 
def __get_codes_stats(repo_name):
 
    repo = Repository.get_by_repo_name(repo_name).scm_instance
 
    repo = db.Repository.get_by_repo_name(repo_name).scm_instance
 

	
 
    tip = repo.get_changeset()
 
    code_stats = {}
 

	
 
    for _topnode, _dirnodes, filenodes in tip.walk('/'):
 
        for filenode in filenodes:
kallithea/lib/db_manage.py
Show inline comments
 
@@ -35,15 +35,14 @@ import uuid
 
import alembic.command
 
import alembic.config
 
import sqlalchemy
 
from sqlalchemy.engine import create_engine
 

	
 
from kallithea.lib.utils2 import ask_ok
 
from kallithea.model import meta
 
from kallithea.model import db, meta
 
from kallithea.model.base import init_model
 
from kallithea.model.db import Repository, Setting, Ui, User
 
from kallithea.model.permission import PermissionModel
 
from kallithea.model.user import UserModel
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -164,31 +163,31 @@ class DbManage(object):
 

	
 
        :param skip_existing:
 
        """
 

	
 
        for k, v, t in [('auth_plugins', 'kallithea.lib.auth_modules.auth_internal', 'list'),
 
                        ('auth_internal_enabled', 'True', 'bool')]:
 
            if skip_existing and Setting.get_by_name(k) is not None:
 
            if skip_existing and db.Setting.get_by_name(k) is not None:
 
                log.debug('Skipping option %s', k)
 
                continue
 
            setting = Setting(k, v, t)
 
            setting = db.Setting(k, v, t)
 
            self.sa.add(setting)
 

	
 
    def create_default_options(self, skip_existing=False):
 
        """Creates default settings"""
 

	
 
        for k, v, t in [
 
            ('default_repo_enable_downloads', False, 'bool'),
 
            ('default_repo_enable_statistics', False, 'bool'),
 
            ('default_repo_private', False, 'bool'),
 
            ('default_repo_type', 'hg', 'unicode')
 
        ]:
 
            if skip_existing and Setting.get_by_name(k) is not None:
 
            if skip_existing and db.Setting.get_by_name(k) is not None:
 
                log.debug('Skipping option %s', k)
 
                continue
 
            setting = Setting(k, v, t)
 
            setting = db.Setting(k, v, t)
 
            self.sa.add(setting)
 

	
 
    def prompt_repo_root_path(self, test_repo_path='', retries=3):
 
        _path = self.cli_args.get('repos_location')
 
        if retries == 3:
 
            log.info('Setting up repositories config')
 
@@ -242,20 +241,20 @@ class DbManage(object):
 
        return real_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),
 
            ('hooks', db.Ui.HOOK_UPDATE, 'hg update >&2', False),
 
            ('hooks', db.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', 'hggit', '', False),
 
        ]
 
        for ui_section, ui_key, ui_value, ui_active in ui_config:
 
            ui_conf = Ui(
 
            ui_conf = db.Ui(
 
                ui_section=ui_section,
 
                ui_key=ui_key,
 
                ui_value=ui_value,
 
                ui_active=ui_active)
 
            self.sa.add(ui_conf)
 

	
 
@@ -267,36 +266,36 @@ class DbManage(object):
 
            ('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'),
 
            ('gravatar_url', db.User.DEFAULT_GRAVATAR_URL, 'unicode'),
 
            ('clone_uri_tmpl', db.Repository.DEFAULT_CLONE_URI, 'unicode'),
 
            ('clone_ssh_tmpl', db.Repository.DEFAULT_CLONE_SSH, 'unicode'),
 
        ]
 
        for key, val, type_ in settings:
 
            sett = Setting(key, val, type_)
 
            sett = db.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_user(self, username, password, email='', admin=False):
 
        log.info('creating user %s', username)
 
        UserModel().create_or_update(username, password, email,
 
                                     firstname='Kallithea', lastname='Admin',
 
                                     active=True, admin=admin,
 
                                     extern_type=User.DEFAULT_AUTH_TYPE)
 
                                     extern_type=db.User.DEFAULT_AUTH_TYPE)
 

	
 
    def create_default_user(self):
 
        log.info('creating default user')
 
        # create default user for handling default permissions.
 
        user = UserModel().create_or_update(username=User.DEFAULT_USER_NAME,
 
        user = UserModel().create_or_update(username=db.User.DEFAULT_USER_NAME,
 
                                            password=str(uuid.uuid1())[:20],
 
                                            email='anonymous@kallithea-scm.org',
 
                                            firstname='Anonymous',
 
                                            lastname='User')
 
        # based on configuration options activate/deactivate this user which
 
        # controls anonymous access
 
@@ -317,7 +316,7 @@ class DbManage(object):
 
    def populate_default_permissions(self):
 
        """
 
        Populate default permissions. It will create only the default
 
        permissions that are missing, and not alter already defined ones
 
        """
 
        log.info('creating default user permissions')
 
        PermissionModel().create_default_permissions(user=User.DEFAULT_USER_NAME)
 
        PermissionModel().create_default_permissions(user=db.User.DEFAULT_USER_NAME)
kallithea/lib/helpers.py
Show inline comments
 
@@ -53,14 +53,14 @@ from kallithea.lib.vcs.backends.base imp
 
from kallithea.lib.vcs.exceptions import ChangesetDoesNotExistError
 
#==============================================================================
 
# SCM FILTERS available via h.
 
#==============================================================================
 
from kallithea.lib.vcs.utils import author_email, author_name
 
from kallithea.lib.webutils import url
 
from kallithea.model import db
 
from kallithea.model.changeset_status import ChangesetStatusModel
 
from kallithea.model.db import ChangesetStatus, Permission, PullRequest, User, UserIpMap
 

	
 

	
 
# mute pyflakes "imported but unused"
 
assert Option
 
assert checkbox
 
assert end_form
 
@@ -597,13 +597,13 @@ def is_hg(repository):
 
@cache_region('long_term', 'user_attr_or_none')
 
def user_attr_or_none(author, show_attr):
 
    """Try to match email part of VCS committer string with a local user and return show_attr
 
    - or return None if user not found"""
 
    email = author_email(author)
 
    if email:
 
        user = User.get_by_email(email)
 
        user = db.User.get_by_email(email)
 
        if user is not None:
 
            return getattr(user, show_attr)
 
    return None
 

	
 

	
 
def email_or_none(author):
 
@@ -625,13 +625,13 @@ def email_or_none(author):
 

	
 

	
 
def person(author, show_attr="username"):
 
    """Find the user identified by 'author', return one of the users attributes,
 
    default to the username attribute, None if there is no user"""
 
    # if author is already an instance use it for extraction
 
    if isinstance(author, User):
 
    if isinstance(author, db.User):
 
        return getattr(author, show_attr)
 

	
 
    value = user_attr_or_none(author, show_attr)
 
    if value is not None:
 
        return value
 

	
 
@@ -640,13 +640,13 @@ def person(author, show_attr="username")
 

	
 

	
 
def person_by_id(id_, show_attr="username"):
 
    # maybe it's an ID ?
 
    if str(id_).isdigit() or isinstance(id_, int):
 
        id_ = int(id_)
 
        user = User.get(id_)
 
        user = db.User.get(id_)
 
        if user is not None:
 
            return getattr(user, show_attr)
 
    return id_
 

	
 

	
 
def boolicon(value):
 
@@ -819,13 +819,13 @@ def action_parser(user_log, feed=False, 
 
    def get_users_group():
 
        group_name = action_params
 
        return group_name
 

	
 
    def get_pull_request():
 
        pull_request_id = action_params
 
        nice_id = PullRequest.make_nice_id(pull_request_id)
 
        nice_id = db.PullRequest.make_nice_id(pull_request_id)
 

	
 
        deleted = user_log.repository is None
 
        if deleted:
 
            repo_name = user_log.repository_name
 
        else:
 
            repo_name = user_log.repository.repo_name
 
@@ -976,13 +976,13 @@ def gravatar_url(email_address, size=30,
 
    email_address = email_address or _def
 

	
 
    if email_address == _def:
 
        return default
 

	
 
    parsed_url = urllib.parse.urlparse(url.current(qualified=True))
 
    return (c.visual.gravatar_url or User.DEFAULT_GRAVATAR_URL) \
 
    return (c.visual.gravatar_url or db.User.DEFAULT_GRAVATAR_URL) \
 
               .replace('{email}', email_address) \
 
               .replace('{md5email}', hashlib.md5(safe_bytes(email_address).lower()).hexdigest()) \
 
               .replace('{netloc}', parsed_url.netloc) \
 
               .replace('{scheme}', parsed_url.scheme) \
 
               .replace('{size}', str(size))
 

	
 
@@ -1307,17 +1307,17 @@ def link_to_ref(repo_name, ref_type, ref
 

	
 
def changeset_status(repo, revision):
 
    return ChangesetStatusModel().get_status(repo, revision)
 

	
 

	
 
def changeset_status_lbl(changeset_status):
 
    return ChangesetStatus.get_status_lbl(changeset_status)
 
    return db.ChangesetStatus.get_status_lbl(changeset_status)
 

	
 

	
 
def get_permission_name(key):
 
    return dict(Permission.PERMS).get(key)
 
    return dict(db.Permission.PERMS).get(key)
 

	
 

	
 
def journal_filter_help():
 
    return _(textwrap.dedent('''
 
        Example filter terms:
 
            repository:vcs
 
@@ -1342,13 +1342,13 @@ def not_mapped_error(repo_name):
 
            ' it was created or renamed from the filesystem'
 
            ' please run the application again'
 
            ' in order to rescan repositories') % repo_name, category='error')
 

	
 

	
 
def ip_range(ip_addr):
 
    s, e = UserIpMap._get_ip_range(ip_addr)
 
    s, e = db.UserIpMap._get_ip_range(ip_addr)
 
    return '%s - %s' % (s, e)
 

	
 

	
 
session_csrf_secret_name = "_session_csrf_secret_token"
 

	
 
def session_csrf_secret_token():
kallithea/lib/hooks.py
Show inline comments
 
@@ -34,13 +34,13 @@ import mercurial.scmutil
 
import kallithea
 
from kallithea.lib import helpers as h
 
from kallithea.lib.exceptions import UserCreationError
 
from kallithea.lib.utils import action_logger, make_ui
 
from kallithea.lib.utils2 import HookEnvironmentError, ascii_str, get_hook_environment, safe_bytes, safe_str
 
from kallithea.lib.vcs.backends.base import EmptyChangeset
 
from kallithea.model.db import Repository, User
 
from kallithea.model import db
 

	
 

	
 
def _get_scm_size(alias, root_path):
 
    if not alias.startswith('.'):
 
        alias += '.'
 

	
 
@@ -88,13 +88,13 @@ def log_pull_action(ui, repo, **kwargs):
 
    Called as Mercurial hook outgoing.pull_logger or from Kallithea before invoking Git.
 

	
 
    Does *not* use the action from the hook environment but is always 'pull'.
 
    """
 
    ex = get_hook_environment()
 

	
 
    user = User.get_by_username(ex.username)
 
    user = db.User.get_by_username(ex.username)
 
    action = 'pull'
 
    action_logger(user, action, ex.repository, ex.ip, commit=True)
 
    # extension hook call
 
    callback = getattr(kallithea.EXTENSIONS, 'PULL_HOOK', None)
 
    if callable(callback):
 
        kw = {}
 
@@ -313,13 +313,13 @@ def _hook_environment(repo_path):
 
    kallithea.config.application.make_app(config.global_conf, **config.local_conf)
 

	
 
    # fix if it's not a bare repo
 
    if repo_path.endswith(os.sep + '.git'):
 
        repo_path = repo_path[:-5]
 

	
 
    repo = Repository.get_by_full_path(repo_path)
 
    repo = db.Repository.get_by_full_path(repo_path)
 
    if not repo:
 
        raise OSError('Repository %s not found in database' % repo_path)
 

	
 
    baseui = make_ui()
 
    return baseui, repo
 

	
kallithea/lib/indexers/daemon.py
Show inline comments
 
@@ -38,13 +38,13 @@ from whoosh.index import create_in, exis
 
from whoosh.qparser import QueryParser
 

	
 
from kallithea.lib.conf import INDEX_EXTENSIONS, INDEX_FILENAMES
 
from kallithea.lib.indexers import CHGSET_IDX_NAME, CHGSETS_SCHEMA, IDX_NAME, SCHEMA
 
from kallithea.lib.utils2 import safe_str
 
from kallithea.lib.vcs.exceptions import ChangesetDoesNotExistError, ChangesetError, NodeDoesNotExistError, RepositoryError
 
from kallithea.model.db import Repository
 
from kallithea.model import db
 
from kallithea.model.scm import ScmModel
 

	
 

	
 
# Add location of top level folder to sys.path
 
project_path = dirname(dirname(dirname(dirname(os.path.realpath(__file__)))))
 
sys.path.append(project_path)
 
@@ -106,13 +106,13 @@ class WhooshIndexingDaemon(object):
 
            log.info('Running full index build, as the changeset '
 
                     'index does not exist')
 
        else:
 
            self.initial = False
 

	
 
    def _get_index_revision(self, repo):
 
        db_repo = Repository.get_by_repo_name(repo.name)
 
        db_repo = db.Repository.get_by_repo_name(repo.name)
 
        landing_rev = 'tip'
 
        if db_repo:
 
            _rev_type, _rev = db_repo.landing_rev
 
            landing_rev = _rev
 
        return landing_rev
 

	
kallithea/lib/ssh.py
Show inline comments
 
@@ -153,15 +153,15 @@ def _safe_check(s, rec = re.compile('^[a
 

	
 
def authorized_keys_line(kallithea_cli_path, config_file, key):
 
    r"""
 
    Return a line as it would appear in .authorized_keys
 

	
 
    >>> getfixture('doctest_mock_ugettext')
 
    >>> from kallithea.model.db import UserSshKeys, User
 
    >>> user = User(user_id=7, username='uu')
 
    >>> key = UserSshKeys(user_ssh_key_id=17, user=user, description='test key')
 
    >>> from kallithea.model import db
 
    >>> user = db.User(user_id=7, username='uu')
 
    >>> key = db.UserSshKeys(user_ssh_key_id=17, user=user, description='test key')
 
    >>> key.public_key='''ssh-rsa  AAAAB3NzaC1yc2EAAAANVGhpcyBpcyBmYWtlIQAAAANieWU= and a comment'''
 
    >>> authorized_keys_line('/srv/kallithea/venv/bin/kallithea-cli', '/srv/kallithea/my.ini', key)
 
    'no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,command="/srv/kallithea/venv/bin/kallithea-cli ssh-serve -c /srv/kallithea/my.ini 7 17" ssh-rsa AAAAB3NzaC1yc2EAAAANVGhpcyBpcyBmYWtlIQAAAANieWU=\n'
 
    """
 
    try:
 
        keytype, key_bytes, comment = parse_pub_key(key.public_key)
kallithea/lib/utils.py
Show inline comments
 
@@ -44,14 +44,13 @@ from kallithea.lib.utils2 import ascii_b
 
from kallithea.lib.vcs.backends.git.repository import GitRepository
 
from kallithea.lib.vcs.backends.hg.repository import MercurialRepository
 
from kallithea.lib.vcs.conf import settings
 
from kallithea.lib.vcs.exceptions import RepositoryError, VCSError
 
from kallithea.lib.vcs.utils.fakemod import create_module
 
from kallithea.lib.vcs.utils.helpers import get_scm
 
from kallithea.model import meta
 
from kallithea.model.db import RepoGroup, Repository, Setting, Ui, User, UserGroup, UserLog
 
from kallithea.model import db, meta
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 
REMOVED_REPO_PAT = re.compile(r'rm__\d{8}_\d{6}_\d{6}_.*')
 

	
 
@@ -72,13 +71,13 @@ def get_repo_group_slug(request):
 
        _group = _group.rstrip('/')
 
    return _group
 

	
 

	
 
def get_user_group_slug(request):
 
    _group = request.environ['pylons.routes_dict'].get('id')
 
    _group = UserGroup.get(_group)
 
    _group = db.UserGroup.get(_group)
 
    if _group:
 
        return _group.users_group_name
 
    return None
 

	
 

	
 
def _get_permanent_id(s):
 
@@ -102,13 +101,13 @@ def fix_repo_id_name(path):
 
    first, rest = path, ''
 
    if '/' in path:
 
        first, rest_ = path.split('/', 1)
 
        rest = '/' + rest_
 
    repo_id = _get_permanent_id(first)
 
    if repo_id is not None:
 
        repo = Repository.get(repo_id)
 
        repo = db.Repository.get(repo_id)
 
        if repo is not None:
 
            return repo.repo_name + rest
 
    return path
 

	
 

	
 
def action_logger(user, action, repo, ipaddr='', commit=False):
 
@@ -128,29 +127,29 @@ def action_logger(user, action, repo, ip
 
    # if we don't get explicit IP address try to get one from registered user
 
    # in tmpl context var
 
    if not ipaddr:
 
        ipaddr = getattr(get_current_authuser(), 'ip_addr', '')
 

	
 
    if getattr(user, 'user_id', None):
 
        user_obj = User.get(user.user_id)
 
        user_obj = db.User.get(user.user_id)
 
    elif isinstance(user, str):
 
        user_obj = User.get_by_username(user)
 
        user_obj = db.User.get_by_username(user)
 
    else:
 
        raise Exception('You have to provide a user object or a username')
 

	
 
    if getattr(repo, 'repo_id', None):
 
        repo_obj = Repository.get(repo.repo_id)
 
        repo_obj = db.Repository.get(repo.repo_id)
 
        repo_name = repo_obj.repo_name
 
    elif isinstance(repo, str):
 
        repo_name = repo.lstrip('/')
 
        repo_obj = Repository.get_by_repo_name(repo_name)
 
        repo_obj = db.Repository.get_by_repo_name(repo_name)
 
    else:
 
        repo_obj = None
 
        repo_name = ''
 

	
 
    user_log = UserLog()
 
    user_log = db.UserLog()
 
    user_log.user_id = user_obj.user_id
 
    user_log.username = user_obj.username
 
    user_log.action = action
 

	
 
    user_log.repository = repo_obj
 
    user_log.repository_name = repo_name
 
@@ -319,13 +318,13 @@ def make_ui(repo_path=None):
 
    # clean the baseui object
 
    baseui._ocfg = mercurial.config.config()
 
    baseui._ucfg = mercurial.config.config()
 
    baseui._tcfg = mercurial.config.config()
 

	
 
    sa = meta.Session()
 
    for ui_ in sa.query(Ui).order_by(Ui.ui_section, Ui.ui_key):
 
    for ui_ in sa.query(db.Ui).order_by(db.Ui.ui_section, db.Ui.ui_key):
 
        if ui_.ui_active:
 
            log.debug('config from db: [%s] %s=%r', ui_.ui_section,
 
                      ui_.ui_key, ui_.ui_value)
 
            baseui.setconfig(ascii_bytes(ui_.ui_section), ascii_bytes(ui_.ui_key),
 
                             b'' if ui_.ui_value is None else safe_bytes(ui_.ui_value))
 

	
 
@@ -350,16 +349,16 @@ def make_ui(repo_path=None):
 
def set_app_settings(config):
 
    """
 
    Updates app config with new settings from database
 

	
 
    :param config:
 
    """
 
    hgsettings = Setting.get_app_settings()
 
    hgsettings = db.Setting.get_app_settings()
 
    for k, v in hgsettings.items():
 
        config[k] = v
 
    config['base_path'] = Ui.get_repos_location()
 
    config['base_path'] = db.Ui.get_repos_location()
 

	
 

	
 
def set_vcs_config(config):
 
    """
 
    Patch VCS config with some Kallithea specific stuff
 

	
 
@@ -403,26 +402,26 @@ def map_groups(path):
 
    parent = None
 
    group = None
 

	
 
    # last element is repo in nested groups structure
 
    groups = groups[:-1]
 
    rgm = RepoGroupModel()
 
    owner = User.get_first_admin()
 
    owner = db.User.get_first_admin()
 
    for lvl, group_name in enumerate(groups):
 
        group_name = '/'.join(groups[:lvl] + [group_name])
 
        group = RepoGroup.get_by_group_name(group_name)
 
        group = db.RepoGroup.get_by_group_name(group_name)
 
        desc = '%s group' % group_name
 

	
 
        # skip folders that are now removed repos
 
        if REMOVED_REPO_PAT.match(group_name):
 
            break
 

	
 
        if group is None:
 
            log.debug('creating group level: %s group_name: %s',
 
                      lvl, group_name)
 
            group = RepoGroup(group_name, parent)
 
            group = db.RepoGroup(group_name, parent)
 
            group.group_description = desc
 
            group.owner = owner
 
            sa.add(group)
 
            rgm._create_default_perms(group)
 
            sa.flush()
 

	
 
@@ -446,17 +445,17 @@ def repo2db_mapper(initial_repo_dict, re
 
    """
 
    from kallithea.model.repo import RepoModel
 
    from kallithea.model.scm import ScmModel
 
    sa = meta.Session()
 
    repo_model = RepoModel()
 
    if user is None:
 
        user = User.get_first_admin()
 
        user = db.User.get_first_admin()
 
    added = []
 

	
 
    # creation defaults
 
    defs = Setting.get_default_repo_settings(strip_prefix=True)
 
    defs = db.Setting.get_default_repo_settings(strip_prefix=True)
 
    enable_statistics = defs.get('repo_enable_statistics')
 
    enable_downloads = defs.get('repo_enable_downloads')
 
    private = defs.get('repo_private')
 

	
 
    for name, repo in sorted(initial_repo_dict.items()):
 
        group = map_groups(name)
 
@@ -475,13 +474,13 @@ def repo2db_mapper(initial_repo_dict, re
 
                description=desc,
 
                repo_group=getattr(group, 'group_id', None),
 
                owner=user,
 
                enable_downloads=enable_downloads,
 
                enable_statistics=enable_statistics,
 
                private=private,
 
                state=Repository.STATE_CREATED
 
                state=db.Repository.STATE_CREATED
 
            )
 
            sa.commit()
 
            # we added that repo just now, and make sure it has githook
 
            # installed, and updated server info
 
            if new_repo.repo_type == 'git':
 
                git_repo = new_repo.scm_instance
 
@@ -493,13 +492,13 @@ def repo2db_mapper(initial_repo_dict, re
 
        elif install_git_hooks:
 
            if db_repo.repo_type == 'git':
 
                ScmModel().install_git_hooks(db_repo.scm_instance, force=overwrite_git_hooks)
 

	
 
    removed = []
 
    # remove from database those repositories that are not in the filesystem
 
    for repo in sa.query(Repository).all():
 
    for repo in sa.query(db.Repository).all():
 
        if repo.repo_name not in initial_repo_dict:
 
            if remove_obsolete:
 
                log.debug("Removing non-existing repository found in db `%s`",
 
                          repo.repo_name)
 
                try:
 
                    RepoModel().delete(repo, forks='detach', fs_remove=False)
 
@@ -594,10 +593,10 @@ def check_git_version():
 

	
 

	
 
def extract_mentioned_users(text):
 
    """ Returns set of actual database Users @mentioned in given text. """
 
    result = set()
 
    for name in extract_mentioned_usernames(text):
 
        user = User.get_by_username(name, case_insensitive=True)
 
        user = db.User.get_by_username(name, case_insensitive=True)
 
        if user is not None and not user.is_default_user:
 
            result.add(user)
 
    return result
kallithea/lib/vcs/backends/ssh.py
Show inline comments
 
@@ -22,14 +22,13 @@ SSH backend for all available SCMs
 
import datetime
 
import logging
 
import sys
 

	
 
from kallithea.lib.auth import AuthUser, HasPermissionAnyMiddleware
 
from kallithea.lib.utils2 import set_hook_environment
 
from kallithea.model import meta
 
from kallithea.model.db import Repository, User, UserSshKeys
 
from kallithea.model import db, meta
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class BaseSshHandler(object):
 
@@ -59,21 +58,21 @@ class BaseSshHandler(object):
 
        self.repo_name = repo_name.rstrip('/')
 

	
 
    def serve(self, user_id, key_id, client_ip):
 
        """Verify basic sanity of the repository, and that the user is
 
        valid and has access - then serve the native VCS protocol for
 
        repository access."""
 
        dbuser = User.get(user_id)
 
        dbuser = db.User.get(user_id)
 
        if dbuser is None:
 
            self.exit('User %r not found' % user_id)
 
        self.authuser = AuthUser.make(dbuser=dbuser, ip_addr=client_ip)
 
        log.info('Authorized user %s from SSH %s trusting user id %s and key id %s for %r', dbuser, client_ip, user_id, key_id, self.repo_name)
 
        if self.authuser is None: # not ok ... but already kind of authenticated by SSH ... but not really not authorized ...
 
            self.exit('User %s from %s cannot be authorized' % (dbuser.username, client_ip))
 

	
 
        ssh_key = UserSshKeys.get(key_id)
 
        ssh_key = db.UserSshKeys.get(key_id)
 
        if ssh_key is None:
 
            self.exit('SSH key %r not found' % key_id)
 
        ssh_key.last_seen = datetime.datetime.now()
 
        meta.Session().commit()
 

	
 
        if HasPermissionAnyMiddleware('repository.write',
 
@@ -81,13 +80,13 @@ class BaseSshHandler(object):
 
            self.allow_push = True
 
        elif HasPermissionAnyMiddleware('repository.read')(self.authuser, self.repo_name):
 
            self.allow_push = False
 
        else:
 
            self.exit('Access to %r denied' % self.repo_name)
 

	
 
        self.db_repo = Repository.get_by_repo_name(self.repo_name)
 
        self.db_repo = db.Repository.get_by_repo_name(self.repo_name)
 
        if self.db_repo is None:
 
            self.exit("Repository '%s' not found" % self.repo_name)
 
        assert self.db_repo.repo_name == self.repo_name
 

	
 
        # Set global hook environment up for 'push' actions.
 
        # If pull actions should be served, the actual hook invocation will be
kallithea/model/api_key.py
Show inline comments
 
@@ -26,14 +26,13 @@ Original author and date, and relevant c
 
"""
 

	
 
import logging
 
import time
 

	
 
from kallithea.lib.utils2 import generate_api_key
 
from kallithea.model import meta
 
from kallithea.model.db import User, UserApiKeys
 
from kallithea.model import db, meta
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class ApiKeyModel(object):
 
@@ -41,15 +40,15 @@ class ApiKeyModel(object):
 
    def create(self, user, description, lifetime=-1):
 
        """
 
        :param user: user or user_id
 
        :param description: description of ApiKey
 
        :param lifetime: expiration time in seconds
 
        """
 
        user = User.guess_instance(user)
 
        user = db.User.guess_instance(user)
 

	
 
        new_api_key = UserApiKeys()
 
        new_api_key = db.UserApiKeys()
 
        new_api_key.api_key = generate_api_key()
 
        new_api_key.user_id = user.user_id
 
        new_api_key.description = description
 
        new_api_key.expires = time.time() + (lifetime * 60) if lifetime != -1 else -1
 
        meta.Session().add(new_api_key)
 

	
 
@@ -57,22 +56,22 @@ class ApiKeyModel(object):
 

	
 
    def delete(self, api_key, user=None):
 
        """
 
        Deletes given api_key, if user is set it also filters the object for
 
        deletion by given user.
 
        """
 
        api_key = UserApiKeys.query().filter(UserApiKeys.api_key == api_key)
 
        api_key = db.UserApiKeys.query().filter(db.UserApiKeys.api_key == api_key)
 

	
 
        if user is not None:
 
            user = User.guess_instance(user)
 
            api_key = api_key.filter(UserApiKeys.user_id == user.user_id)
 
            user = db.User.guess_instance(user)
 
            api_key = api_key.filter(db.UserApiKeys.user_id == user.user_id)
 

	
 
        api_key = api_key.scalar()
 
        meta.Session().delete(api_key)
 

	
 
    def get_api_keys(self, user, show_expired=True):
 
        user = User.guess_instance(user)
 
        user_api_keys = UserApiKeys.query() \
 
            .filter(UserApiKeys.user_id == user.user_id)
 
        user = db.User.guess_instance(user)
 
        user_api_keys = db.UserApiKeys.query() \
 
            .filter(db.UserApiKeys.user_id == user.user_id)
 
        if not show_expired:
 
            user_api_keys = user_api_keys.filter_by(is_expired=False)
 
        return user_api_keys
kallithea/model/changeset_status.py
Show inline comments
 
@@ -26,57 +26,56 @@ Original author and date, and relevant c
 
"""
 

	
 
import logging
 

	
 
from sqlalchemy.orm import joinedload
 

	
 
from kallithea.model import meta
 
from kallithea.model.db import ChangesetStatus, PullRequest, Repository, User
 
from kallithea.model import db, meta
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class ChangesetStatusModel(object):
 

	
 
    def _get_status_query(self, repo, revision, pull_request,
 
                          with_revisions=False):
 
        repo = Repository.guess_instance(repo)
 
        repo = db.Repository.guess_instance(repo)
 

	
 
        q = ChangesetStatus.query() \
 
            .filter(ChangesetStatus.repo == repo)
 
        q = db.ChangesetStatus.query() \
 
            .filter(db.ChangesetStatus.repo == repo)
 
        if not with_revisions:
 
            # only report the latest vote across all users! TODO: be smarter!
 
            q = q.filter(ChangesetStatus.version == 0)
 
            q = q.filter(db.ChangesetStatus.version == 0)
 

	
 
        if revision:
 
            q = q.filter(ChangesetStatus.revision == revision)
 
            q = q.filter(db.ChangesetStatus.revision == revision)
 
        elif pull_request:
 
            pull_request = PullRequest.guess_instance(pull_request)
 
            q = q.filter(ChangesetStatus.pull_request == pull_request)
 
            pull_request = db.PullRequest.guess_instance(pull_request)
 
            q = q.filter(db.ChangesetStatus.pull_request == pull_request)
 
        else:
 
            raise Exception('Please specify revision or pull_request')
 
        q = q.order_by(ChangesetStatus.version.asc())
 
        q = q.order_by(db.ChangesetStatus.version.asc())
 
        return q
 

	
 
    def _calculate_status(self, statuses):
 
        """
 
        Given a list of statuses, calculate the resulting status, according to
 
        the policy: approve if consensus, reject when at least one reject.
 
        """
 

	
 
        if not statuses:
 
            return ChangesetStatus.STATUS_UNDER_REVIEW
 
            return db.ChangesetStatus.STATUS_UNDER_REVIEW
 

	
 
        if all(st and st.status == ChangesetStatus.STATUS_APPROVED for st in statuses):
 
            return ChangesetStatus.STATUS_APPROVED
 
        if all(st and st.status == db.ChangesetStatus.STATUS_APPROVED for st in statuses):
 
            return db.ChangesetStatus.STATUS_APPROVED
 

	
 
        if any(st and st.status == ChangesetStatus.STATUS_REJECTED for st in statuses):
 
            return ChangesetStatus.STATUS_REJECTED
 
        if any(st and st.status == db.ChangesetStatus.STATUS_REJECTED for st in statuses):
 
            return db.ChangesetStatus.STATUS_REJECTED
 

	
 
        return ChangesetStatus.STATUS_UNDER_REVIEW
 
        return db.ChangesetStatus.STATUS_UNDER_REVIEW
 

	
 
    def calculate_pull_request_result(self, pull_request):
 
        """
 
        Return a tuple (reviewers, pending reviewers, pull request status)
 
        Only approve and reject counts as valid votes.
 
        """
 
@@ -92,15 +91,15 @@ class ChangesetStatusModel(object):
 
        pull_request_reviewers = []
 
        pull_request_pending_reviewers = []
 
        relevant_statuses = []
 
        for user in pull_request.get_reviewer_users():
 
            st = cs_statuses.get(user.username)
 
            relevant_statuses.append(st)
 
            status = ChangesetStatus.STATUS_NOT_REVIEWED if st is None else st.status
 
            if status in (ChangesetStatus.STATUS_NOT_REVIEWED,
 
                          ChangesetStatus.STATUS_UNDER_REVIEW):
 
            status = db.ChangesetStatus.STATUS_NOT_REVIEWED if st is None else st.status
 
            if status in (db.ChangesetStatus.STATUS_NOT_REVIEWED,
 
                          db.ChangesetStatus.STATUS_UNDER_REVIEW):
 
                pull_request_pending_reviewers.append(user)
 
            pull_request_reviewers.append((user, status))
 

	
 
        result = self._calculate_status(relevant_statuses)
 

	
 
        return (pull_request_reviewers,
 
@@ -128,13 +127,13 @@ class ChangesetStatusModel(object):
 
        q = self._get_status_query(repo, revision, pull_request)
 

	
 
        # need to use first here since there can be multiple statuses
 
        # returned from pull_request
 
        status = q.first()
 
        if as_str:
 
            return str(status.status) if status else ChangesetStatus.DEFAULT
 
            return str(status.status) if status else db.ChangesetStatus.DEFAULT
 
        return status
 

	
 
    def set_status(self, repo, status, user, comment, revision=None,
 
                   pull_request=None):
 
        """
 
        Creates new status for changeset or updates the old ones bumping their
 
@@ -144,39 +143,39 @@ class ChangesetStatusModel(object):
 
        :param status:
 
        :param user:
 
        :param comment:
 
        :param revision:
 
        :param pull_request:
 
        """
 
        repo = Repository.guess_instance(repo)
 
        repo = db.Repository.guess_instance(repo)
 

	
 
        q = ChangesetStatus.query()
 
        q = db.ChangesetStatus.query()
 
        if revision is not None:
 
            assert pull_request is None
 
            q = q.filter(ChangesetStatus.repo == repo)
 
            q = q.filter(ChangesetStatus.revision == revision)
 
            q = q.filter(db.ChangesetStatus.repo == repo)
 
            q = q.filter(db.ChangesetStatus.revision == revision)
 
            revisions = [revision]
 
        else:
 
            assert pull_request is not None
 
            pull_request = PullRequest.guess_instance(pull_request)
 
            pull_request = db.PullRequest.guess_instance(pull_request)
 
            repo = pull_request.org_repo
 
            q = q.filter(ChangesetStatus.repo == repo)
 
            q = q.filter(ChangesetStatus.revision.in_(pull_request.revisions))
 
            q = q.filter(db.ChangesetStatus.repo == repo)
 
            q = q.filter(db.ChangesetStatus.revision.in_(pull_request.revisions))
 
            revisions = pull_request.revisions
 
        cur_statuses = q.all()
 

	
 
        # update all current statuses with older version
 
        for st in cur_statuses:
 
            st.version += 1
 

	
 
        new_statuses = []
 
        for rev in revisions:
 
            new_status = ChangesetStatus()
 
            new_status = db.ChangesetStatus()
 
            new_status.version = 0 # default
 
            new_status.author = User.guess_instance(user)
 
            new_status.repo = Repository.guess_instance(repo)
 
            new_status.author = db.User.guess_instance(user)
 
            new_status.repo = db.Repository.guess_instance(repo)
 
            new_status.status = status
 
            new_status.comment = comment
 
            new_status.revision = rev
 
            new_status.pull_request = pull_request
 
            new_statuses.append(new_status)
 
            meta.Session().add(new_status)
kallithea/model/comment.py
Show inline comments
 
@@ -29,30 +29,29 @@ import logging
 
from collections import defaultdict
 

	
 
from tg.i18n import ugettext as _
 

	
 
from kallithea.lib import helpers as h
 
from kallithea.lib.utils import extract_mentioned_users
 
from kallithea.model import meta
 
from kallithea.model.db import ChangesetComment, PullRequest, Repository, User
 
from kallithea.model import db, meta
 
from kallithea.model.notification import NotificationModel
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
def _list_changeset_commenters(revision):
 
    return (meta.Session().query(User)
 
        .join(ChangesetComment.author)
 
        .filter(ChangesetComment.revision == revision)
 
    return (meta.Session().query(db.User)
 
        .join(db.ChangesetComment.author)
 
        .filter(db.ChangesetComment.revision == revision)
 
        .all())
 

	
 
def _list_pull_request_commenters(pull_request):
 
    return (meta.Session().query(User)
 
        .join(ChangesetComment.author)
 
        .filter(ChangesetComment.pull_request_id == pull_request.pull_request_id)
 
    return (meta.Session().query(db.User)
 
        .join(db.ChangesetComment.author)
 
        .filter(db.ChangesetComment.pull_request_id == pull_request.pull_request_id)
 
        .all())
 

	
 

	
 
class ChangesetCommentsModel(object):
 

	
 
    def _get_notification_data(self, repo, comment, author, comment_text,
 
@@ -85,13 +84,13 @@ class ChangesetCommentsModel(object):
 
                'Re changeset: %(desc)s %(line)s' %
 
                          {'desc': desc, 'line': line},
 
                 comment_url)
 
            # get the current participants of this changeset
 
            recipients = _list_changeset_commenters(revision)
 
            # add changeset author if it's known locally
 
            cs_author = User.get_from_cs_author(cs.author)
 
            cs_author = db.User.get_from_cs_author(cs.author)
 
            if not cs_author:
 
                # use repo owner if we cannot extract the author correctly
 
                # FIXME: just use committer name even if not a user
 
                cs_author = repo.owner
 
            recipients.append(cs_author)
 

	
 
@@ -173,25 +172,25 @@ class ChangesetCommentsModel(object):
 
        Returns the created comment.
 
        """
 
        if not status_change and not text:
 
            log.warning('Missing text for comment, skipping...')
 
            return None
 

	
 
        repo = Repository.guess_instance(repo)
 
        author = User.guess_instance(author)
 
        comment = ChangesetComment()
 
        repo = db.Repository.guess_instance(repo)
 
        author = db.User.guess_instance(author)
 
        comment = db.ChangesetComment()
 
        comment.repo = repo
 
        comment.author = author
 
        comment.text = text
 
        comment.f_path = f_path
 
        comment.line_no = line_no
 

	
 
        if revision is not None:
 
            comment.revision = revision
 
        elif pull_request is not None:
 
            pull_request = PullRequest.guess_instance(pull_request)
 
            pull_request = db.PullRequest.guess_instance(pull_request)
 
            comment.pull_request = pull_request
 
        else:
 
            raise Exception('Please specify revision or pull_request_id')
 

	
 
        meta.Session().add(comment)
 
        meta.Session().flush()
 
@@ -226,13 +225,13 @@ class ChangesetCommentsModel(object):
 
                    email_kwargs=email_kwargs
 
                )
 

	
 
        return comment
 

	
 
    def delete(self, comment):
 
        comment = ChangesetComment.guess_instance(comment)
 
        comment = db.ChangesetComment.guess_instance(comment)
 
        meta.Session().delete(comment)
 

	
 
        return comment
 

	
 
    def get_comments(self, repo_id, revision=None, pull_request=None):
 
        """
 
@@ -267,37 +266,37 @@ class ChangesetCommentsModel(object):
 
        if f_path is None and line_no is not None:
 
            raise Exception("line_no only makes sense if f_path is given.")
 

	
 
        if inline is None and f_path is not None:
 
            raise Exception("f_path only makes sense for inline comments.")
 

	
 
        q = meta.Session().query(ChangesetComment)
 
        q = meta.Session().query(db.ChangesetComment)
 

	
 
        if inline:
 
            if f_path is not None:
 
                # inline comments for a given file...
 
                q = q.filter(ChangesetComment.f_path == f_path)
 
                q = q.filter(db.ChangesetComment.f_path == f_path)
 
                if line_no is None:
 
                    # ... on any line
 
                    q = q.filter(ChangesetComment.line_no != None)
 
                    q = q.filter(db.ChangesetComment.line_no != None)
 
                else:
 
                    # ... on specific line
 
                    q = q.filter(ChangesetComment.line_no == line_no)
 
                    q = q.filter(db.ChangesetComment.line_no == line_no)
 
            else:
 
                # all inline comments
 
                q = q.filter(ChangesetComment.line_no != None) \
 
                    .filter(ChangesetComment.f_path != None)
 
                q = q.filter(db.ChangesetComment.line_no != None) \
 
                    .filter(db.ChangesetComment.f_path != None)
 
        else:
 
            # all general comments
 
            q = q.filter(ChangesetComment.line_no == None) \
 
                .filter(ChangesetComment.f_path == None)
 
            q = q.filter(db.ChangesetComment.line_no == None) \
 
                .filter(db.ChangesetComment.f_path == None)
 

	
 
        if revision is not None:
 
            q = q.filter(ChangesetComment.revision == revision) \
 
                .filter(ChangesetComment.repo_id == repo_id)
 
            q = q.filter(db.ChangesetComment.revision == revision) \
 
                .filter(db.ChangesetComment.repo_id == repo_id)
 
        elif pull_request is not None:
 
            pull_request = PullRequest.guess_instance(pull_request)
 
            q = q.filter(ChangesetComment.pull_request == pull_request)
 
            pull_request = db.PullRequest.guess_instance(pull_request)
 
            q = q.filter(db.ChangesetComment.pull_request == pull_request)
 
        else:
 
            raise Exception('Please specify either revision or pull_request')
 

	
 
        return q.order_by(ChangesetComment.created_on).all()
 
        return q.order_by(db.ChangesetComment.created_on).all()
kallithea/model/gist.py
Show inline comments
 
@@ -31,14 +31,13 @@ import random
 
import shutil
 
import time
 
import traceback
 

	
 
from kallithea.lib import ext_json
 
from kallithea.lib.utils2 import AttributeDict, ascii_bytes, safe_int, time_to_datetime
 
from kallithea.model import meta
 
from kallithea.model.db import Gist, User
 
from kallithea.model import db, meta
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.scm import ScmModel
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -83,51 +82,51 @@ class GistModel(object):
 
            'gist_updated': time.time(),
 
        }
 
        with open(os.path.join(repo.path, '.hg', GIST_METADATA_FILE), 'wb') as f:
 
            f.write(ascii_bytes(ext_json.dumps(metadata)))
 

	
 
    def get_gist(self, gist):
 
        return Gist.guess_instance(gist)
 
        return db.Gist.guess_instance(gist)
 

	
 
    def get_gist_files(self, gist_access_id, revision=None):
 
        """
 
        Get files for given gist
 

	
 
        :param gist_access_id:
 
        """
 
        repo = Gist.get_by_access_id(gist_access_id)
 
        repo = db.Gist.get_by_access_id(gist_access_id)
 
        cs = repo.scm_instance.get_changeset(revision)
 
        return cs, [n for n in cs.get_node('/')]
 

	
 
    def create(self, description, owner, ip_addr, gist_mapping,
 
               gist_type=Gist.GIST_PUBLIC, lifetime=-1):
 
               gist_type=db.Gist.GIST_PUBLIC, lifetime=-1):
 
        """
 

	
 
        :param description: description of the gist
 
        :param owner: user who created this gist
 
        :param gist_mapping: mapping {filename:{'content':content},...}
 
        :param gist_type: type of gist private/public
 
        :param lifetime: in minutes, -1 == forever
 
        """
 
        owner = User.guess_instance(owner)
 
        owner = db.User.guess_instance(owner)
 
        gist_access_id = make_gist_access_id()
 
        lifetime = safe_int(lifetime, -1)
 
        gist_expires = time.time() + (lifetime * 60) if lifetime != -1 else -1
 
        log.debug('set GIST expiration date to: %s',
 
                  time_to_datetime(gist_expires)
 
                   if gist_expires != -1 else 'forever')
 
        # create the Database version
 
        gist = Gist()
 
        gist = db.Gist()
 
        gist.gist_description = description
 
        gist.gist_access_id = gist_access_id
 
        gist.owner_id = owner.user_id
 
        gist.gist_expires = gist_expires
 
        gist.gist_type = gist_type
 
        meta.Session().add(gist)
 
        meta.Session().flush() # make database assign gist.gist_id
 
        if gist_type == Gist.GIST_PUBLIC:
 
        if gist_type == db.Gist.GIST_PUBLIC:
 
            # use DB ID for easy to use GIST ID
 
            gist.gist_access_id = str(gist.gist_id)
 

	
 
        log.debug('Creating new %s GIST repo %s', gist_type, gist.gist_access_id)
 
        repo = RepoModel()._create_filesystem_repo(
 
            repo_name=gist.gist_access_id, repo_type='hg', repo_group=GIST_STORE_LOC)
 
@@ -168,26 +167,26 @@ class GistModel(object):
 

	
 
        self._store_metadata(repo, gist.gist_id, gist.gist_access_id,
 
                             owner.user_id, gist.gist_type, gist.gist_expires)
 
        return gist
 

	
 
    def delete(self, gist, fs_remove=True):
 
        gist = Gist.guess_instance(gist)
 
        gist = db.Gist.guess_instance(gist)
 
        try:
 
            meta.Session().delete(gist)
 
            if fs_remove:
 
                self.__delete_gist(gist)
 
            else:
 
                log.debug('skipping removal from filesystem')
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise
 

	
 
    def update(self, gist, description, owner, ip_addr, gist_mapping, gist_type,
 
               lifetime):
 
        gist = Gist.guess_instance(gist)
 
        gist = db.Gist.guess_instance(gist)
 
        gist_repo = gist.scm_instance
 

	
 
        lifetime = safe_int(lifetime, -1)
 
        if lifetime == 0:  # preserve old value
 
            gist_expires = gist.gist_expires
 
        else:
kallithea/model/notification.py
Show inline comments
 
@@ -31,13 +31,13 @@ import logging
 

	
 
from tg import app_globals
 
from tg import tmpl_context as c
 
from tg.i18n import ugettext as _
 

	
 
from kallithea.lib import helpers as h
 
from kallithea.model.db import User
 
from kallithea.model import db
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class NotificationModel(object):
 
@@ -68,29 +68,29 @@ class NotificationModel(object):
 
        """
 
        from kallithea.lib.celerylib import tasks
 
        email_kwargs = email_kwargs or {}
 
        if recipients and not getattr(recipients, '__iter__', False):
 
            raise Exception('recipients must be a list or iterable')
 

	
 
        created_by_obj = User.guess_instance(created_by)
 
        created_by_obj = db.User.guess_instance(created_by)
 

	
 
        recipients_objs = set()
 
        if recipients:
 
            for u in recipients:
 
                obj = User.guess_instance(u)
 
                obj = db.User.guess_instance(u)
 
                if obj is not None:
 
                    recipients_objs.add(obj)
 
                else:
 
                    # TODO: inform user that requested operation couldn't be completed
 
                    log.error('cannot email unknown user %r', u)
 
            log.debug('sending notifications %s to %s',
 
                type_, recipients_objs
 
            )
 
        elif recipients is None:
 
            # empty recipients means to all admins
 
            recipients_objs = User.query().filter(User.admin == True).all()
 
            recipients_objs = db.User.query().filter(db.User.admin == True).all()
 
            log.debug('sending notifications %s to admins: %s',
 
                type_, recipients_objs
 
            )
 
        #else: silently skip notification mails?
 

	
 
        if not with_email:
kallithea/model/permission.py
Show inline comments
 
@@ -29,14 +29,13 @@ Original author and date, and relevant c
 
import logging
 
import traceback
 

	
 
from sqlalchemy.exc import DatabaseError
 

	
 
from kallithea.lib.utils2 import asbool
 
from kallithea.model import meta
 
from kallithea.model.db import Permission, User, UserRepoGroupToPerm, UserRepoToPerm, UserToPerm, UserUserGroupToPerm
 
from kallithea.model import db, meta
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class PermissionModel(object):
 
@@ -45,76 +44,76 @@ class PermissionModel(object):
 
    """
 

	
 
    def create_permissions(self):
 
        """
 
        Create permissions for whole system
 
        """
 
        for p in Permission.PERMS:
 
            if not Permission.get_by_key(p[0]):
 
                new_perm = Permission()
 
        for p in db.Permission.PERMS:
 
            if not db.Permission.get_by_key(p[0]):
 
                new_perm = db.Permission()
 
                new_perm.permission_name = p[0]
 
                meta.Session().add(new_perm)
 

	
 
    def create_default_permissions(self, user, force=False):
 
        """
 
        Create missing default permissions for user. If force is set, the default
 
        permissions for the user are reset, otherwise only missing permissions are
 
        created.
 

	
 
        :param user:
 
        """
 
        user = User.guess_instance(user)
 
        user = db.User.guess_instance(user)
 

	
 
        def _make_perm(perm):
 
            new_perm = UserToPerm()
 
            new_perm = db.UserToPerm()
 
            new_perm.user = user
 
            new_perm.permission = Permission.get_by_key(perm)
 
            new_perm.permission = db.Permission.get_by_key(perm)
 
            return new_perm
 

	
 
        def _get_group(perm_name):
 
            return '.'.join(perm_name.split('.')[:1])
 

	
 
        perms = UserToPerm.query().filter(UserToPerm.user == user).all()
 
        perms = db.UserToPerm.query().filter(db.UserToPerm.user == user).all()
 
        defined_perms_groups = set(_get_group(x.permission.permission_name) for x in perms)
 
        log.debug('GOT ALREADY DEFINED:%s', perms)
 

	
 
        if force:
 
            for perm in perms:
 
                meta.Session().delete(perm)
 
            meta.Session().commit()
 
            defined_perms_groups = []
 
        # For every default permission that needs to be created, we check if
 
        # its group is already defined. If it's not, we create default permission.
 
        for perm_name in Permission.DEFAULT_USER_PERMISSIONS:
 
        for perm_name in db.Permission.DEFAULT_USER_PERMISSIONS:
 
            gr = _get_group(perm_name)
 
            if gr not in defined_perms_groups:
 
                log.debug('GR:%s not found, creating permission %s',
 
                          gr, perm_name)
 
                new_perm = _make_perm(perm_name)
 
                meta.Session().add(new_perm)
 

	
 
    def update(self, form_result):
 
        perm_user = User.get_by_username(username=form_result['perm_user_name'])
 
        perm_user = db.User.get_by_username(username=form_result['perm_user_name'])
 

	
 
        try:
 
            # stage 1 set anonymous access
 
            if perm_user.is_default_user:
 
                perm_user.active = asbool(form_result['anonymous'])
 

	
 
            # stage 2 reset defaults and set them from form data
 
            def _make_new(usr, perm_name):
 
                log.debug('Creating new permission:%s', perm_name)
 
                new = UserToPerm()
 
                new = db.UserToPerm()
 
                new.user = usr
 
                new.permission = Permission.get_by_key(perm_name)
 
                new.permission = db.Permission.get_by_key(perm_name)
 
                return new
 
            # clear current entries, to make this function idempotent
 
            # it will fix even if we define more permissions or permissions
 
            # are somehow missing
 
            u2p = UserToPerm.query() \
 
                .filter(UserToPerm.user == perm_user) \
 
            u2p = db.UserToPerm.query() \
 
                .filter(db.UserToPerm.user == perm_user) \
 
                .all()
 
            for p in u2p:
 
                meta.Session().delete(p)
 
            # create fresh set of permissions
 
            for def_perm_key in ['default_repo_perm',
 
                                 'default_group_perm',
 
@@ -127,37 +126,37 @@ class PermissionModel(object):
 
                p = _make_new(perm_user, form_result[def_perm_key])
 
                meta.Session().add(p)
 

	
 
            # stage 3 update all default permissions for repos if checked
 
            if form_result['overwrite_default_repo']:
 
                _def_name = form_result['default_repo_perm'].split('repository.')[-1]
 
                _def = Permission.get_by_key('repository.' + _def_name)
 
                _def = db.Permission.get_by_key('repository.' + _def_name)
 
                # repos
 
                for r2p in UserRepoToPerm.query() \
 
                               .filter(UserRepoToPerm.user == perm_user) \
 
                for r2p in db.UserRepoToPerm.query() \
 
                               .filter(db.UserRepoToPerm.user == perm_user) \
 
                               .all():
 

	
 
                    # don't reset PRIVATE repositories
 
                    if not r2p.repository.private:
 
                        r2p.permission = _def
 

	
 
            if form_result['overwrite_default_group']:
 
                _def_name = form_result['default_group_perm'].split('group.')[-1]
 
                # groups
 
                _def = Permission.get_by_key('group.' + _def_name)
 
                for g2p in UserRepoGroupToPerm.query() \
 
                               .filter(UserRepoGroupToPerm.user == perm_user) \
 
                _def = db.Permission.get_by_key('group.' + _def_name)
 
                for g2p in db.UserRepoGroupToPerm.query() \
 
                               .filter(db.UserRepoGroupToPerm.user == perm_user) \
 
                               .all():
 
                    g2p.permission = _def
 

	
 
            if form_result['overwrite_default_user_group']:
 
                _def_name = form_result['default_user_group_perm'].split('usergroup.')[-1]
 
                # groups
 
                _def = Permission.get_by_key('usergroup.' + _def_name)
 
                for g2p in UserUserGroupToPerm.query() \
 
                               .filter(UserUserGroupToPerm.user == perm_user) \
 
                _def = db.Permission.get_by_key('usergroup.' + _def_name)
 
                for g2p in db.UserUserGroupToPerm.query() \
 
                               .filter(db.UserUserGroupToPerm.user == perm_user) \
 
                               .all():
 
                    g2p.permission = _def
 

	
 
            meta.Session().commit()
 
        except (DatabaseError,):
 
            log.error(traceback.format_exc())
kallithea/model/pull_request.py
Show inline comments
 
@@ -33,14 +33,13 @@ from tg import request
 
from tg.i18n import ugettext as _
 

	
 
from kallithea.lib import helpers as h
 
from kallithea.lib.hooks import log_create_pullrequest
 
from kallithea.lib.utils import extract_mentioned_users
 
from kallithea.lib.utils2 import ascii_bytes
 
from kallithea.model import meta
 
from kallithea.model.db import ChangesetStatus, PullRequest, PullRequestReviewer, User
 
from kallithea.model import db, meta
 
from kallithea.model.notification import NotificationModel
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
@@ -57,26 +56,26 @@ class PullRequestModel(object):
 
        reviewers = set(reviewers)
 
        _assert_valid_reviewers(reviewers)
 
        if mention_recipients is not None:
 
            mention_recipients = set(mention_recipients) - reviewers
 
            _assert_valid_reviewers(mention_recipients)
 

	
 
        redundant_reviewers = set(User.query() \
 
            .join(PullRequestReviewer) \
 
            .filter(PullRequestReviewer.pull_request == pr) \
 
            .filter(PullRequestReviewer.user_id.in_(r.user_id for r in reviewers))
 
        redundant_reviewers = set(db.User.query() \
 
            .join(db.PullRequestReviewer) \
 
            .filter(db.PullRequestReviewer.pull_request == pr) \
 
            .filter(db.PullRequestReviewer.user_id.in_(r.user_id for r in reviewers))
 
            .all())
 

	
 
        if redundant_reviewers:
 
            log.debug('Following reviewers were already part of pull request %s: %s', pr.pull_request_id, redundant_reviewers)
 

	
 
            reviewers -= redundant_reviewers
 

	
 
        log.debug('Adding reviewers to pull request %s: %s', pr.pull_request_id, reviewers)
 
        for reviewer in reviewers:
 
            prr = PullRequestReviewer(reviewer, pr)
 
            prr = db.PullRequestReviewer(reviewer, pr)
 
            meta.Session().add(prr)
 

	
 
        # notification to reviewers
 
        pr_url = pr.url(canonical=True)
 
        threading = ['%s-pr-%s@%s' % (pr.other_repo.repo_name,
 
                                      pr.pull_request_id,
 
@@ -140,30 +139,30 @@ class PullRequestModel(object):
 

	
 
    def remove_reviewers(self, user, pull_request, reviewers):
 
        """Remove specified users from being reviewers of the PR."""
 
        if not reviewers:
 
            return # avoid SQLAlchemy warning about empty sequence for IN-predicate
 

	
 
        PullRequestReviewer.query() \
 
        db.PullRequestReviewer.query() \
 
            .filter_by(pull_request=pull_request) \
 
            .filter(PullRequestReviewer.user_id.in_(r.user_id for r in reviewers)) \
 
            .filter(db.PullRequestReviewer.user_id.in_(r.user_id for r in reviewers)) \
 
            .delete(synchronize_session='fetch') # the default of 'evaluate' is not available
 

	
 
    def delete(self, pull_request):
 
        pull_request = PullRequest.guess_instance(pull_request)
 
        pull_request = db.PullRequest.guess_instance(pull_request)
 
        meta.Session().delete(pull_request)
 
        if pull_request.org_repo.scm_instance.alias == 'git':
 
            # remove a ref under refs/pull/ so that commits can be garbage-collected
 
            try:
 
                del pull_request.org_repo.scm_instance._repo[b"refs/pull/%d/head" % pull_request.pull_request_id]
 
            except KeyError:
 
                pass
 

	
 
    def close_pull_request(self, pull_request):
 
        pull_request = PullRequest.guess_instance(pull_request)
 
        pull_request.status = PullRequest.STATUS_CLOSED
 
        pull_request = db.PullRequest.guess_instance(pull_request)
 
        pull_request.status = db.PullRequest.STATUS_CLOSED
 
        pull_request.updated_on = datetime.datetime.now()
 

	
 

	
 
class CreatePullRequestAction(object):
 

	
 
    class ValidationError(Exception):
 
@@ -251,15 +250,15 @@ class CreatePullRequestAction(object):
 
        self.reviewers = reviewers
 

	
 
        if not CreatePullRequestAction.is_user_authorized(self.org_repo, self.other_repo):
 
            raise self.Unauthorized(_('You are not authorized to create the pull request'))
 

	
 
    def execute(self):
 
        created_by = User.get(request.authuser.user_id)
 
        created_by = db.User.get(request.authuser.user_id)
 

	
 
        pr = PullRequest()
 
        pr = db.PullRequest()
 
        pr.org_repo = self.org_repo
 
        pr.org_ref = self.org_ref
 
        pr.other_repo = self.other_repo
 
        pr.other_ref = self.other_ref
 
        pr.revisions = self.revisions
 
        pr.title = self.title
 
@@ -278,17 +277,17 @@ class CreatePullRequestAction(object):
 
        comment = ChangesetCommentsModel().create(
 
            text='',
 
            repo=self.org_repo,
 
            author=created_by,
 
            pull_request=pr,
 
            send_email=False,
 
            status_change=ChangesetStatus.STATUS_UNDER_REVIEW,
 
            status_change=db.ChangesetStatus.STATUS_UNDER_REVIEW,
 
        )
 
        ChangesetStatusModel().set_status(
 
            self.org_repo,
 
            ChangesetStatus.STATUS_UNDER_REVIEW,
 
            db.ChangesetStatus.STATUS_UNDER_REVIEW,
 
            created_by,
 
            comment,
 
            pull_request=pr,
 
        )
 

	
 
        mention_recipients = extract_mentioned_users(self.description)
kallithea/model/repo.py
Show inline comments
 
@@ -37,35 +37,33 @@ from kallithea.lib import helpers as h
 
from kallithea.lib.auth import HasRepoPermissionLevel, HasUserGroupPermissionLevel
 
from kallithea.lib.exceptions import AttachedForksError
 
from kallithea.lib.hooks import log_delete_repository
 
from kallithea.lib.utils import is_valid_repo_uri, make_ui
 
from kallithea.lib.utils2 import LazyProperty, get_current_authuser, obfuscate_url_pw, remove_prefix
 
from kallithea.lib.vcs.backends import get_backend
 
from kallithea.model import meta
 
from kallithea.model.db import (Permission, RepoGroup, Repository, RepositoryField, Statistics, Ui, User, UserGroup, UserGroupRepoGroupToPerm,
 
                                UserGroupRepoToPerm, UserRepoGroupToPerm, UserRepoToPerm)
 
from kallithea.model import db, meta
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class RepoModel(object):
 

	
 
    def _create_default_perms(self, repository, private):
 
        # create default permission
 
        default = 'repository.read'
 
        def_user = User.get_default_user()
 
        def_user = db.User.get_default_user()
 
        for p in def_user.user_perms:
 
            if p.permission.permission_name.startswith('repository.'):
 
                default = p.permission.permission_name
 
                break
 

	
 
        default_perm = 'repository.none' if private else default
 

	
 
        repo_to_perm = UserRepoToPerm()
 
        repo_to_perm.permission = Permission.get_by_key(default_perm)
 
        repo_to_perm = db.UserRepoToPerm()
 
        repo_to_perm.permission = db.Permission.get_by_key(default_perm)
 

	
 
        repo_to_perm.repository = repository
 
        repo_to_perm.user_id = def_user.user_id
 
        meta.Session().add(repo_to_perm)
 

	
 
        return repo_to_perm
 
@@ -73,41 +71,41 @@ class RepoModel(object):
 
    @LazyProperty
 
    def repos_path(self):
 
        """
 
        Gets the repositories root path from database
 
        """
 

	
 
        q = Ui.query().filter(Ui.ui_key == '/').one()
 
        q = db.Ui.query().filter(db.Ui.ui_key == '/').one()
 
        return q.ui_value
 

	
 
    def get(self, repo_id):
 
        repo = Repository.query() \
 
            .filter(Repository.repo_id == repo_id)
 
        repo = db.Repository.query() \
 
            .filter(db.Repository.repo_id == repo_id)
 
        return repo.scalar()
 

	
 
    def get_repo(self, repository):
 
        return Repository.guess_instance(repository)
 
        return db.Repository.guess_instance(repository)
 

	
 
    def get_by_repo_name(self, repo_name):
 
        repo = Repository.query() \
 
            .filter(Repository.repo_name == repo_name)
 
        repo = db.Repository.query() \
 
            .filter(db.Repository.repo_name == repo_name)
 
        return repo.scalar()
 

	
 
    def get_all_user_repos(self, user):
 
        """
 
        Gets all repositories that user have at least read access
 

	
 
        :param user:
 
        """
 
        from kallithea.lib.auth import AuthUser
 
        auth_user = AuthUser(dbuser=User.guess_instance(user))
 
        auth_user = AuthUser(dbuser=db.User.guess_instance(user))
 
        repos = [repo_name
 
            for repo_name, perm in auth_user.repository_permissions.items()
 
            if perm in ['repository.read', 'repository.write', 'repository.admin']
 
            ]
 
        return Repository.query().filter(Repository.repo_name.in_(repos))
 
        return db.Repository.query().filter(db.Repository.repo_name.in_(repos))
 

	
 
    @classmethod
 
    def _render_datatable(cls, tmpl, *args, **kwargs):
 
        from tg import app_globals, request
 
        from tg import tmpl_context as c
 
        from tg.i18n import ugettext as _
 
@@ -217,13 +215,13 @@ class RepoModel(object):
 
        Gets information about repository, and returns a dict for
 
        usage in forms
 

	
 
        :param repo_name:
 
        """
 

	
 
        repo_info = Repository.get_by_repo_name(repo_name)
 
        repo_info = db.Repository.get_by_repo_name(repo_name)
 

	
 
        if repo_info is None:
 
            return None
 

	
 
        defaults = repo_info.get_dict()
 
        defaults['repo_name'] = repo_info.just_name
 
@@ -245,13 +243,13 @@ class RepoModel(object):
 
                defaults['clone_uri_hidden'] = repo_info.clone_uri_hidden
 

	
 
        # fill owner
 
        if repo_info.owner:
 
            defaults.update({'owner': repo_info.owner.username})
 
        else:
 
            replacement_user = User.query().filter(User.admin ==
 
            replacement_user = db.User.query().filter(db.User.admin ==
 
                                                   True).first().username
 
            defaults.update({'owner': replacement_user})
 

	
 
        # fill repository users
 
        for p in repo_info.repo_to_perm:
 
            defaults.update({'u_perm_%s' % p.user.username:
 
@@ -263,20 +261,20 @@ class RepoModel(object):
 
                                 p.permission.permission_name})
 

	
 
        return defaults
 

	
 
    def update(self, repo, **kwargs):
 
        try:
 
            cur_repo = Repository.guess_instance(repo)
 
            cur_repo = db.Repository.guess_instance(repo)
 
            org_repo_name = cur_repo.repo_name
 
            if 'owner' in kwargs:
 
                cur_repo.owner = User.get_by_username(kwargs['owner'])
 
                cur_repo.owner = db.User.get_by_username(kwargs['owner'])
 

	
 
            if 'repo_group' in kwargs:
 
                assert kwargs['repo_group'] != '-1', kwargs # RepoForm should have converted to None
 
                cur_repo.group = RepoGroup.get(kwargs['repo_group'])
 
                cur_repo.group = db.RepoGroup.get(kwargs['repo_group'])
 
                cur_repo.repo_name = cur_repo.get_new_name(cur_repo.just_name)
 
            log.debug('Updating repo %s with params:%s', cur_repo, kwargs)
 
            for k in ['repo_enable_downloads',
 
                      'repo_description',
 
                      'repo_landing_rev',
 
                      'repo_private',
 
@@ -302,15 +300,15 @@ class RepoModel(object):
 
            if kwargs.get('repo_private'):
 
                EMPTY_PERM = 'repository.none'
 
                RepoModel().grant_user_permission(
 
                    repo=cur_repo, user='default', perm=EMPTY_PERM
 
                )
 
                # handle extra fields
 
            for field in [k for k in kwargs if k.startswith(RepositoryField.PREFIX)]:
 
                k = RepositoryField.un_prefix_key(field)
 
                ex_field = RepositoryField.get_by_key_name(key=k, repo=cur_repo)
 
            for field in [k for k in kwargs if k.startswith(db.RepositoryField.PREFIX)]:
 
                k = db.RepositoryField.un_prefix_key(field)
 
                ex_field = db.RepositoryField.get_by_key_name(key=k, repo=cur_repo)
 
                if ex_field:
 
                    ex_field.field_value = kwargs[field]
 

	
 
            if org_repo_name != cur_repo.repo_name:
 
                # rename repository
 
                self._rename_filesystem_repo(old=org_repo_name, new=cur_repo.repo_name)
 
@@ -322,35 +320,35 @@ class RepoModel(object):
 

	
 
    def _create_repo(self, repo_name, repo_type, description, owner,
 
                     private=False, clone_uri=None, repo_group=None,
 
                     landing_rev='rev:tip', fork_of=None,
 
                     copy_fork_permissions=False, enable_statistics=False,
 
                     enable_downloads=False,
 
                     copy_group_permissions=False, state=Repository.STATE_PENDING):
 
                     copy_group_permissions=False, state=db.Repository.STATE_PENDING):
 
        """
 
        Create repository inside database with PENDING state. This should only be
 
        executed by create() repo, with exception of importing existing repos.
 

	
 
        """
 
        from kallithea.model.scm import ScmModel
 

	
 
        owner = User.guess_instance(owner)
 
        fork_of = Repository.guess_instance(fork_of)
 
        repo_group = RepoGroup.guess_instance(repo_group)
 
        owner = db.User.guess_instance(owner)
 
        fork_of = db.Repository.guess_instance(fork_of)
 
        repo_group = db.RepoGroup.guess_instance(repo_group)
 
        try:
 
            repo_name = repo_name
 
            description = description
 
            # repo name is just a name of repository
 
            # while repo_name_full is a full qualified name that is combined
 
            # with name and path of group
 
            repo_name_full = repo_name
 
            repo_name = repo_name.split(kallithea.URL_SEP)[-1]
 
            if kallithea.lib.utils2.repo_name_slug(repo_name) != repo_name:
 
                raise Exception('invalid repo name %s' % repo_name)
 

	
 
            new_repo = Repository()
 
            new_repo = db.Repository()
 
            new_repo.repo_state = state
 
            new_repo.enable_statistics = False
 
            new_repo.repo_name = repo_name_full
 
            new_repo.repo_type = repo_type
 
            new_repo.owner = owner
 
            new_repo.group = repo_group
 
@@ -370,41 +368,41 @@ class RepoModel(object):
 
                new_repo.fork = parent_repo
 

	
 
            meta.Session().add(new_repo)
 

	
 
            if fork_of and copy_fork_permissions:
 
                repo = fork_of
 
                user_perms = UserRepoToPerm.query() \
 
                    .filter(UserRepoToPerm.repository == repo).all()
 
                group_perms = UserGroupRepoToPerm.query() \
 
                    .filter(UserGroupRepoToPerm.repository == repo).all()
 
                user_perms = db.UserRepoToPerm.query() \
 
                    .filter(db.UserRepoToPerm.repository == repo).all()
 
                group_perms = db.UserGroupRepoToPerm.query() \
 
                    .filter(db.UserGroupRepoToPerm.repository == repo).all()
 

	
 
                for perm in user_perms:
 
                    UserRepoToPerm.create(perm.user, new_repo, perm.permission)
 
                    db.UserRepoToPerm.create(perm.user, new_repo, perm.permission)
 

	
 
                for perm in group_perms:
 
                    UserGroupRepoToPerm.create(perm.users_group, new_repo,
 
                    db.UserGroupRepoToPerm.create(perm.users_group, new_repo,
 
                                               perm.permission)
 

	
 
            elif repo_group and copy_group_permissions:
 

	
 
                user_perms = UserRepoGroupToPerm.query() \
 
                    .filter(UserRepoGroupToPerm.group == repo_group).all()
 
                user_perms = db.UserRepoGroupToPerm.query() \
 
                    .filter(db.UserRepoGroupToPerm.group == repo_group).all()
 

	
 
                group_perms = UserGroupRepoGroupToPerm.query() \
 
                    .filter(UserGroupRepoGroupToPerm.group == repo_group).all()
 
                group_perms = db.UserGroupRepoGroupToPerm.query() \
 
                    .filter(db.UserGroupRepoGroupToPerm.group == repo_group).all()
 

	
 
                for perm in user_perms:
 
                    perm_name = perm.permission.permission_name.replace('group.', 'repository.')
 
                    perm_obj = Permission.get_by_key(perm_name)
 
                    UserRepoToPerm.create(perm.user, new_repo, perm_obj)
 
                    perm_obj = db.Permission.get_by_key(perm_name)
 
                    db.UserRepoToPerm.create(perm.user, new_repo, perm_obj)
 

	
 
                for perm in group_perms:
 
                    perm_name = perm.permission.permission_name.replace('group.', 'repository.')
 
                    perm_obj = Permission.get_by_key(perm_name)
 
                    UserGroupRepoToPerm.create(perm.users_group, new_repo, perm_obj)
 
                    perm_obj = db.Permission.get_by_key(perm_name)
 
                    db.UserGroupRepoToPerm.create(perm.users_group, new_repo, perm_obj)
 

	
 
            else:
 
                self._create_default_perms(new_repo, private)
 

	
 
            # now automatically start following this repository as owner
 
            ScmModel().toggle_following_repo(new_repo.repo_id, owner.user_id)
 
@@ -478,13 +476,13 @@ class RepoModel(object):
 
        :param repo:
 
        :param forks: str 'delete' or 'detach'
 
        :param fs_remove: remove(archive) repo from filesystem
 
        """
 
        if not cur_user:
 
            cur_user = getattr(get_current_authuser(), 'username', None)
 
        repo = Repository.guess_instance(repo)
 
        repo = db.Repository.guess_instance(repo)
 
        if repo is not None:
 
            if forks == 'detach':
 
                for r in repo.forks:
 
                    r.fork = None
 
            elif forks == 'delete':
 
                for r in repo.forks:
 
@@ -511,24 +509,24 @@ class RepoModel(object):
 
        if found
 

	
 
        :param repo: Instance of Repository, repository_id, or repository name
 
        :param user: Instance of User, user_id or username
 
        :param perm: Instance of Permission, or permission_name
 
        """
 
        user = User.guess_instance(user)
 
        repo = Repository.guess_instance(repo)
 
        permission = Permission.guess_instance(perm)
 
        user = db.User.guess_instance(user)
 
        repo = db.Repository.guess_instance(repo)
 
        permission = db.Permission.guess_instance(perm)
 

	
 
        # check if we have that permission already
 
        obj = UserRepoToPerm.query() \
 
            .filter(UserRepoToPerm.user == user) \
 
            .filter(UserRepoToPerm.repository == repo) \
 
        obj = db.UserRepoToPerm.query() \
 
            .filter(db.UserRepoToPerm.user == user) \
 
            .filter(db.UserRepoToPerm.repository == repo) \
 
            .scalar()
 
        if obj is None:
 
            # create new !
 
            obj = UserRepoToPerm()
 
            obj = db.UserRepoToPerm()
 
            meta.Session().add(obj)
 
        obj.repository = repo
 
        obj.user = user
 
        obj.permission = permission
 
        log.debug('Granted perm %s to %s on %s', perm, user, repo)
 
        return obj
 
@@ -538,18 +536,18 @@ class RepoModel(object):
 
        Revoke permission for user on given repository
 

	
 
        :param repo: Instance of Repository, repository_id, or repository name
 
        :param user: Instance of User, user_id or username
 
        """
 

	
 
        user = User.guess_instance(user)
 
        repo = Repository.guess_instance(repo)
 
        user = db.User.guess_instance(user)
 
        repo = db.Repository.guess_instance(repo)
 

	
 
        obj = UserRepoToPerm.query() \
 
            .filter(UserRepoToPerm.repository == repo) \
 
            .filter(UserRepoToPerm.user == user) \
 
        obj = db.UserRepoToPerm.query() \
 
            .filter(db.UserRepoToPerm.repository == repo) \
 
            .filter(db.UserRepoToPerm.user == user) \
 
            .scalar()
 
        if obj is not None:
 
            meta.Session().delete(obj)
 
            log.debug('Revoked perm on %s on %s', repo, user)
 

	
 
    def grant_user_group_permission(self, repo, group_name, perm):
 
@@ -559,25 +557,25 @@ class RepoModel(object):
 

	
 
        :param repo: Instance of Repository, repository_id, or repository name
 
        :param group_name: Instance of UserGroup, users_group_id,
 
            or user group name
 
        :param perm: Instance of Permission, or permission_name
 
        """
 
        repo = Repository.guess_instance(repo)
 
        group_name = UserGroup.guess_instance(group_name)
 
        permission = Permission.guess_instance(perm)
 
        repo = db.Repository.guess_instance(repo)
 
        group_name = db.UserGroup.guess_instance(group_name)
 
        permission = db.Permission.guess_instance(perm)
 

	
 
        # check if we have that permission already
 
        obj = UserGroupRepoToPerm.query() \
 
            .filter(UserGroupRepoToPerm.users_group == group_name) \
 
            .filter(UserGroupRepoToPerm.repository == repo) \
 
        obj = db.UserGroupRepoToPerm.query() \
 
            .filter(db.UserGroupRepoToPerm.users_group == group_name) \
 
            .filter(db.UserGroupRepoToPerm.repository == repo) \
 
            .scalar()
 

	
 
        if obj is None:
 
            # create new
 
            obj = UserGroupRepoToPerm()
 
            obj = db.UserGroupRepoToPerm()
 
            meta.Session().add(obj)
 

	
 
        obj.repository = repo
 
        obj.users_group = group_name
 
        obj.permission = permission
 
        log.debug('Granted perm %s to %s on %s', perm, group_name, repo)
 
@@ -588,33 +586,33 @@ class RepoModel(object):
 
        Revoke permission for user group on given repository
 

	
 
        :param repo: Instance of Repository, repository_id, or repository name
 
        :param group_name: Instance of UserGroup, users_group_id,
 
            or user group name
 
        """
 
        repo = Repository.guess_instance(repo)
 
        group_name = UserGroup.guess_instance(group_name)
 
        repo = db.Repository.guess_instance(repo)
 
        group_name = db.UserGroup.guess_instance(group_name)
 

	
 
        obj = UserGroupRepoToPerm.query() \
 
            .filter(UserGroupRepoToPerm.repository == repo) \
 
            .filter(UserGroupRepoToPerm.users_group == group_name) \
 
        obj = db.UserGroupRepoToPerm.query() \
 
            .filter(db.UserGroupRepoToPerm.repository == repo) \
 
            .filter(db.UserGroupRepoToPerm.users_group == group_name) \
 
            .scalar()
 
        if obj is not None:
 
            meta.Session().delete(obj)
 
            log.debug('Revoked perm to %s on %s', repo, group_name)
 

	
 
    def delete_stats(self, repo_name):
 
        """
 
        removes stats for given repo
 

	
 
        :param repo_name:
 
        """
 
        repo = Repository.guess_instance(repo_name)
 
        repo = db.Repository.guess_instance(repo_name)
 
        try:
 
            obj = Statistics.query() \
 
                .filter(Statistics.repository == repo).scalar()
 
            obj = db.Statistics.query() \
 
                .filter(db.Statistics.repository == repo).scalar()
 
            if obj is not None:
 
                meta.Session().delete(obj)
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise
 

	
 
@@ -629,13 +627,13 @@ class RepoModel(object):
 
        from kallithea.lib.utils import is_valid_repo, is_valid_repo_group
 
        from kallithea.model.scm import ScmModel
 

	
 
        if '/' in repo_name:
 
            raise ValueError('repo_name must not contain groups got `%s`' % repo_name)
 

	
 
        if isinstance(repo_group, RepoGroup):
 
        if isinstance(repo_group, db.RepoGroup):
 
            new_parent_path = os.sep.join(repo_group.full_path_splitted)
 
        else:
 
            new_parent_path = repo_group or ''
 

	
 
        if repo_store_location:
 
            _paths = [repo_store_location]
kallithea/model/repo_group.py
Show inline comments
 
@@ -31,14 +31,13 @@ import logging
 
import os
 
import shutil
 
import traceback
 

	
 
import kallithea.lib.utils2
 
from kallithea.lib.utils2 import LazyProperty
 
from kallithea.model import meta
 
from kallithea.model.db import Permission, RepoGroup, Repository, Ui, User, UserGroup, UserGroupRepoGroupToPerm, UserRepoGroupToPerm
 
from kallithea.model import db, meta
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class RepoGroupModel(object):
 
@@ -46,26 +45,26 @@ class RepoGroupModel(object):
 
    @LazyProperty
 
    def repos_path(self):
 
        """
 
        Gets the repositories root path from database
 
        """
 

	
 
        q = Ui.get_by_key('paths', '/')
 
        q = db.Ui.get_by_key('paths', '/')
 
        return q.ui_value
 

	
 
    def _create_default_perms(self, new_group):
 
        # create default permission
 
        default_perm = 'group.read'
 
        def_user = User.get_default_user()
 
        def_user = db.User.get_default_user()
 
        for p in def_user.user_perms:
 
            if p.permission.permission_name.startswith('group.'):
 
                default_perm = p.permission.permission_name
 
                break
 

	
 
        repo_group_to_perm = UserRepoGroupToPerm()
 
        repo_group_to_perm.permission = Permission.get_by_key(default_perm)
 
        repo_group_to_perm = db.UserRepoGroupToPerm()
 
        repo_group_to_perm.permission = db.Permission.get_by_key(default_perm)
 

	
 
        repo_group_to_perm.group = new_group
 
        repo_group_to_perm.user_id = def_user.user_id
 
        meta.Session().add(repo_group_to_perm)
 
        return repo_group_to_perm
 

	
 
@@ -136,15 +135,15 @@ class RepoGroupModel(object):
 
    def create(self, group_name, group_description, owner, parent=None,
 
               just_db=False, copy_permissions=False):
 
        try:
 
            if kallithea.lib.utils2.repo_name_slug(group_name) != group_name:
 
                raise Exception('invalid repo group name %s' % group_name)
 

	
 
            owner = User.guess_instance(owner)
 
            parent_group = RepoGroup.guess_instance(parent)
 
            new_repo_group = RepoGroup()
 
            owner = db.User.guess_instance(owner)
 
            parent_group = db.RepoGroup.guess_instance(parent)
 
            new_repo_group = db.RepoGroup()
 
            new_repo_group.owner = owner
 
            new_repo_group.group_description = group_description or group_name
 
            new_repo_group.parent_group = parent_group
 
            new_repo_group.group_name = new_repo_group.get_new_name(group_name)
 

	
 
            meta.Session().add(new_repo_group)
 
@@ -154,27 +153,27 @@ class RepoGroupModel(object):
 
            if not owner.is_admin:
 
                self.grant_user_permission(repo_group=new_repo_group,
 
                                           user=owner, perm='group.admin')
 

	
 
            if parent_group and copy_permissions:
 
                # copy permissions from parent
 
                user_perms = UserRepoGroupToPerm.query() \
 
                    .filter(UserRepoGroupToPerm.group == parent_group).all()
 
                user_perms = db.UserRepoGroupToPerm.query() \
 
                    .filter(db.UserRepoGroupToPerm.group == parent_group).all()
 

	
 
                group_perms = UserGroupRepoGroupToPerm.query() \
 
                    .filter(UserGroupRepoGroupToPerm.group == parent_group).all()
 
                group_perms = db.UserGroupRepoGroupToPerm.query() \
 
                    .filter(db.UserGroupRepoGroupToPerm.group == parent_group).all()
 

	
 
                for perm in user_perms:
 
                    # don't copy over the permission for user who is creating
 
                    # this group, if he is not super admin he get's admin
 
                    # permission set above
 
                    if perm.user != owner or owner.is_admin:
 
                        UserRepoGroupToPerm.create(perm.user, new_repo_group, perm.permission)
 
                        db.UserRepoGroupToPerm.create(perm.user, new_repo_group, perm.permission)
 

	
 
                for perm in group_perms:
 
                    UserGroupRepoGroupToPerm.create(perm.users_group, new_repo_group, perm.permission)
 
                    db.UserGroupRepoGroupToPerm.create(perm.users_group, new_repo_group, perm.permission)
 
            else:
 
                self._create_default_perms(new_repo_group)
 

	
 
            if not just_db:
 
                # we need to flush here, in order to check if database won't
 
                # throw any exceptions, create filesystem dirs at the very end
 
@@ -195,16 +194,16 @@ class RepoGroupModel(object):
 
        if not perms_new:
 
            perms_new = []
 
        if not perms_updates:
 
            perms_updates = []
 

	
 
        def _set_perm_user(obj, user, perm):
 
            if isinstance(obj, RepoGroup):
 
            if isinstance(obj, db.RepoGroup):
 
                self.grant_user_permission(repo_group=obj, user=user, perm=perm)
 
            elif isinstance(obj, Repository):
 
                user = User.guess_instance(user)
 
            elif isinstance(obj, db.Repository):
 
                user = db.User.guess_instance(user)
 

	
 
                # private repos will not allow to change the default permissions
 
                # using recursive mode
 
                if obj.private and user.is_default_user:
 
                    return
 

	
 
@@ -213,17 +212,17 @@ class RepoGroupModel(object):
 
                perm = perm.replace('group.', 'repository.')
 
                RepoModel().grant_user_permission(
 
                    repo=obj, user=user, perm=perm
 
                )
 

	
 
        def _set_perm_group(obj, users_group, perm):
 
            if isinstance(obj, RepoGroup):
 
            if isinstance(obj, db.RepoGroup):
 
                self.grant_user_group_permission(repo_group=obj,
 
                                                  group_name=users_group,
 
                                                  perm=perm)
 
            elif isinstance(obj, Repository):
 
            elif isinstance(obj, db.Repository):
 
                # we set group permission but we have to switch to repo
 
                # permission
 
                perm = perm.replace('group.', 'repository.')
 
                RepoModel().grant_user_group_permission(
 
                    repo=obj, group_name=users_group, perm=perm
 
                )
 
@@ -237,17 +236,17 @@ class RepoGroupModel(object):
 
            # iterated obj is an instance of a repos group or repository in
 
            # that group, recursive option can be: none, repos, groups, all
 
            if recursive == 'all':
 
                pass
 
            elif recursive == 'repos':
 
                # skip groups, other than this one
 
                if isinstance(obj, RepoGroup) and not obj == repo_group:
 
                if isinstance(obj, db.RepoGroup) and not obj == repo_group:
 
                    continue
 
            elif recursive == 'groups':
 
                # skip repos
 
                if isinstance(obj, Repository):
 
                if isinstance(obj, db.Repository):
 
                    continue
 
            else:  # recursive == 'none': # DEFAULT don't apply to iterated objects
 
                obj = repo_group
 
                # also we do a break at the end of this loop.
 

	
 
            # update permissions
 
@@ -276,24 +275,24 @@ class RepoGroupModel(object):
 
                break
 

	
 
        return updates
 

	
 
    def update(self, repo_group, repo_group_args):
 
        try:
 
            repo_group = RepoGroup.guess_instance(repo_group)
 
            repo_group = db.RepoGroup.guess_instance(repo_group)
 
            old_path = repo_group.full_path
 

	
 
            # change properties
 
            if 'group_description' in repo_group_args:
 
                repo_group.group_description = repo_group_args['group_description']
 
            if 'parent_group_id' in repo_group_args:
 
                repo_group.parent_group_id = repo_group_args['parent_group_id']
 

	
 
            if 'parent_group_id' in repo_group_args:
 
                assert repo_group_args['parent_group_id'] != '-1', repo_group_args  # RepoGroupForm should have converted to None
 
                repo_group.parent_group = RepoGroup.get(repo_group_args['parent_group_id'])
 
                repo_group.parent_group = db.RepoGroup.get(repo_group_args['parent_group_id'])
 
            if 'group_name' in repo_group_args:
 
                group_name = repo_group_args['group_name']
 
                if kallithea.lib.utils2.repo_name_slug(group_name) != group_name:
 
                    raise Exception('invalid repo group name %s' % group_name)
 
                repo_group.group_name = repo_group.get_new_name(group_name)
 
            new_path = repo_group.full_path
 
@@ -303,18 +302,18 @@ class RepoGroupModel(object):
 
            # if obj is a repoGroup also fix the name of the group according
 
            # to the parent
 
            # if obj is a Repo fix it's name
 
            # this can be potentially heavy operation
 
            for obj in repo_group.recursive_groups_and_repos():
 
                # set the value from it's parent
 
                if isinstance(obj, RepoGroup):
 
                if isinstance(obj, db.RepoGroup):
 
                    new_name = obj.get_new_name(obj.name)
 
                    log.debug('Fixing group %s to new name %s'
 
                                % (obj.group_name, new_name))
 
                    obj.group_name = new_name
 
                elif isinstance(obj, Repository):
 
                elif isinstance(obj, db.Repository):
 
                    # we need to get all repositories from this new group and
 
                    # rename them accordingly to new group path
 
                    new_name = obj.get_new_name(obj.just_name)
 
                    log.debug('Fixing repo %s to new name %s'
 
                                % (obj.repo_name, new_name))
 
                    obj.repo_name = new_name
 
@@ -324,50 +323,50 @@ class RepoGroupModel(object):
 
            return repo_group
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise
 

	
 
    def delete(self, repo_group, force_delete=False):
 
        repo_group = RepoGroup.guess_instance(repo_group)
 
        repo_group = db.RepoGroup.guess_instance(repo_group)
 
        try:
 
            meta.Session().delete(repo_group)
 
            self._delete_group(repo_group, force_delete)
 
        except Exception:
 
            log.error('Error removing repo_group %s', repo_group)
 
            raise
 

	
 
    def add_permission(self, repo_group, obj, obj_type, perm, recursive):
 
        from kallithea.model.repo import RepoModel
 
        repo_group = RepoGroup.guess_instance(repo_group)
 
        perm = Permission.guess_instance(perm)
 
        repo_group = db.RepoGroup.guess_instance(repo_group)
 
        perm = db.Permission.guess_instance(perm)
 

	
 
        for el in repo_group.recursive_groups_and_repos():
 
            # iterated obj is an instance of a repos group or repository in
 
            # that group, recursive option can be: none, repos, groups, all
 
            if recursive == 'all':
 
                pass
 
            elif recursive == 'repos':
 
                # skip groups, other than this one
 
                if isinstance(el, RepoGroup) and not el == repo_group:
 
                if isinstance(el, db.RepoGroup) and not el == repo_group:
 
                    continue
 
            elif recursive == 'groups':
 
                # skip repos
 
                if isinstance(el, Repository):
 
                if isinstance(el, db.Repository):
 
                    continue
 
            else:  # recursive == 'none': # DEFAULT don't apply to iterated objects
 
                el = repo_group
 
                # also we do a break at the end of this loop.
 

	
 
            if isinstance(el, RepoGroup):
 
            if isinstance(el, db.RepoGroup):
 
                if obj_type == 'user':
 
                    RepoGroupModel().grant_user_permission(el, user=obj, perm=perm)
 
                elif obj_type == 'user_group':
 
                    RepoGroupModel().grant_user_group_permission(el, group_name=obj, perm=perm)
 
                else:
 
                    raise Exception('undefined object type %s' % obj_type)
 
            elif isinstance(el, Repository):
 
            elif isinstance(el, db.Repository):
 
                # for repos we need to hotfix the name of permission
 
                _perm = perm.permission_name.replace('group.', 'repository.')
 
                if obj_type == 'user':
 
                    RepoModel().grant_user_permission(el, user=obj, perm=_perm)
 
                elif obj_type == 'user_group':
 
                    RepoModel().grant_user_group_permission(el, group_name=obj, perm=_perm)
 
@@ -390,39 +389,39 @@ class RepoGroupModel(object):
 
        :param repo_group:
 
        :param obj: user or user group id
 
        :param obj_type: user or user group type
 
        :param recursive: recurse to all children of group
 
        """
 
        from kallithea.model.repo import RepoModel
 
        repo_group = RepoGroup.guess_instance(repo_group)
 
        repo_group = db.RepoGroup.guess_instance(repo_group)
 

	
 
        for el in repo_group.recursive_groups_and_repos():
 
            # iterated obj is an instance of a repos group or repository in
 
            # that group, recursive option can be: none, repos, groups, all
 
            if recursive == 'all':
 
                pass
 
            elif recursive == 'repos':
 
                # skip groups, other than this one
 
                if isinstance(el, RepoGroup) and not el == repo_group:
 
                if isinstance(el, db.RepoGroup) and not el == repo_group:
 
                    continue
 
            elif recursive == 'groups':
 
                # skip repos
 
                if isinstance(el, Repository):
 
                if isinstance(el, db.Repository):
 
                    continue
 
            else:  # recursive == 'none': # DEFAULT don't apply to iterated objects
 
                el = repo_group
 
                # also we do a break at the end of this loop.
 

	
 
            if isinstance(el, RepoGroup):
 
            if isinstance(el, db.RepoGroup):
 
                if obj_type == 'user':
 
                    RepoGroupModel().revoke_user_permission(el, user=obj)
 
                elif obj_type == 'user_group':
 
                    RepoGroupModel().revoke_user_group_permission(el, group_name=obj)
 
                else:
 
                    raise Exception('undefined object type %s' % obj_type)
 
            elif isinstance(el, Repository):
 
            elif isinstance(el, db.Repository):
 
                if obj_type == 'user':
 
                    RepoModel().revoke_user_permission(el, user=obj)
 
                elif obj_type == 'user_group':
 
                    RepoModel().revoke_user_group_permission(el, group_name=obj)
 
                else:
 
                    raise Exception('undefined object type %s' % obj_type)
 
@@ -443,24 +442,24 @@ class RepoGroupModel(object):
 
        :param repo_group: Instance of RepoGroup, repositories_group_id,
 
            or repositories_group name
 
        :param user: Instance of User, user_id or username
 
        :param perm: Instance of Permission, or permission_name
 
        """
 

	
 
        repo_group = RepoGroup.guess_instance(repo_group)
 
        user = User.guess_instance(user)
 
        permission = Permission.guess_instance(perm)
 
        repo_group = db.RepoGroup.guess_instance(repo_group)
 
        user = db.User.guess_instance(user)
 
        permission = db.Permission.guess_instance(perm)
 

	
 
        # check if we have that permission already
 
        obj = UserRepoGroupToPerm.query() \
 
            .filter(UserRepoGroupToPerm.user == user) \
 
            .filter(UserRepoGroupToPerm.group == repo_group) \
 
        obj = db.UserRepoGroupToPerm.query() \
 
            .filter(db.UserRepoGroupToPerm.user == user) \
 
            .filter(db.UserRepoGroupToPerm.group == repo_group) \
 
            .scalar()
 
        if obj is None:
 
            # create new !
 
            obj = UserRepoGroupToPerm()
 
            obj = db.UserRepoGroupToPerm()
 
            meta.Session().add(obj)
 
        obj.group = repo_group
 
        obj.user = user
 
        obj.permission = permission
 
        log.debug('Granted perm %s to %s on %s', perm, user, repo_group)
 
        return obj
 
@@ -471,18 +470,18 @@ class RepoGroupModel(object):
 

	
 
        :param repo_group: Instance of RepoGroup, repositories_group_id,
 
            or repositories_group name
 
        :param user: Instance of User, user_id or username
 
        """
 

	
 
        repo_group = RepoGroup.guess_instance(repo_group)
 
        user = User.guess_instance(user)
 
        repo_group = db.RepoGroup.guess_instance(repo_group)
 
        user = db.User.guess_instance(user)
 

	
 
        obj = UserRepoGroupToPerm.query() \
 
            .filter(UserRepoGroupToPerm.user == user) \
 
            .filter(UserRepoGroupToPerm.group == repo_group) \
 
        obj = db.UserRepoGroupToPerm.query() \
 
            .filter(db.UserRepoGroupToPerm.user == user) \
 
            .filter(db.UserRepoGroupToPerm.group == repo_group) \
 
            .scalar()
 
        if obj is not None:
 
            meta.Session().delete(obj)
 
            log.debug('Revoked perm on %s on %s', repo_group, user)
 

	
 
    def grant_user_group_permission(self, repo_group, group_name, perm):
 
@@ -493,25 +492,25 @@ class RepoGroupModel(object):
 
        :param repo_group: Instance of RepoGroup, repositories_group_id,
 
            or repositories_group name
 
        :param group_name: Instance of UserGroup, users_group_id,
 
            or user group name
 
        :param perm: Instance of Permission, or permission_name
 
        """
 
        repo_group = RepoGroup.guess_instance(repo_group)
 
        group_name = UserGroup.guess_instance(group_name)
 
        permission = Permission.guess_instance(perm)
 
        repo_group = db.RepoGroup.guess_instance(repo_group)
 
        group_name = db.UserGroup.guess_instance(group_name)
 
        permission = db.Permission.guess_instance(perm)
 

	
 
        # check if we have that permission already
 
        obj = UserGroupRepoGroupToPerm.query() \
 
            .filter(UserGroupRepoGroupToPerm.group == repo_group) \
 
            .filter(UserGroupRepoGroupToPerm.users_group == group_name) \
 
        obj = db.UserGroupRepoGroupToPerm.query() \
 
            .filter(db.UserGroupRepoGroupToPerm.group == repo_group) \
 
            .filter(db.UserGroupRepoGroupToPerm.users_group == group_name) \
 
            .scalar()
 

	
 
        if obj is None:
 
            # create new
 
            obj = UserGroupRepoGroupToPerm()
 
            obj = db.UserGroupRepoGroupToPerm()
 
            meta.Session().add(obj)
 

	
 
        obj.group = repo_group
 
        obj.users_group = group_name
 
        obj.permission = permission
 
        log.debug('Granted perm %s to %s on %s', perm, group_name, repo_group)
 
@@ -523,16 +522,16 @@ class RepoGroupModel(object):
 

	
 
        :param repo_group: Instance of RepoGroup, repositories_group_id,
 
            or repositories_group name
 
        :param group_name: Instance of UserGroup, users_group_id,
 
            or user group name
 
        """
 
        repo_group = RepoGroup.guess_instance(repo_group)
 
        group_name = UserGroup.guess_instance(group_name)
 
        repo_group = db.RepoGroup.guess_instance(repo_group)
 
        group_name = db.UserGroup.guess_instance(group_name)
 

	
 
        obj = UserGroupRepoGroupToPerm.query() \
 
            .filter(UserGroupRepoGroupToPerm.group == repo_group) \
 
            .filter(UserGroupRepoGroupToPerm.users_group == group_name) \
 
        obj = db.UserGroupRepoGroupToPerm.query() \
 
            .filter(db.UserGroupRepoGroupToPerm.group == repo_group) \
 
            .filter(db.UserGroupRepoGroupToPerm.users_group == group_name) \
 
            .scalar()
 
        if obj is not None:
 
            meta.Session().delete(obj)
 
            log.debug('Revoked perm to %s on %s', repo_group, group_name)
kallithea/model/scm.py
Show inline comments
 
@@ -43,14 +43,13 @@ from kallithea.lib.utils import action_l
 
from kallithea.lib.utils2 import safe_bytes, set_hook_environment
 
from kallithea.lib.vcs import get_backend
 
from kallithea.lib.vcs.backends.base import EmptyChangeset
 
from kallithea.lib.vcs.exceptions import RepositoryError
 
from kallithea.lib.vcs.nodes import FileNode
 
from kallithea.lib.vcs.utils.lazy import LazyProperty
 
from kallithea.model import meta
 
from kallithea.model.db import PullRequest, RepoGroup, Repository, Ui, User, UserFollowing, UserLog
 
from kallithea.model import db, meta
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class UserTemp(object):
 
@@ -133,13 +132,13 @@ class UserGroupList(_PermCheckIterator):
 
class ScmModel(object):
 
    """
 
    Generic Scm Model
 
    """
 

	
 
    def __get_repo(self, instance):
 
        cls = Repository
 
        cls = db.Repository
 
        if isinstance(instance, cls):
 
            return instance
 
        elif isinstance(instance, int):
 
            return cls.get(instance)
 
        elif isinstance(instance, str):
 
            if instance.isdigit():
 
@@ -151,13 +150,13 @@ class ScmModel(object):
 
    @LazyProperty
 
    def repos_path(self):
 
        """
 
        Gets the repositories root path from database
 
        """
 

	
 
        q = Ui.query().filter(Ui.ui_key == '/').one()
 
        q = db.Ui.query().filter(db.Ui.ui_key == '/').one()
 

	
 
        return q.ui_value
 

	
 
    def repo_scan(self, repos_path=None):
 
        """
 
        Listing of repositories in given path. This path should not be a
 
@@ -175,13 +174,13 @@ class ScmModel(object):
 
        baseui = make_ui()
 
        repos = {}
 

	
 
        for name, path in get_filesystem_repos(repos_path):
 
            # name need to be decomposed and put back together using the /
 
            # since this is internal storage separator for kallithea
 
            name = Repository.normalize_repo_name(name)
 
            name = db.Repository.normalize_repo_name(name)
 

	
 
            try:
 
                if name in repos:
 
                    raise RepositoryError('Duplicate repository name %s '
 
                                          'found in %s' % (name, path))
 
                else:
 
@@ -204,33 +203,33 @@ class ScmModel(object):
 

	
 
    def get_repo_groups(self, groups=None):
 
        """Return the repo groups the user has access to
 
        If no groups are specified, use top level groups.
 
        """
 
        if groups is None:
 
            groups = RepoGroup.query() \
 
                .filter(RepoGroup.parent_group_id == None).all()
 
            groups = db.RepoGroup.query() \
 
                .filter(db.RepoGroup.parent_group_id == None).all()
 
        return RepoGroupList(groups, perm_level='read')
 

	
 
    def mark_for_invalidation(self, repo_name):
 
        """
 
        Mark caches of this repo invalid in the database.
 

	
 
        :param repo_name: the repo for which caches should be marked invalid
 
        """
 
        log.debug("Marking %s as invalidated and update cache", repo_name)
 
        repo = Repository.get_by_repo_name(repo_name)
 
        repo = db.Repository.get_by_repo_name(repo_name)
 
        if repo is not None:
 
            repo.set_invalidate()
 
            repo.update_changeset_cache()
 

	
 
    def toggle_following_repo(self, follow_repo_id, user_id):
 

	
 
        f = UserFollowing.query() \
 
            .filter(UserFollowing.follows_repository_id == follow_repo_id) \
 
            .filter(UserFollowing.user_id == user_id).scalar()
 
        f = db.UserFollowing.query() \
 
            .filter(db.UserFollowing.follows_repository_id == follow_repo_id) \
 
            .filter(db.UserFollowing.user_id == user_id).scalar()
 

	
 
        if f is not None:
 
            try:
 
                meta.Session().delete(f)
 
                action_logger(UserTemp(user_id),
 
                              'stopped_following_repo',
 
@@ -238,81 +237,81 @@ class ScmModel(object):
 
                return
 
            except Exception:
 
                log.error(traceback.format_exc())
 
                raise
 

	
 
        try:
 
            f = UserFollowing()
 
            f = db.UserFollowing()
 
            f.user_id = user_id
 
            f.follows_repository_id = follow_repo_id
 
            meta.Session().add(f)
 

	
 
            action_logger(UserTemp(user_id),
 
                          'started_following_repo',
 
                          RepoTemp(follow_repo_id))
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise
 

	
 
    def toggle_following_user(self, follow_user_id, user_id):
 
        f = UserFollowing.query() \
 
            .filter(UserFollowing.follows_user_id == follow_user_id) \
 
            .filter(UserFollowing.user_id == user_id).scalar()
 
        f = db.UserFollowing.query() \
 
            .filter(db.UserFollowing.follows_user_id == follow_user_id) \
 
            .filter(db.UserFollowing.user_id == user_id).scalar()
 

	
 
        if f is not None:
 
            try:
 
                meta.Session().delete(f)
 
                return
 
            except Exception:
 
                log.error(traceback.format_exc())
 
                raise
 

	
 
        try:
 
            f = UserFollowing()
 
            f = db.UserFollowing()
 
            f.user_id = user_id
 
            f.follows_user_id = follow_user_id
 
            meta.Session().add(f)
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise
 

	
 
    def is_following_repo(self, repo_name, user_id):
 
        r = Repository.query() \
 
            .filter(Repository.repo_name == repo_name).scalar()
 
        r = db.Repository.query() \
 
            .filter(db.Repository.repo_name == repo_name).scalar()
 

	
 
        f = UserFollowing.query() \
 
            .filter(UserFollowing.follows_repository == r) \
 
            .filter(UserFollowing.user_id == user_id).scalar()
 
        f = db.UserFollowing.query() \
 
            .filter(db.UserFollowing.follows_repository == r) \
 
            .filter(db.UserFollowing.user_id == user_id).scalar()
 

	
 
        return f is not None
 

	
 
    def is_following_user(self, username, user_id):
 
        u = User.get_by_username(username)
 
        u = db.User.get_by_username(username)
 

	
 
        f = UserFollowing.query() \
 
            .filter(UserFollowing.follows_user == u) \
 
            .filter(UserFollowing.user_id == user_id).scalar()
 
        f = db.UserFollowing.query() \
 
            .filter(db.UserFollowing.follows_user == u) \
 
            .filter(db.UserFollowing.user_id == user_id).scalar()
 

	
 
        return f is not None
 

	
 
    def get_followers(self, repo):
 
        repo = Repository.guess_instance(repo)
 
        repo = db.Repository.guess_instance(repo)
 

	
 
        return UserFollowing.query() \
 
                .filter(UserFollowing.follows_repository == repo).count()
 
        return db.UserFollowing.query() \
 
                .filter(db.UserFollowing.follows_repository == repo).count()
 

	
 
    def get_forks(self, repo):
 
        repo = Repository.guess_instance(repo)
 
        return Repository.query() \
 
                .filter(Repository.fork == repo).count()
 
        repo = db.Repository.guess_instance(repo)
 
        return db.Repository.query() \
 
                .filter(db.Repository.fork == repo).count()
 

	
 
    def get_pull_requests(self, repo):
 
        repo = Repository.guess_instance(repo)
 
        return PullRequest.query() \
 
                .filter(PullRequest.other_repo == repo) \
 
                .filter(PullRequest.status != PullRequest.STATUS_CLOSED).count()
 
        repo = db.Repository.guess_instance(repo)
 
        return db.PullRequest.query() \
 
                .filter(db.PullRequest.other_repo == repo) \
 
                .filter(db.PullRequest.status != db.PullRequest.STATUS_CLOSED).count()
 

	
 
    def mark_as_fork(self, repo, fork, user):
 
        repo = self.__get_repo(repo)
 
        fork = self.__get_repo(fork)
 
        if fork and repo.repo_id == fork.repo_id:
 
            raise Exception("Cannot set repository as fork of itself")
 
@@ -390,13 +389,13 @@ class ScmModel(object):
 
                      content, f_path):
 
        """
 
        Commit a change to a single file
 

	
 
        :param repo: a db_repo.scm_instance
 
        """
 
        user = User.guess_instance(user)
 
        user = db.User.guess_instance(user)
 
        IMC = self._get_IMC_module(repo.alias)
 
        imc = IMC(repo)
 
        imc.change(FileNode(f_path, content, mode=cs.get_file_mode(f_path)))
 
        try:
 
            tip = imc.commit(message=message, author=author,
 
                             parents=[cs], branch=cs.branch)
 
@@ -462,13 +461,13 @@ class ScmModel(object):
 
        :param author: author of commit, cna be different that committer only for git
 
        :param trigger_push_hook: trigger push hooks
 

	
 
        :returns: new committed changeset
 
        """
 

	
 
        user = User.guess_instance(user)
 
        user = db.User.guess_instance(user)
 
        scm_instance = repo.scm_instance_no_cache()
 

	
 
        processed_nodes = []
 
        for f_path in nodes:
 
            content = nodes[f_path]['content']
 
            f_path = self._sanitize_path(f_path)
 
@@ -514,13 +513,13 @@ class ScmModel(object):
 

	
 
    def update_nodes(self, user, ip_addr, repo, message, nodes, parent_cs=None,
 
                     author=None, trigger_push_hook=True):
 
        """
 
        Commits specified nodes to repo. Again.
 
        """
 
        user = User.guess_instance(user)
 
        user = db.User.guess_instance(user)
 
        scm_instance = repo.scm_instance_no_cache()
 

	
 
        message = message
 
        committer = user.full_contact
 
        if not author:
 
            author = committer
 
@@ -587,13 +586,13 @@ class ScmModel(object):
 
        :param author: author of commit, cna be different that committer only for git
 
        :param trigger_push_hook: trigger push hooks
 

	
 
        :returns: new committed changeset after deletion
 
        """
 

	
 
        user = User.guess_instance(user)
 
        user = db.User.guess_instance(user)
 
        scm_instance = repo.scm_instance_no_cache()
 

	
 
        processed_nodes = []
 
        for f_path in nodes:
 
            f_path = self._sanitize_path(f_path)
 
            # content can be empty but for compatibility it allows same dicts
 
@@ -635,13 +634,13 @@ class ScmModel(object):
 
                              revisions=[tip.raw_id])
 
        else:
 
            self.mark_for_invalidation(repo.repo_name)
 
        return tip
 

	
 
    def get_unread_journal(self):
 
        return UserLog.query().count()
 
        return db.UserLog.query().count()
 

	
 
    def get_repo_landing_revs(self, repo=None):
 
        """
 
        Generates select option with tags branches and bookmarks (for hg only)
 
        grouped by type
 

	
 
@@ -746,17 +745,17 @@ class ScmModel(object):
 
def AvailableRepoGroupChoices(repo_group_perm_level, extras=()):
 
    """Return group_id,string tuples with choices for all the repo groups where
 
    the user has the necessary permissions.
 

	
 
    Top level is -1.
 
    """
 
    groups = RepoGroup.query().all()
 
    groups = db.RepoGroup.query().all()
 
    if HasPermissionAny('hg.admin')('available repo groups'):
 
        groups.append(None)
 
    else:
 
        groups = list(RepoGroupList(groups, perm_level=repo_group_perm_level))
 
        if HasPermissionAny('hg.create.repository')('available repo groups'):
 
            groups.append(None)
 
        for extra in extras:
 
            if not any(rg == extra for rg in groups):
 
                groups.append(extra)
 
    return RepoGroup.groups_choices(groups=groups)
 
    return db.RepoGroup.groups_choices(groups=groups)
kallithea/model/ssh_key.py
Show inline comments
 
@@ -28,14 +28,13 @@ import tempfile
 
from tg import config
 
from tg.i18n import ugettext as _
 

	
 
from kallithea.lib import ssh
 
from kallithea.lib.utils2 import asbool
 
from kallithea.lib.vcs.exceptions import RepositoryError
 
from kallithea.model import meta
 
from kallithea.model.db import User, UserSshKeys
 
from kallithea.model import db, meta
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class SshKeyModelException(RepositoryError):
 
@@ -55,46 +54,46 @@ class SshKeyModel(object):
 
            keytype, _pub, comment = ssh.parse_pub_key(public_key)
 
        except ssh.SshKeyParseError as e:
 
            raise SshKeyModelException(_('SSH key %r is invalid: %s') % (public_key, e.args[0]))
 
        if not description.strip():
 
            description = comment.strip()
 

	
 
        user = User.guess_instance(user)
 
        user = db.User.guess_instance(user)
 

	
 
        new_ssh_key = UserSshKeys()
 
        new_ssh_key = db.UserSshKeys()
 
        new_ssh_key.user_id = user.user_id
 
        new_ssh_key.description = description
 
        new_ssh_key.public_key = public_key
 

	
 
        for ssh_key in UserSshKeys.query().filter(UserSshKeys.fingerprint == new_ssh_key.fingerprint).all():
 
        for ssh_key in db.UserSshKeys.query().filter(db.UserSshKeys.fingerprint == new_ssh_key.fingerprint).all():
 
            raise SshKeyModelException(_('SSH key %s is already used by %s') %
 
                                       (new_ssh_key.fingerprint, ssh_key.user.username))
 

	
 
        meta.Session().add(new_ssh_key)
 

	
 
        return new_ssh_key
 

	
 
    def delete(self, fingerprint, user):
 
        """
 
        Deletes ssh key with given fingerprint for the given user.
 
        Will raise SshKeyModelException on errors
 
        """
 
        ssh_key = UserSshKeys.query().filter(UserSshKeys.fingerprint == fingerprint)
 
        ssh_key = db.UserSshKeys.query().filter(db.UserSshKeys.fingerprint == fingerprint)
 

	
 
        user = User.guess_instance(user)
 
        ssh_key = ssh_key.filter(UserSshKeys.user_id == user.user_id)
 
        user = db.User.guess_instance(user)
 
        ssh_key = ssh_key.filter(db.UserSshKeys.user_id == user.user_id)
 

	
 
        ssh_key = ssh_key.scalar()
 
        if ssh_key is None:
 
            raise SshKeyModelException(_('SSH key with fingerprint %r found') % fingerprint)
 
        meta.Session().delete(ssh_key)
 

	
 
    def get_ssh_keys(self, user):
 
        user = User.guess_instance(user)
 
        user_ssh_keys = UserSshKeys.query() \
 
            .filter(UserSshKeys.user_id == user.user_id).all()
 
        user = db.User.guess_instance(user)
 
        user_ssh_keys = db.UserSshKeys.query() \
 
            .filter(db.UserSshKeys.user_id == user.user_id).all()
 
        return user_ssh_keys
 

	
 
    def write_authorized_keys(self):
 
        if not asbool(config.get('ssh_enabled', False)):
 
            log.error("Will not write SSH authorized_keys file - ssh_enabled is not configured")
 
            return
 
@@ -128,11 +127,11 @@ class SshKeyModel(object):
 
                    else:
 
                        raise SshKeyModelException("Safety check failed, found %r line in %s - please remove it if Kallithea should manage the file" % (l.strip(), authorized_keys))
 

	
 
        fh, tmp_authorized_keys = tempfile.mkstemp('.authorized_keys', dir=os.path.dirname(authorized_keys))
 
        with os.fdopen(fh, 'w') as f:
 
            f.write("# WARNING: This .ssh/authorized_keys file is managed by Kallithea. Manual editing or adding new entries will make Kallithea back off.\n")
 
            for key in UserSshKeys.query().join(UserSshKeys.user).filter(User.active == True):
 
            for key in db.UserSshKeys.query().join(db.UserSshKeys.user).filter(db.User.active == True):
 
                f.write(ssh.authorized_keys_line(kallithea_cli_path, config['__file__'], key))
 
        os.chmod(tmp_authorized_keys, stat.S_IRUSR | stat.S_IWUSR)
 
        # Note: simple overwrite / rename isn't enough to replace the file on Windows
 
        os.replace(tmp_authorized_keys, authorized_keys)
kallithea/model/user.py
Show inline comments
 
@@ -35,28 +35,27 @@ import traceback
 
from sqlalchemy.exc import DatabaseError
 
from tg import config
 
from tg.i18n import ugettext as _
 

	
 
from kallithea.lib.exceptions import DefaultUserException, UserOwnsReposException
 
from kallithea.lib.utils2 import generate_api_key, get_current_authuser
 
from kallithea.model import meta
 
from kallithea.model.db import Permission, User, UserEmailMap, UserIpMap, UserToPerm
 
from kallithea.model import db, meta
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class UserModel(object):
 
    password_reset_token_lifetime = 86400 # 24 hours
 

	
 
    def get(self, user_id):
 
        user = User.query()
 
        user = db.User.query()
 
        return user.get(user_id)
 

	
 
    def get_user(self, user):
 
        return User.guess_instance(user)
 
        return db.User.guess_instance(user)
 

	
 
    def create(self, form_data, cur_user=None):
 
        if not cur_user:
 
            cur_user = getattr(get_current_authuser(), 'username', None)
 

	
 
        from kallithea.lib.hooks import check_allowed_create_user, log_create_user
 
@@ -71,13 +70,13 @@ class UserModel(object):
 
            'admin': False
 
        }
 
        # raises UserCreationError if it's not allowed
 
        check_allowed_create_user(user_data, cur_user)
 
        from kallithea.lib.auth import get_crypt_password
 

	
 
        new_user = User()
 
        new_user = db.User()
 
        for k, v in form_data.items():
 
            if k == 'password':
 
                v = get_crypt_password(v)
 
            if k == 'firstname':
 
                k = 'name'
 
            setattr(new_user, k, v)
 
@@ -118,16 +117,16 @@ class UserModel(object):
 
            'active': active, 'admin': admin
 
        }
 
        # raises UserCreationError if it's not allowed
 
        check_allowed_create_user(user_data, cur_user)
 

	
 
        log.debug('Checking for %s account in Kallithea database', username)
 
        user = User.get_by_username(username, case_insensitive=True)
 
        user = db.User.get_by_username(username, case_insensitive=True)
 
        if user is None:
 
            log.debug('creating new user %s', username)
 
            new_user = User()
 
            new_user = db.User()
 
            edit = False
 
        else:
 
            log.debug('updating user %s', username)
 
            new_user = user
 
            edit = True
 

	
 
@@ -167,13 +166,13 @@ class UserModel(object):
 

	
 
    def create_registration(self, form_data):
 
        import kallithea.lib.helpers as h
 
        from kallithea.model.notification import NotificationModel
 

	
 
        form_data['admin'] = False
 
        form_data['extern_type'] = User.DEFAULT_AUTH_TYPE
 
        form_data['extern_type'] = db.User.DEFAULT_AUTH_TYPE
 
        form_data['extern_name'] = ''
 
        new_user = self.create(form_data)
 

	
 
        # notification to admins
 
        subject = _('New user registration')
 
        body = (
 
@@ -215,13 +214,13 @@ class UserModel(object):
 
                    k = 'name'
 
                setattr(user, k, v)
 

	
 
    def update_user(self, user, **kwargs):
 
        from kallithea.lib.auth import get_crypt_password
 

	
 
        user = User.guess_instance(user)
 
        user = db.User.guess_instance(user)
 
        if user.is_default_user:
 
            raise DefaultUserException(
 
                _("You can't edit this user since it's"
 
                  " crucial for entire application")
 
            )
 

	
 
@@ -232,13 +231,13 @@ class UserModel(object):
 
            setattr(user, k, v)
 
        return user
 

	
 
    def delete(self, user, cur_user=None):
 
        if cur_user is None:
 
            cur_user = getattr(get_current_authuser(), 'username', None)
 
        user = User.guess_instance(user)
 
        user = db.User.guess_instance(user)
 

	
 
        if user.is_default_user:
 
            raise DefaultUserException(
 
                _("You can't remove this user since it is"
 
                  " crucial for the entire application"))
 
        if user.repositories:
 
@@ -317,13 +316,13 @@ class UserModel(object):
 
        """
 
        import kallithea.lib.helpers as h
 
        from kallithea.lib.celerylib import tasks
 
        from kallithea.model.notification import EmailNotificationModel
 

	
 
        user_email = data['email']
 
        user = User.get_by_email(user_email)
 
        user = db.User.get_by_email(user_email)
 
        timestamp = int(time.time())
 
        if user is not None:
 
            if self.can_change_password(user):
 
                log.debug('password reset user %s found', user)
 
                token = self.get_reset_password_token(user,
 
                                                      timestamp,
 
@@ -358,13 +357,13 @@ class UserModel(object):
 
        return h.url('reset_password_confirmation',
 
                     email=user_email,
 
                     timestamp=timestamp)
 

	
 
    def verify_reset_password_token(self, email, timestamp, token):
 
        import kallithea.lib.helpers as h
 
        user = User.get_by_email(email)
 
        user = db.User.get_by_email(email)
 
        if user is None:
 
            log.debug("user with email %s not found", email)
 
            return False
 

	
 
        token_age = int(time.time()) - int(timestamp)
 

	
 
@@ -383,13 +382,13 @@ class UserModel(object):
 
        log.debug('received password reset token: %s', token)
 
        return expected_token == token
 

	
 
    def reset_password(self, user_email, new_passwd):
 
        from kallithea.lib import auth
 
        from kallithea.lib.celerylib import tasks
 
        user = User.get_by_email(user_email)
 
        user = db.User.get_by_email(user_email)
 
        if user is not None:
 
            if not self.can_change_password(user):
 
                raise Exception('trying to change password for external user')
 
            user.password = auth.get_crypt_password(new_passwd)
 
            meta.Session().commit()
 
            log.info('change password for %s', user_email)
 
@@ -401,82 +400,82 @@ class UserModel(object):
 
                 _('The password to your account %s has been changed using password reset form.') % (user.username,))
 
        log.info('send password reset mail to %s', user_email)
 

	
 
        return True
 

	
 
    def has_perm(self, user, perm):
 
        perm = Permission.guess_instance(perm)
 
        user = User.guess_instance(user)
 
        perm = db.Permission.guess_instance(perm)
 
        user = db.User.guess_instance(user)
 

	
 
        return UserToPerm.query().filter(UserToPerm.user == user) \
 
            .filter(UserToPerm.permission == perm).scalar() is not None
 
        return db.UserToPerm.query().filter(db.UserToPerm.user == user) \
 
            .filter(db.UserToPerm.permission == perm).scalar() is not None
 

	
 
    def grant_perm(self, user, perm):
 
        """
 
        Grant user global permissions
 

	
 
        :param user:
 
        :param perm:
 
        """
 
        user = User.guess_instance(user)
 
        perm = Permission.guess_instance(perm)
 
        user = db.User.guess_instance(user)
 
        perm = db.Permission.guess_instance(perm)
 
        # if this permission is already granted skip it
 
        _perm = UserToPerm.query() \
 
            .filter(UserToPerm.user == user) \
 
            .filter(UserToPerm.permission == perm) \
 
        _perm = db.UserToPerm.query() \
 
            .filter(db.UserToPerm.user == user) \
 
            .filter(db.UserToPerm.permission == perm) \
 
            .scalar()
 
        if _perm:
 
            return
 
        new = UserToPerm()
 
        new = db.UserToPerm()
 
        new.user = user
 
        new.permission = perm
 
        meta.Session().add(new)
 
        return new
 

	
 
    def revoke_perm(self, user, perm):
 
        """
 
        Revoke users global permissions
 

	
 
        :param user:
 
        :param perm:
 
        """
 
        user = User.guess_instance(user)
 
        perm = Permission.guess_instance(perm)
 
        user = db.User.guess_instance(user)
 
        perm = db.Permission.guess_instance(perm)
 

	
 
        UserToPerm.query().filter(
 
            UserToPerm.user == user,
 
            UserToPerm.permission == perm,
 
        db.UserToPerm.query().filter(
 
            db.UserToPerm.user == user,
 
            db.UserToPerm.permission == perm,
 
        ).delete()
 

	
 
    def add_extra_email(self, user, email):
 
        """
 
        Adds email address to UserEmailMap
 

	
 
        :param user:
 
        :param email:
 
        """
 
        from kallithea.model import forms
 
        form = forms.UserExtraEmailForm()()
 
        data = form.to_python(dict(email=email))
 
        user = User.guess_instance(user)
 
        user = db.User.guess_instance(user)
 

	
 
        obj = UserEmailMap()
 
        obj = db.UserEmailMap()
 
        obj.user = user
 
        obj.email = data['email']
 
        meta.Session().add(obj)
 
        return obj
 

	
 
    def delete_extra_email(self, user, email_id):
 
        """
 
        Removes email address from UserEmailMap
 

	
 
        :param user:
 
        :param email_id:
 
        """
 
        user = User.guess_instance(user)
 
        obj = UserEmailMap.query().get(email_id)
 
        user = db.User.guess_instance(user)
 
        obj = db.UserEmailMap.query().get(email_id)
 
        if obj is not None:
 
            meta.Session().delete(obj)
 

	
 
    def add_extra_ip(self, user, ip):
 
        """
 
        Adds IP address to UserIpMap
 
@@ -484,25 +483,25 @@ class UserModel(object):
 
        :param user:
 
        :param ip:
 
        """
 
        from kallithea.model import forms
 
        form = forms.UserExtraIpForm()()
 
        data = form.to_python(dict(ip=ip))
 
        user = User.guess_instance(user)
 
        user = db.User.guess_instance(user)
 

	
 
        obj = UserIpMap()
 
        obj = db.UserIpMap()
 
        obj.user = user
 
        obj.ip_addr = data['ip']
 
        meta.Session().add(obj)
 
        return obj
 

	
 
    def delete_extra_ip(self, user, ip_id):
 
        """
 
        Removes IP address from UserIpMap
 

	
 
        :param user:
 
        :param ip_id:
 
        """
 
        user = User.guess_instance(user)
 
        obj = UserIpMap.query().get(ip_id)
 
        user = db.User.guess_instance(user)
 
        obj = db.UserIpMap.query().get(ip_id)
 
        if obj:
 
            meta.Session().delete(obj)
kallithea/model/user_group.py
Show inline comments
 
@@ -25,32 +25,31 @@ Original author and date, and relevant c
 

	
 

	
 
import logging
 
import traceback
 

	
 
from kallithea.lib.exceptions import RepoGroupAssignmentError, UserGroupsAssignedException
 
from kallithea.model import meta
 
from kallithea.model.db import Permission, User, UserGroup, UserGroupMember, UserGroupRepoToPerm, UserGroupToPerm, UserGroupUserGroupToPerm, UserUserGroupToPerm
 
from kallithea.model import db, meta
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class UserGroupModel(object):
 

	
 
    def _create_default_perms(self, user_group):
 
        # create default permission
 
        default_perm = 'usergroup.read'
 
        def_user = User.get_default_user()
 
        def_user = db.User.get_default_user()
 
        for p in def_user.user_perms:
 
            if p.permission.permission_name.startswith('usergroup.'):
 
                default_perm = p.permission.permission_name
 
                break
 

	
 
        user_group_to_perm = UserUserGroupToPerm()
 
        user_group_to_perm.permission = Permission.get_by_key(default_perm)
 
        user_group_to_perm = db.UserUserGroupToPerm()
 
        user_group_to_perm.permission = db.Permission.get_by_key(default_perm)
 

	
 
        user_group_to_perm.user_group = user_group
 
        user_group_to_perm.user_id = def_user.user_id
 
        meta.Session().add(user_group_to_perm)
 
        return user_group_to_perm
 

	
 
@@ -86,24 +85,24 @@ class UserGroupModel(object):
 
                if HasUserGroupPermissionLevel('read')(member):
 
                    self.grant_user_group_permission(
 
                        target_user_group=user_group, user_group=member, perm=perm
 
                    )
 

	
 
    def get(self, user_group_id):
 
        return UserGroup.get(user_group_id)
 
        return db.UserGroup.get(user_group_id)
 

	
 
    def get_group(self, user_group):
 
        return UserGroup.guess_instance(user_group)
 
        return db.UserGroup.guess_instance(user_group)
 

	
 
    def get_by_name(self, name, case_insensitive=False):
 
        return UserGroup.get_by_group_name(name, case_insensitive=case_insensitive)
 
        return db.UserGroup.get_by_group_name(name, case_insensitive=case_insensitive)
 

	
 
    def create(self, name, description, owner, active=True, group_data=None):
 
        try:
 
            new_user_group = UserGroup()
 
            new_user_group.owner = User.guess_instance(owner)
 
            new_user_group = db.UserGroup()
 
            new_user_group.owner = db.User.guess_instance(owner)
 
            new_user_group.users_group_name = name
 
            new_user_group.user_group_description = description
 
            new_user_group.users_group_active = active
 
            if group_data:
 
                new_user_group.group_data = group_data
 
            meta.Session().add(new_user_group)
 
@@ -117,21 +116,21 @@ class UserGroupModel(object):
 
            log.error(traceback.format_exc())
 
            raise
 

	
 
    def update(self, user_group, form_data):
 

	
 
        try:
 
            user_group = UserGroup.guess_instance(user_group)
 
            user_group = db.UserGroup.guess_instance(user_group)
 

	
 
            for k, v in form_data.items():
 
                if k == 'users_group_members':
 
                    members_list = []
 
                    if v:
 
                        v = [v] if isinstance(v, str) else v
 
                        for u_id in set(v):
 
                            member = UserGroupMember(user_group.users_group_id, u_id)
 
                            member = db.UserGroupMember(user_group.users_group_id, u_id)
 
                            members_list.append(member)
 
                            meta.Session().add(member)
 
                    user_group.members = members_list
 
                setattr(user_group, k, v)
 

	
 
            # Flush to make db assign users_group_member_id to newly
 
@@ -147,40 +146,40 @@ class UserGroupModel(object):
 
        raises exception if there are members in that group, else deletes
 
        group and users
 

	
 
        :param user_group:
 
        :param force:
 
        """
 
        user_group = UserGroup.guess_instance(user_group)
 
        user_group = db.UserGroup.guess_instance(user_group)
 
        try:
 
            # check if this group is not assigned to repo
 
            assigned_groups = UserGroupRepoToPerm.query() \
 
                .filter(UserGroupRepoToPerm.users_group == user_group).all()
 
            assigned_groups = db.UserGroupRepoToPerm.query() \
 
                .filter(db.UserGroupRepoToPerm.users_group == user_group).all()
 
            assigned_groups = [x.repository.repo_name for x in assigned_groups]
 

	
 
            if assigned_groups and not force:
 
                raise UserGroupsAssignedException(
 
                    'User Group assigned to %s' % ", ".join(assigned_groups))
 
            meta.Session().delete(user_group)
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise
 

	
 
    def add_user_to_group(self, user_group, user):
 
        """Return True if user already is in the group - else return the new UserGroupMember"""
 
        user_group = UserGroup.guess_instance(user_group)
 
        user = User.guess_instance(user)
 
        user_group = db.UserGroup.guess_instance(user_group)
 
        user = db.User.guess_instance(user)
 

	
 
        for m in user_group.members:
 
            u = m.user
 
            if u.user_id == user.user_id:
 
                # user already in the group, skip
 
                return True
 

	
 
        try:
 
            user_group_member = UserGroupMember()
 
            user_group_member = db.UserGroupMember()
 
            user_group_member.user = user
 
            user_group_member.users_group = user_group
 

	
 
            user_group.members.append(user_group_member)
 
            user.group_member.append(user_group_member)
 

	
 
@@ -188,14 +187,14 @@ class UserGroupModel(object):
 
            return user_group_member
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise
 

	
 
    def remove_user_from_group(self, user_group, user):
 
        user_group = UserGroup.guess_instance(user_group)
 
        user = User.guess_instance(user)
 
        user_group = db.UserGroup.guess_instance(user_group)
 
        user = db.User.guess_instance(user)
 

	
 
        user_group_member = None
 
        for m in user_group.members:
 
            if m.user_id == user.user_id:
 
                # Found this user's membership row
 
                user_group_member = m
 
@@ -210,44 +209,44 @@ class UserGroupModel(object):
 
                raise
 
        else:
 
            # User isn't in that group
 
            return False
 

	
 
    def has_perm(self, user_group, perm):
 
        user_group = UserGroup.guess_instance(user_group)
 
        perm = Permission.guess_instance(perm)
 
        user_group = db.UserGroup.guess_instance(user_group)
 
        perm = db.Permission.guess_instance(perm)
 

	
 
        return UserGroupToPerm.query() \
 
            .filter(UserGroupToPerm.users_group == user_group) \
 
            .filter(UserGroupToPerm.permission == perm).scalar() is not None
 
        return db.UserGroupToPerm.query() \
 
            .filter(db.UserGroupToPerm.users_group == user_group) \
 
            .filter(db.UserGroupToPerm.permission == perm).scalar() is not None
 

	
 
    def grant_perm(self, user_group, perm):
 
        user_group = UserGroup.guess_instance(user_group)
 
        perm = Permission.guess_instance(perm)
 
        user_group = db.UserGroup.guess_instance(user_group)
 
        perm = db.Permission.guess_instance(perm)
 

	
 
        # if this permission is already granted skip it
 
        _perm = UserGroupToPerm.query() \
 
            .filter(UserGroupToPerm.users_group == user_group) \
 
            .filter(UserGroupToPerm.permission == perm) \
 
        _perm = db.UserGroupToPerm.query() \
 
            .filter(db.UserGroupToPerm.users_group == user_group) \
 
            .filter(db.UserGroupToPerm.permission == perm) \
 
            .scalar()
 
        if _perm:
 
            return
 

	
 
        new = UserGroupToPerm()
 
        new = db.UserGroupToPerm()
 
        new.users_group = user_group
 
        new.permission = perm
 
        meta.Session().add(new)
 
        return new
 

	
 
    def revoke_perm(self, user_group, perm):
 
        user_group = UserGroup.guess_instance(user_group)
 
        perm = Permission.guess_instance(perm)
 
        user_group = db.UserGroup.guess_instance(user_group)
 
        perm = db.Permission.guess_instance(perm)
 

	
 
        obj = UserGroupToPerm.query() \
 
            .filter(UserGroupToPerm.users_group == user_group) \
 
            .filter(UserGroupToPerm.permission == perm).scalar()
 
        obj = db.UserGroupToPerm.query() \
 
            .filter(db.UserGroupToPerm.users_group == user_group) \
 
            .filter(db.UserGroupToPerm.permission == perm).scalar()
 
        if obj is not None:
 
            meta.Session().delete(obj)
 

	
 
    def grant_user_permission(self, user_group, user, perm):
 
        """
 
        Grant permission for user on given user group, or update
 
@@ -256,24 +255,24 @@ class UserGroupModel(object):
 
        :param user_group: Instance of UserGroup, users_group_id,
 
            or users_group_name
 
        :param user: Instance of User, user_id or username
 
        :param perm: Instance of Permission, or permission_name
 
        """
 

	
 
        user_group = UserGroup.guess_instance(user_group)
 
        user = User.guess_instance(user)
 
        permission = Permission.guess_instance(perm)
 
        user_group = db.UserGroup.guess_instance(user_group)
 
        user = db.User.guess_instance(user)
 
        permission = db.Permission.guess_instance(perm)
 

	
 
        # check if we have that permission already
 
        obj = UserUserGroupToPerm.query() \
 
            .filter(UserUserGroupToPerm.user == user) \
 
            .filter(UserUserGroupToPerm.user_group == user_group) \
 
        obj = db.UserUserGroupToPerm.query() \
 
            .filter(db.UserUserGroupToPerm.user == user) \
 
            .filter(db.UserUserGroupToPerm.user_group == user_group) \
 
            .scalar()
 
        if obj is None:
 
            # create new !
 
            obj = UserUserGroupToPerm()
 
            obj = db.UserUserGroupToPerm()
 
            meta.Session().add(obj)
 
        obj.user_group = user_group
 
        obj.user = user
 
        obj.permission = permission
 
        log.debug('Granted perm %s to %s on %s', perm, user, user_group)
 
        return obj
 
@@ -284,18 +283,18 @@ class UserGroupModel(object):
 

	
 
        :param user_group: Instance of RepoGroup, repositories_group_id,
 
            or repositories_group name
 
        :param user: Instance of User, user_id or username
 
        """
 

	
 
        user_group = UserGroup.guess_instance(user_group)
 
        user = User.guess_instance(user)
 
        user_group = db.UserGroup.guess_instance(user_group)
 
        user = db.User.guess_instance(user)
 

	
 
        obj = UserUserGroupToPerm.query() \
 
            .filter(UserUserGroupToPerm.user == user) \
 
            .filter(UserUserGroupToPerm.user_group == user_group) \
 
        obj = db.UserUserGroupToPerm.query() \
 
            .filter(db.UserUserGroupToPerm.user == user) \
 
            .filter(db.UserUserGroupToPerm.user_group == user_group) \
 
            .scalar()
 
        if obj is not None:
 
            meta.Session().delete(obj)
 
            log.debug('Revoked perm on %s on %s', user_group, user)
 

	
 
    def grant_user_group_permission(self, target_user_group, user_group, perm):
 
@@ -303,28 +302,28 @@ class UserGroupModel(object):
 
        Grant user group permission for given target_user_group
 

	
 
        :param target_user_group:
 
        :param user_group:
 
        :param perm:
 
        """
 
        target_user_group = UserGroup.guess_instance(target_user_group)
 
        user_group = UserGroup.guess_instance(user_group)
 
        permission = Permission.guess_instance(perm)
 
        target_user_group = db.UserGroup.guess_instance(target_user_group)
 
        user_group = db.UserGroup.guess_instance(user_group)
 
        permission = db.Permission.guess_instance(perm)
 
        # forbid assigning same user group to itself
 
        if target_user_group == user_group:
 
            raise RepoGroupAssignmentError('target repo:%s cannot be '
 
                                           'assigned to itself' % target_user_group)
 

	
 
        # check if we have that permission already
 
        obj = UserGroupUserGroupToPerm.query() \
 
            .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group) \
 
            .filter(UserGroupUserGroupToPerm.user_group == user_group) \
 
        obj = db.UserGroupUserGroupToPerm.query() \
 
            .filter(db.UserGroupUserGroupToPerm.target_user_group == target_user_group) \
 
            .filter(db.UserGroupUserGroupToPerm.user_group == user_group) \
 
            .scalar()
 
        if obj is None:
 
            # create new !
 
            obj = UserGroupUserGroupToPerm()
 
            obj = db.UserGroupUserGroupToPerm()
 
            meta.Session().add(obj)
 
        obj.user_group = user_group
 
        obj.target_user_group = target_user_group
 
        obj.permission = permission
 
        log.debug('Granted perm %s to %s on %s', perm, target_user_group, user_group)
 
        return obj
 
@@ -333,25 +332,25 @@ class UserGroupModel(object):
 
        """
 
        Revoke user group permission for given target_user_group
 

	
 
        :param target_user_group:
 
        :param user_group:
 
        """
 
        target_user_group = UserGroup.guess_instance(target_user_group)
 
        user_group = UserGroup.guess_instance(user_group)
 
        target_user_group = db.UserGroup.guess_instance(target_user_group)
 
        user_group = db.UserGroup.guess_instance(user_group)
 

	
 
        obj = UserGroupUserGroupToPerm.query() \
 
            .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group) \
 
            .filter(UserGroupUserGroupToPerm.user_group == user_group) \
 
        obj = db.UserGroupUserGroupToPerm.query() \
 
            .filter(db.UserGroupUserGroupToPerm.target_user_group == target_user_group) \
 
            .filter(db.UserGroupUserGroupToPerm.user_group == user_group) \
 
            .scalar()
 
        if obj is not None:
 
            meta.Session().delete(obj)
 
            log.debug('Revoked perm on %s on %s', target_user_group, user_group)
 

	
 
    def enforce_groups(self, user, groups, extern_type=None):
 
        user = User.guess_instance(user)
 
        user = db.User.guess_instance(user)
 
        log.debug('Enforcing groups %s on user %s', user, groups)
 
        current_groups = user.group_member
 
        # find the external created groups
 
        externals = [x.users_group for x in current_groups
 
                     if 'extern_type' in x.users_group.group_data]
 

	
 
@@ -360,15 +359,15 @@ class UserGroupModel(object):
 
        for gr in externals:
 
            if gr.users_group_name not in groups:
 
                log.debug('Removing user %s from user group %s', user, gr)
 
                self.remove_user_from_group(gr, user)
 

	
 
        # now we calculate in which groups user should be == groups params
 
        owner = User.get_first_admin().username
 
        owner = db.User.get_first_admin().username
 
        for gr in set(groups):
 
            existing_group = UserGroup.get_by_group_name(gr)
 
            existing_group = db.UserGroup.get_by_group_name(gr)
 
            if not existing_group:
 
                desc = 'Automatically created from plugin:%s' % extern_type
 
                # we use first admin account to set the owner of the group
 
                existing_group = UserGroupModel().create(gr, desc, owner,
 
                                        group_data={'extern_type': extern_type})
 

	
kallithea/model/validators.py
Show inline comments
 
@@ -30,13 +30,13 @@ from tg.i18n import ugettext as _
 
import kallithea
 
from kallithea.lib.auth import HasPermissionAny, HasRepoGroupPermissionLevel
 
from kallithea.lib.compat import OrderedSet
 
from kallithea.lib.exceptions import InvalidCloneUriException, LdapImportError
 
from kallithea.lib.utils import is_valid_repo_uri
 
from kallithea.lib.utils2 import asbool, aslist, repo_name_slug
 
from kallithea.model.db import RepoGroup, Repository, User, UserGroup
 
from kallithea.model import db
 

	
 

	
 
# silence warnings and pylint
 
UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set, \
 
    NotEmpty, IPAddress, CIDR, String, FancyValidator
 

	
 
@@ -82,16 +82,16 @@ def ValidUsername(edit=False, old_data=N
 
            if value in ['default', 'new_user']:
 
                msg = self.message('system_invalid_username', state, username=value)
 
                raise formencode.Invalid(msg, value, state)
 
            # check if user is unique
 
            old_un = None
 
            if edit:
 
                old_un = User.get(old_data.get('user_id')).username
 
                old_un = db.User.get(old_data.get('user_id')).username
 

	
 
            if old_un != value or not edit:
 
                if User.get_by_username(value, case_insensitive=True):
 
                if db.User.get_by_username(value, case_insensitive=True):
 
                    msg = self.message('username_exists', state, username=value)
 
                    raise formencode.Invalid(msg, value, state)
 

	
 
            if re.match(r'^[a-zA-Z0-9\_]{1}[a-zA-Z0-9\-\_\.]*$', value) is None:
 
                msg = self.message('invalid_username', state)
 
                raise formencode.Invalid(msg, value, state)
 
@@ -109,14 +109,14 @@ def ValidRepoUser():
 
        messages = {
 
            'invalid_username': _('Username %(username)s is not valid')
 
        }
 

	
 
        def _validate_python(self, value, state):
 
            try:
 
                User.query().filter(User.active == True) \
 
                    .filter(User.username == value).one()
 
                db.User.query().filter(db.User.active == True) \
 
                    .filter(db.User.username == value).one()
 
            except sqlalchemy.exc.InvalidRequestError: # NoResultFound/MultipleResultsFound
 
                msg = self.message('invalid_username', state, username=value)
 
                raise formencode.Invalid(msg, value, state,
 
                    error_dict=dict(username=msg)
 
                )
 

	
 
@@ -143,16 +143,16 @@ def ValidUserGroup(edit=False, old_data=
 
                    error_dict=dict(users_group_name=msg)
 
                )
 
            # check if group is unique
 
            old_ugname = None
 
            if edit:
 
                old_id = old_data.get('users_group_id')
 
                old_ugname = UserGroup.get(old_id).users_group_name
 
                old_ugname = db.UserGroup.get(old_id).users_group_name
 

	
 
            if old_ugname != value or not edit:
 
                is_existing_group = UserGroup.get_by_group_name(value,
 
                is_existing_group = db.UserGroup.get_by_group_name(value,
 
                                                        case_insensitive=True)
 
                if is_existing_group:
 
                    msg = self.message('group_exist', state, usergroup=value)
 
                    raise formencode.Invalid(msg, value, state,
 
                        error_dict=dict(users_group_name=msg)
 
                    )
 
@@ -191,30 +191,30 @@ def ValidRepoGroup(edit=False, old_data=
 
                raise formencode.Invalid(msg, value, state,
 
                    error_dict=dict(parent_group_id=msg)
 
                )
 

	
 
            old_gname = None
 
            if edit:
 
                old_gname = RepoGroup.get(old_data.get('group_id')).group_name
 
                old_gname = db.RepoGroup.get(old_data.get('group_id')).group_name
 

	
 
            if old_gname != group_name or not edit:
 

	
 
                # check group
 
                gr = RepoGroup.query() \
 
                      .filter(func.lower(RepoGroup.group_name) == func.lower(slug)) \
 
                      .filter(RepoGroup.parent_group_id == parent_group_id) \
 
                gr = db.RepoGroup.query() \
 
                      .filter(func.lower(db.RepoGroup.group_name) == func.lower(slug)) \
 
                      .filter(db.RepoGroup.parent_group_id == parent_group_id) \
 
                      .scalar()
 
                if gr is not None:
 
                    msg = self.message('group_exists', state, group_name=slug)
 
                    raise formencode.Invalid(msg, value, state,
 
                            error_dict=dict(group_name=msg)
 
                    )
 

	
 
                # check for same repo
 
                repo = Repository.query() \
 
                      .filter(func.lower(Repository.repo_name) == func.lower(slug)) \
 
                repo = db.Repository.query() \
 
                      .filter(func.lower(db.Repository.repo_name) == func.lower(slug)) \
 
                      .scalar()
 
                if repo is not None:
 
                    msg = self.message('repo_exists', state, group_name=slug)
 
                    raise formencode.Invalid(msg, value, state,
 
                            error_dict=dict(group_name=msg)
 
                    )
 
@@ -281,13 +281,13 @@ def ValidAuth():
 
            password = value['password']
 
            username = value['username']
 

	
 
            # authenticate returns unused dict but has called
 
            # plugin._authenticate which has create_or_update'ed the username user in db
 
            if auth_modules.authenticate(username, password) is None:
 
                user = User.get_by_username_or_email(username)
 
                user = db.User.get_by_username_or_email(username)
 
                if user and not user.active:
 
                    log.warning('user %s is disabled', username)
 
                    msg = self.message('invalid_auth', state)
 
                    raise formencode.Invalid(msg, value, state,
 
                        error_dict=dict(username=' ', password=msg)
 
                    )
 
@@ -316,13 +316,13 @@ def ValidRepoName(edit=False, old_data=N
 
        }
 

	
 
        def _convert_to_python(self, value, state):
 
            repo_name = repo_name_slug(value.get('repo_name', ''))
 
            repo_group = value.get('repo_group')
 
            if repo_group:
 
                gr = RepoGroup.get(repo_group)
 
                gr = db.RepoGroup.get(repo_group)
 
                group_path = gr.full_path
 
                group_name = gr.group_name
 
                # value needs to be aware of group name in order to check
 
                # db key This is an actual just the name to store in the
 
                # database
 
                repo_name_full = group_path + kallithea.URL_SEP + repo_name
 
@@ -348,14 +348,14 @@ def ValidRepoName(edit=False, old_data=N
 
                    error_dict=dict(repo_name=msg)
 
                )
 

	
 
            rename = old_data.get('repo_name') != repo_name_full
 
            create = not edit
 
            if rename or create:
 
                repo = Repository.get_by_repo_name(repo_name_full, case_insensitive=True)
 
                repo_group = RepoGroup.get_by_group_name(repo_name_full, case_insensitive=True)
 
                repo = db.Repository.get_by_repo_name(repo_name_full, case_insensitive=True)
 
                repo_group = db.RepoGroup.get_by_group_name(repo_name_full, case_insensitive=True)
 
                if group_path != '':
 
                    if repo is not None:
 
                        msg = self.message('repository_in_group_exists', state,
 
                                repo=repo.repo_name, group=group_name)
 
                        raise formencode.Invalid(msg, value, state,
 
                            error_dict=dict(repo_name=msg)
 
@@ -448,13 +448,13 @@ def CanWriteGroup(old_data=None):
 
            # root location
 
            if value == -1:
 
                return None
 
            return value
 

	
 
        def _validate_python(self, value, state):
 
            gr = RepoGroup.get(value)
 
            gr = db.RepoGroup.get(value)
 
            gr_name = gr.group_name if gr is not None else None # None means ROOT location
 

	
 
            # create repositories with write permission on group is set to true
 
            group_admin = HasRepoGroupPermissionLevel('admin')(gr_name,
 
                                            'can write into group validator')
 
            group_write = HasRepoGroupPermissionLevel('write')(gr_name,
 
@@ -497,13 +497,13 @@ def CanCreateGroup(can_create_in_root=Fa
 
            # root location
 
            if value == -1:
 
                return None
 
            return value
 

	
 
        def _validate_python(self, value, state):
 
            gr = RepoGroup.get(value)
 
            gr = db.RepoGroup.get(value)
 
            gr_name = gr.group_name if gr is not None else None # None means ROOT location
 

	
 
            if can_create_in_root and gr is None:
 
                # we can create in root, we're fine no validations required
 
                return
 

	
 
@@ -562,13 +562,13 @@ def ValidPerms(type_='repo'):
 
            for k, v in value.items():
 
                if k.startswith('u_perm_') or k.startswith('g_perm_'):
 
                    member_name = k[7:]
 
                    t = {'u': 'user',
 
                         'g': 'users_group'
 
                    }[k[0]]
 
                    if member_name == User.DEFAULT_USER_NAME:
 
                    if member_name == db.User.DEFAULT_USER_NAME:
 
                        if asbool(value.get('repo_private')):
 
                            # set none for default when updating to
 
                            # private repo protects against form manipulation
 
                            v = EMPTY_PERM
 
                    perms_update.add((member_name, v, t))
 

	
 
@@ -576,19 +576,19 @@ def ValidPerms(type_='repo'):
 
            value['perms_new'] = list(perms_new)
 

	
 
            # update permissions
 
            for k, v, t in perms_new:
 
                try:
 
                    if t == 'user':
 
                        _user_db = User.query() \
 
                            .filter(User.active == True) \
 
                            .filter(User.username == k).one()
 
                        _user_db = db.User.query() \
 
                            .filter(db.User.active == True) \
 
                            .filter(db.User.username == k).one()
 
                    if t == 'users_group':
 
                        _user_db = UserGroup.query() \
 
                            .filter(UserGroup.users_group_active == True) \
 
                            .filter(UserGroup.users_group_name == k).one()
 
                        _user_db = db.UserGroup.query() \
 
                            .filter(db.UserGroup.users_group_active == True) \
 
                            .filter(db.UserGroup.users_group_name == k).one()
 

	
 
                except Exception as e:
 
                    log.warning('Error validating %s permission %s', t, k)
 
                    msg = self.message('perm_new_member_type', state)
 
                    raise formencode.Invalid(msg, value, state,
 
                        error_dict=dict(perm_new_member_name=msg)
 
@@ -644,13 +644,13 @@ def UniqSystemEmail(old_data=None):
 

	
 
        def _convert_to_python(self, value, state):
 
            return value.lower()
 

	
 
        def _validate_python(self, value, state):
 
            if (old_data.get('email') or '').lower() != value:
 
                user = User.get_by_email(value)
 
                user = db.User.get_by_email(value)
 
                if user is not None:
 
                    msg = self.message('email_taken', state)
 
                    raise formencode.Invalid(msg, value, state,
 
                        error_dict=dict(email=msg)
 
                    )
 
    return _validator
 
@@ -663,13 +663,13 @@ def ValidSystemEmail():
 
        }
 

	
 
        def _convert_to_python(self, value, state):
 
            return value.lower()
 

	
 
        def _validate_python(self, value, state):
 
            user = User.get_by_email(value)
 
            user = db.User.get_by_email(value)
 
            if user is None:
 
                msg = self.message('non_existing_email', state, email=value)
 
                raise formencode.Invalid(msg, value, state,
 
                    error_dict=dict(email=msg)
 
                )
 

	
kallithea/tests/api/api_base.py
Show inline comments
 
@@ -23,15 +23,14 @@ import re
 
import mock
 
import pytest
 

	
 
from kallithea.lib import ext_json
 
from kallithea.lib.auth import AuthUser
 
from kallithea.lib.utils2 import ascii_bytes
 
from kallithea.model import meta
 
from kallithea.model import db, meta
 
from kallithea.model.changeset_status import ChangesetStatusModel
 
from kallithea.model.db import ChangesetStatus, PullRequest, PullRequestReviewer, RepoGroup, Repository, Setting, Ui, User
 
from kallithea.model.gist import GistModel
 
from kallithea.model.pull_request import PullRequestModel
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.repo_group import RepoGroupModel
 
from kallithea.model.scm import ScmModel
 
from kallithea.model.user import UserModel
 
@@ -88,13 +87,13 @@ def make_repo_group(name=TEST_REPO_GROUP
 
class _BaseTestApi(object):
 
    REPO = None
 
    REPO_TYPE = None
 

	
 
    @classmethod
 
    def setup_class(cls):
 
        cls.usr = User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        cls.usr = db.User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        cls.apikey = cls.usr.api_key
 
        cls.test_user = UserModel().create_or_update(
 
            username='test-api',
 
            password='test',
 
            email='test@example.com',
 
            firstname='first',
 
@@ -190,26 +189,26 @@ class _BaseTestApi(object):
 
        self._compare_ok(id_, expected, response.body)
 

	
 
    def test_api_get_users(self):
 
        id_, params = _build_data(self.apikey, 'get_users', )
 
        response = api_call(self, params)
 
        ret_all = []
 
        _users = User.query().filter_by(is_default_user=False) \
 
            .order_by(User.username).all()
 
        _users = db.User.query().filter_by(is_default_user=False) \
 
            .order_by(db.User.username).all()
 
        for usr in _users:
 
            ret = usr.get_api_data()
 
            ret_all.append(jsonify(ret))
 
        expected = ret_all
 
        self._compare_ok(id_, expected, given=response.body)
 

	
 
    def test_api_get_user(self):
 
        id_, params = _build_data(self.apikey, 'get_user',
 
                                  userid=base.TEST_USER_ADMIN_LOGIN)
 
        response = api_call(self, params)
 

	
 
        usr = User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        usr = db.User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        ret = usr.get_api_data()
 
        ret['permissions'] = AuthUser(dbuser=usr).permissions
 

	
 
        expected = ret
 
        self._compare_ok(id_, expected, given=response.body)
 

	
 
@@ -222,24 +221,24 @@ class _BaseTestApi(object):
 
        self._compare_error(id_, expected, given=response.body)
 

	
 
    def test_api_get_user_without_giving_userid(self):
 
        id_, params = _build_data(self.apikey, 'get_user')
 
        response = api_call(self, params)
 

	
 
        usr = User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        usr = db.User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        ret = usr.get_api_data()
 
        ret['permissions'] = AuthUser(dbuser=usr).permissions
 

	
 
        expected = ret
 
        self._compare_ok(id_, expected, given=response.body)
 

	
 
    def test_api_get_user_without_giving_userid_non_admin(self):
 
        id_, params = _build_data(self.apikey_regular, 'get_user')
 
        response = api_call(self, params)
 

	
 
        usr = User.get_by_username(self.TEST_USER_LOGIN)
 
        usr = db.User.get_by_username(self.TEST_USER_LOGIN)
 
        ret = usr.get_api_data()
 
        ret['permissions'] = AuthUser(dbuser=usr).permissions
 

	
 
        expected = ret
 
        self._compare_ok(id_, expected, given=response.body)
 

	
 
@@ -255,26 +254,26 @@ class _BaseTestApi(object):
 
        # Note: pulling from local repos is a mis-feature - it will bypass access control
 
        # ... but ok, if the path already has been set in the database
 
        repo_name = 'test_pull'
 
        r = fixture.create_repo(repo_name, repo_type=self.REPO_TYPE)
 
        # hack around that clone_uri can't be set to to a local path
 
        # (as shown by test_api_create_repo_clone_uri_local)
 
        r.clone_uri = os.path.join(Ui.get_by_key('paths', '/').ui_value, self.REPO)
 
        r.clone_uri = os.path.join(db.Ui.get_by_key('paths', '/').ui_value, self.REPO)
 
        meta.Session().commit()
 

	
 
        pre_cached_tip = [repo.get_api_data()['last_changeset']['short_id'] for repo in Repository.query().filter(Repository.repo_name == repo_name)]
 
        pre_cached_tip = [repo.get_api_data()['last_changeset']['short_id'] for repo in db.Repository.query().filter(db.Repository.repo_name == repo_name)]
 

	
 
        id_, params = _build_data(self.apikey, 'pull',
 
                                  repoid=repo_name,)
 
        response = api_call(self, params)
 

	
 
        expected = {'msg': 'Pulled from `%s`' % repo_name,
 
                    'repository': repo_name}
 
        self._compare_ok(id_, expected, given=response.body)
 

	
 
        post_cached_tip = [repo.get_api_data()['last_changeset']['short_id'] for repo in Repository.query().filter(Repository.repo_name == repo_name)]
 
        post_cached_tip = [repo.get_api_data()['last_changeset']['short_id'] for repo in db.Repository.query().filter(db.Repository.repo_name == repo_name)]
 

	
 
        fixture.destroy_repo(repo_name)
 

	
 
        assert pre_cached_tip != post_cached_tip
 

	
 
    def test_api_pull_fork(self):
 
@@ -300,13 +299,13 @@ class _BaseTestApi(object):
 
        self._compare_error(id_, expected, given=response.body)
 

	
 
    def test_api_pull_custom_remote(self):
 
        repo_name = 'test_pull_custom_remote'
 
        fixture.create_repo(repo_name, repo_type=self.REPO_TYPE)
 

	
 
        custom_remote_path = os.path.join(Ui.get_by_key('paths', '/').ui_value, self.REPO)
 
        custom_remote_path = os.path.join(db.Ui.get_by_key('paths', '/').ui_value, self.REPO)
 

	
 
        id_, params = _build_data(self.apikey, 'pull',
 
                                  repoid=repo_name,
 
                                  clone_uri=custom_remote_path)
 
        response = api_call(self, params)
 

	
 
@@ -358,13 +357,13 @@ class _BaseTestApi(object):
 
        id_, params = _build_data(self.apikey, 'create_user',
 
                                  username=username,
 
                                  email=email,
 
                                  password='trololo')
 
        response = api_call(self, params)
 

	
 
        usr = User.get_by_username(username)
 
        usr = db.User.get_by_username(username)
 
        ret = dict(
 
            msg='created new user `%s`' % username,
 
            user=jsonify(usr.get_api_data())
 
        )
 

	
 
        try:
 
@@ -379,13 +378,13 @@ class _BaseTestApi(object):
 

	
 
        id_, params = _build_data(self.apikey, 'create_user',
 
                                  username=username,
 
                                  email=email)
 
        response = api_call(self, params)
 

	
 
        usr = User.get_by_username(username)
 
        usr = db.User.get_by_username(username)
 
        ret = dict(
 
            msg='created new user `%s`' % username,
 
            user=jsonify(usr.get_api_data())
 
        )
 
        try:
 
            expected = ret
 
@@ -399,13 +398,13 @@ class _BaseTestApi(object):
 

	
 
        id_, params = _build_data(self.apikey, 'create_user',
 
                                  username=username,
 
                                  email=email, extern_name='internal')
 
        response = api_call(self, params)
 

	
 
        usr = User.get_by_username(username)
 
        usr = db.User.get_by_username(username)
 
        ret = dict(
 
            msg='created new user `%s`' % username,
 
            user=jsonify(usr.get_api_data())
 
        )
 
        try:
 
            expected = ret
 
@@ -476,31 +475,31 @@ class _BaseTestApi(object):
 
        ('extern_name', None),
 
        ('active', False),
 
        ('active', True),
 
        ('password', 'newpass'),
 
    ])
 
    def test_api_update_user(self, name, expected):
 
        usr = User.get_by_username(self.TEST_USER_LOGIN)
 
        usr = db.User.get_by_username(self.TEST_USER_LOGIN)
 
        kw = {name: expected,
 
              'userid': usr.user_id}
 
        id_, params = _build_data(self.apikey, 'update_user', **kw)
 
        response = api_call(self, params)
 

	
 
        ret = {
 
            'msg': 'updated user ID:%s %s' % (
 
                usr.user_id, self.TEST_USER_LOGIN),
 
            'user': jsonify(User \
 
            'user': jsonify(db.User \
 
                .get_by_username(self.TEST_USER_LOGIN) \
 
                .get_api_data())
 
        }
 

	
 
        expected = ret
 
        self._compare_ok(id_, expected, given=response.body)
 

	
 
    def test_api_update_user_no_changed_params(self):
 
        usr = User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        usr = db.User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        ret = jsonify(usr.get_api_data())
 
        id_, params = _build_data(self.apikey, 'update_user',
 
                                  userid=base.TEST_USER_ADMIN_LOGIN)
 

	
 
        response = api_call(self, params)
 
        ret = {
 
@@ -509,13 +508,13 @@ class _BaseTestApi(object):
 
            'user': ret
 
        }
 
        expected = ret
 
        self._compare_ok(id_, expected, given=response.body)
 

	
 
    def test_api_update_user_by_user_id(self):
 
        usr = User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        usr = db.User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        ret = jsonify(usr.get_api_data())
 
        id_, params = _build_data(self.apikey, 'update_user',
 
                                  userid=usr.user_id)
 

	
 
        response = api_call(self, params)
 
        ret = {
 
@@ -524,23 +523,23 @@ class _BaseTestApi(object):
 
            'user': ret
 
        }
 
        expected = ret
 
        self._compare_ok(id_, expected, given=response.body)
 

	
 
    def test_api_update_user_default_user(self):
 
        usr = User.get_default_user()
 
        usr = db.User.get_default_user()
 
        id_, params = _build_data(self.apikey, 'update_user',
 
                                  userid=usr.user_id)
 

	
 
        response = api_call(self, params)
 
        expected = 'editing default user is forbidden'
 
        self._compare_error(id_, expected, given=response.body)
 

	
 
    @mock.patch.object(UserModel, 'update_user', raise_exception)
 
    def test_api_update_user_when_exception_happens(self):
 
        usr = User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        usr = db.User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        ret = jsonify(usr.get_api_data())
 
        id_, params = _build_data(self.apikey, 'update_user',
 
                                  userid=usr.user_id)
 

	
 
        response = api_call(self, params)
 
        ret = 'failed to update user `%s`' % usr.user_id
 
@@ -642,13 +641,13 @@ class _BaseTestApi(object):
 
            self._compare_ok(id_, expected, given=response.body)
 
        finally:
 
            RepoModel().revoke_user_permission(self.REPO, self.TEST_USER_LOGIN)
 

	
 
    def test_api_get_repo_by_non_admin_no_permission_to_repo(self):
 
        RepoModel().grant_user_permission(repo=self.REPO,
 
                                          user=User.DEFAULT_USER_NAME,
 
                                          user=db.User.DEFAULT_USER_NAME,
 
                                          perm='repository.none')
 
        try:
 
            RepoModel().grant_user_permission(repo=self.REPO,
 
                                              user=self.TEST_USER_LOGIN,
 
                                              perm='repository.none')
 

	
 
@@ -657,13 +656,13 @@ class _BaseTestApi(object):
 
            response = api_call(self, params)
 

	
 
            expected = 'repository `%s` does not exist' % (self.REPO)
 
            self._compare_error(id_, expected, given=response.body)
 
        finally:
 
            RepoModel().grant_user_permission(repo=self.REPO,
 
                                              user=User.DEFAULT_USER_NAME,
 
                                              user=db.User.DEFAULT_USER_NAME,
 
                                              perm='repository.read')
 

	
 
    def test_api_get_repo_that_doesn_not_exist(self):
 
        id_, params = _build_data(self.apikey, 'get_repo',
 
                                  repoid='no-such-repo')
 
        response = api_call(self, params)
 
@@ -675,13 +674,13 @@ class _BaseTestApi(object):
 
    def test_api_get_repos(self):
 
        id_, params = _build_data(self.apikey, 'get_repos')
 
        response = api_call(self, params)
 

	
 
        expected = jsonify([
 
            repo.get_api_data()
 
            for repo in Repository.query()
 
            for repo in db.Repository.query()
 
        ])
 

	
 
        self._compare_ok(id_, expected, given=response.body)
 

	
 
    def test_api_get_repos_non_admin(self):
 
        id_, params = _build_data(self.apikey_regular, 'get_repos')
 
@@ -872,13 +871,13 @@ class _BaseTestApi(object):
 

	
 
    def test_api_create_repo_in_repo_group_without_permission(self):
 
        repo_group_basename = 'api-repo-repo'
 
        repo_group_name = '%s/%s' % (TEST_REPO_GROUP, repo_group_basename)
 
        repo_name = '%s/api-repo' % repo_group_name
 

	
 
        top_group = RepoGroup.get_by_group_name(TEST_REPO_GROUP)
 
        top_group = db.RepoGroup.get_by_group_name(TEST_REPO_GROUP)
 
        assert top_group
 
        rg = fixture.create_repo_group(repo_group_basename, parent_group_id=top_group)
 
        meta.Session().commit()
 
        RepoGroupModel().grant_user_permission(repo_group_name,
 
                                               self.TEST_USER_LOGIN,
 
                                               'group.none')
 
@@ -1299,26 +1298,26 @@ class _BaseTestApi(object):
 
        expected = 'Only Kallithea admin can specify `owner` param'
 
        self._compare_error(id_, expected, given=response.body)
 
        fixture.destroy_repo(fork_name)
 

	
 
    def test_api_fork_repo_non_admin_no_permission_to_fork(self):
 
        RepoModel().grant_user_permission(repo=self.REPO,
 
                                          user=User.DEFAULT_USER_NAME,
 
                                          user=db.User.DEFAULT_USER_NAME,
 
                                          perm='repository.none')
 
        try:
 
            fork_name = 'api-repo-fork'
 
            id_, params = _build_data(self.apikey_regular, 'fork_repo',
 
                                      repoid=self.REPO,
 
                                      fork_name=fork_name,
 
            )
 
            response = api_call(self, params)
 
            expected = 'repository `%s` does not exist' % (self.REPO)
 
            self._compare_error(id_, expected, given=response.body)
 
        finally:
 
            RepoModel().grant_user_permission(repo=self.REPO,
 
                                              user=User.DEFAULT_USER_NAME,
 
                                              user=db.User.DEFAULT_USER_NAME,
 
                                              perm='repository.read')
 
            fixture.destroy_repo(fork_name)
 

	
 
    @base.parametrize('name,perm', [
 
        ('read', 'repository.read'),
 
        ('write', 'repository.write'),
 
@@ -2325,13 +2324,13 @@ class _BaseTestApi(object):
 
        }
 
        self._compare_ok(id_, expected, given=response.body)
 

	
 
    def test_api_get_server_info(self):
 
        id_, params = _build_data(self.apikey, 'get_server_info')
 
        response = api_call(self, params)
 
        expected = Setting.get_server_info()
 
        expected = db.Setting.get_server_info()
 
        self._compare_ok(id_, expected, given=response.body)
 

	
 
    def test_api_get_changesets(self):
 
        id_, params = _build_data(self.apikey, 'get_changesets',
 
                                  repoid=self.REPO, start=0, end=2)
 
        response = api_call(self, params)
 
@@ -2426,13 +2425,13 @@ class _BaseTestApi(object):
 
            "id": random_id,
 
            "api_key": self.apikey,
 
            "method": 'get_pullrequest',
 
            "args": {"pullrequest_id": pull_request_id},
 
        }))
 
        response = api_call(self, params)
 
        pullrequest = PullRequest().get(pull_request_id)
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        expected = {
 
            "status": "new",
 
            "pull_request_id": pull_request_id,
 
            "description": "No description",
 
            "url": "/%s/pull-request/%s/_/%s" % (self.REPO, pull_request_id, "stable"),
 
            "reviewers": [{"username": "test_regular"}],
 
@@ -2460,76 +2459,76 @@ class _BaseTestApi(object):
 
            "api_key": self.apikey,
 
            "method": "comment_pullrequest",
 
            "args": {"pull_request_id": pull_request_id, "close_pr": True},
 
        }))
 
        response = api_call(self, params)
 
        self._compare_ok(random_id, True, given=response.body)
 
        pullrequest = PullRequest().get(pull_request_id)
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        assert pullrequest.comments[-1].text == ''
 
        assert pullrequest.status == PullRequest.STATUS_CLOSED
 
        assert pullrequest.status == db.PullRequest.STATUS_CLOSED
 
        assert pullrequest.is_closed() == True
 

	
 
    def test_api_status_pullrequest(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, "status test")
 

	
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": User.get_by_username(base.TEST_USER_REGULAR2_LOGIN).api_key,
 
            "api_key": db.User.get_by_username(base.TEST_USER_REGULAR2_LOGIN).api_key,
 
            "method": "comment_pullrequest",
 
            "args": {"pull_request_id": pull_request_id, "status": ChangesetStatus.STATUS_APPROVED},
 
            "args": {"pull_request_id": pull_request_id, "status": db.ChangesetStatus.STATUS_APPROVED},
 
        }))
 
        response = api_call(self, params)
 
        pullrequest = PullRequest().get(pull_request_id)
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        self._compare_error(random_id, "No permission to change pull request status. User needs to be admin, owner or reviewer.", given=response.body)
 
        assert ChangesetStatus.STATUS_UNDER_REVIEW == ChangesetStatusModel().calculate_pull_request_result(pullrequest)[2]
 
        assert db.ChangesetStatus.STATUS_UNDER_REVIEW == ChangesetStatusModel().calculate_pull_request_result(pullrequest)[2]
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": User.get_by_username(base.TEST_USER_REGULAR_LOGIN).api_key,
 
            "api_key": db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN).api_key,
 
            "method": "comment_pullrequest",
 
            "args": {"pull_request_id": pull_request_id, "status": ChangesetStatus.STATUS_APPROVED},
 
            "args": {"pull_request_id": pull_request_id, "status": db.ChangesetStatus.STATUS_APPROVED},
 
        }))
 
        response = api_call(self, params)
 
        self._compare_ok(random_id, True, given=response.body)
 
        pullrequest = PullRequest().get(pull_request_id)
 
        assert ChangesetStatus.STATUS_APPROVED == ChangesetStatusModel().calculate_pull_request_result(pullrequest)[2]
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        assert db.ChangesetStatus.STATUS_APPROVED == ChangesetStatusModel().calculate_pull_request_result(pullrequest)[2]
 

	
 
    def test_api_comment_pullrequest(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, "comment test")
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": self.apikey,
 
            "method": "comment_pullrequest",
 
            "args": {"pull_request_id": pull_request_id, "comment_msg": "Looks good to me"},
 
        }))
 
        response = api_call(self, params)
 
        self._compare_ok(random_id, True, given=response.body)
 
        pullrequest = PullRequest().get(pull_request_id)
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        assert pullrequest.comments[-1].text == 'Looks good to me'
 

	
 
    def test_api_edit_reviewers_add_single(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, 'edit reviewer test')
 
        pullrequest = PullRequest().get(pull_request_id)
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        pullrequest.owner = self.test_user
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": self.apikey_regular,
 
            "method": "edit_reviewers",
 
            "args": {"pull_request_id": pull_request_id, "add": base.TEST_USER_REGULAR2_LOGIN},
 
        }))
 
        response = api_call(self, params)
 
        expected = { 'added': [base.TEST_USER_REGULAR2_LOGIN], 'already_present': [], 'removed': [] }
 

	
 
        self._compare_ok(random_id, expected, given=response.body)
 
        assert User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) in pullrequest.get_reviewer_users()
 

	
 
    def test_api_edit_reviewers_add_nonexistent(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, 'edit reviewer test')
 
        pullrequest = PullRequest().get(pull_request_id)
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        pullrequest.owner = self.test_user
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": self.apikey_regular,
 
            "method": "edit_reviewers",
 
@@ -2538,13 +2537,13 @@ class _BaseTestApi(object):
 
        response = api_call(self, params)
 

	
 
        self._compare_error(random_id, "user `999` does not exist", given=response.body)
 

	
 
    def test_api_edit_reviewers_add_multiple(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, 'edit reviewer test')
 
        pullrequest = PullRequest().get(pull_request_id)
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        pullrequest.owner = self.test_user
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": self.apikey_regular,
 
            "method": "edit_reviewers",
 
@@ -2556,18 +2555,18 @@ class _BaseTestApi(object):
 
        response = api_call(self, params)
 
        # list order depends on python sorting hash, which is randomized
 
        assert set(ext_json.loads(response.body)['result']['added']) == set([base.TEST_USER_REGULAR2_LOGIN, self.TEST_USER_LOGIN])
 
        assert set(ext_json.loads(response.body)['result']['already_present']) == set()
 
        assert set(ext_json.loads(response.body)['result']['removed']) == set()
 

	
 
        assert User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) in pullrequest.get_reviewer_users()
 
        assert User.get_by_username(self.TEST_USER_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(self.TEST_USER_LOGIN) in pullrequest.get_reviewer_users()
 

	
 
    def test_api_edit_reviewers_add_already_present(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, 'edit reviewer test')
 
        pullrequest = PullRequest().get(pull_request_id)
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        pullrequest.owner = self.test_user
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": self.apikey_regular,
 
            "method": "edit_reviewers",
 
@@ -2580,18 +2579,18 @@ class _BaseTestApi(object):
 
        expected = { 'added': [base.TEST_USER_REGULAR2_LOGIN],
 
                     'already_present': [base.TEST_USER_REGULAR_LOGIN],
 
                     'removed': [],
 
                   }
 

	
 
        self._compare_ok(random_id, expected, given=response.body)
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        assert User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) in pullrequest.get_reviewer_users()
 

	
 
    def test_api_edit_reviewers_add_closed(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, 'edit reviewer test')
 
        pullrequest = PullRequest().get(pull_request_id)
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        pullrequest.owner = self.test_user
 
        PullRequestModel().close_pull_request(pull_request_id)
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": self.apikey_regular,
 
@@ -2600,14 +2599,14 @@ class _BaseTestApi(object):
 
        }))
 
        response = api_call(self, params)
 
        self._compare_error(random_id, "Cannot edit reviewers of a closed pull request.", given=response.body)
 

	
 
    def test_api_edit_reviewers_add_not_owner(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, 'edit reviewer test')
 
        pullrequest = PullRequest().get(pull_request_id)
 
        pullrequest.owner = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        pullrequest.owner = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": self.apikey_regular,
 
            "method": "edit_reviewers",
 
            "args": {"pull_request_id": pull_request_id, "add": base.TEST_USER_REGULAR2_LOGIN},
 
@@ -2615,14 +2614,14 @@ class _BaseTestApi(object):
 
        response = api_call(self, params)
 
        self._compare_error(random_id, "No permission to edit reviewers of this pull request. User needs to be admin or pull request owner.", given=response.body)
 

	
 

	
 
    def test_api_edit_reviewers_remove_single(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, 'edit reviewer test')
 
        pullrequest = PullRequest().get(pull_request_id)
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 

	
 
        pullrequest.owner = self.test_user
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": self.apikey_regular,
 
@@ -2633,37 +2632,37 @@ class _BaseTestApi(object):
 

	
 
        expected = { 'added': [],
 
                     'already_present': [],
 
                     'removed': [base.TEST_USER_REGULAR_LOGIN],
 
                   }
 
        self._compare_ok(random_id, expected, given=response.body)
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) not in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) not in pullrequest.get_reviewer_users()
 

	
 
    def test_api_edit_reviewers_remove_nonexistent(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, 'edit reviewer test')
 
        pullrequest = PullRequest().get(pull_request_id)
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 

	
 
        pullrequest.owner = self.test_user
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": self.apikey_regular,
 
            "method": "edit_reviewers",
 
            "args": {"pull_request_id": pull_request_id, "remove": 999},
 
        }))
 
        response = api_call(self, params)
 

	
 
        self._compare_error(random_id, "user `999` does not exist", given=response.body)
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 

	
 
    def test_api_edit_reviewers_remove_nonpresent(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, 'edit reviewer test')
 
        pullrequest = PullRequest().get(pull_request_id)
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        assert User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) not in pullrequest.get_reviewer_users()
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) not in pullrequest.get_reviewer_users()
 

	
 
        pullrequest.owner = self.test_user
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": self.apikey_regular,
 
@@ -2675,24 +2674,24 @@ class _BaseTestApi(object):
 
        # NOTE: no explicit indication that removed user was not even a reviewer
 
        expected = { 'added': [],
 
                     'already_present': [],
 
                     'removed': [base.TEST_USER_REGULAR2_LOGIN],
 
                   }
 
        self._compare_ok(random_id, expected, given=response.body)
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        assert User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) not in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) not in pullrequest.get_reviewer_users()
 

	
 
    def test_api_edit_reviewers_remove_multiple(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, 'edit reviewer test')
 
        pullrequest = PullRequest().get(pull_request_id)
 
        prr = PullRequestReviewer(User.get_by_username(base.TEST_USER_REGULAR2_LOGIN), pullrequest)
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        prr = db.PullRequestReviewer(db.User.get_by_username(base.TEST_USER_REGULAR2_LOGIN), pullrequest)
 
        meta.Session().add(prr)
 
        meta.Session().commit()
 

	
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        assert User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) in pullrequest.get_reviewer_users()
 

	
 
        pullrequest.owner = self.test_user
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": self.apikey_regular,
 
@@ -2702,19 +2701,19 @@ class _BaseTestApi(object):
 
        response = api_call(self, params)
 

	
 
        # list order depends on python sorting hash, which is randomized
 
        assert set(ext_json.loads(response.body)['result']['added']) == set()
 
        assert set(ext_json.loads(response.body)['result']['already_present']) == set()
 
        assert set(ext_json.loads(response.body)['result']['removed']) == set([base.TEST_USER_REGULAR_LOGIN, base.TEST_USER_REGULAR2_LOGIN])
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) not in pullrequest.get_reviewer_users()
 
        assert User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) not in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) not in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) not in pullrequest.get_reviewer_users()
 

	
 
    def test_api_edit_reviewers_remove_closed(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, 'edit reviewer test')
 
        pullrequest = PullRequest().get(pull_request_id)
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        PullRequestModel().close_pull_request(pull_request_id)
 

	
 
        pullrequest.owner = self.test_user
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
@@ -2722,37 +2721,37 @@ class _BaseTestApi(object):
 
            "method": "edit_reviewers",
 
            "args": {"pull_request_id": pull_request_id, "remove": base.TEST_USER_REGULAR_LOGIN},
 
        }))
 
        response = api_call(self, params)
 

	
 
        self._compare_error(random_id, "Cannot edit reviewers of a closed pull request.", given=response.body)
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 

	
 
    def test_api_edit_reviewers_remove_not_owner(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, 'edit reviewer test')
 
        pullrequest = PullRequest().get(pull_request_id)
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 

	
 
        pullrequest.owner = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 

	
 
        pullrequest.owner = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": self.apikey_regular,
 
            "method": "edit_reviewers",
 
            "args": {"pull_request_id": pull_request_id, "remove": base.TEST_USER_REGULAR_LOGIN},
 
        }))
 
        response = api_call(self, params)
 

	
 
        self._compare_error(random_id, "No permission to edit reviewers of this pull request. User needs to be admin or pull request owner.", given=response.body)
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 

	
 
    def test_api_edit_reviewers_add_remove_single(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, 'edit reviewer test')
 
        pullrequest = PullRequest().get(pull_request_id)
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        assert User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) not in pullrequest.get_reviewer_users()
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) not in pullrequest.get_reviewer_users()
 

	
 
        pullrequest.owner = self.test_user
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": self.apikey_regular,
 
@@ -2766,24 +2765,24 @@ class _BaseTestApi(object):
 

	
 
        expected = { 'added': [base.TEST_USER_REGULAR2_LOGIN],
 
                     'already_present': [],
 
                     'removed': [base.TEST_USER_REGULAR_LOGIN],
 
                   }
 
        self._compare_ok(random_id, expected, given=response.body)
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) not in pullrequest.get_reviewer_users()
 
        assert User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) not in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) in pullrequest.get_reviewer_users()
 

	
 
    def test_api_edit_reviewers_add_remove_multiple(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, 'edit reviewer test')
 
        pullrequest = PullRequest().get(pull_request_id)
 
        prr = PullRequestReviewer(User.get_by_username(base.TEST_USER_ADMIN_LOGIN), pullrequest)
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        prr = db.PullRequestReviewer(db.User.get_by_username(base.TEST_USER_ADMIN_LOGIN), pullrequest)
 
        meta.Session().add(prr)
 
        meta.Session().commit()
 
        assert User.get_by_username(base.TEST_USER_ADMIN_LOGIN) in pullrequest.get_reviewer_users()
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        assert User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) not in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_ADMIN_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) not in pullrequest.get_reviewer_users()
 

	
 
        pullrequest.owner = self.test_user
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": self.apikey_regular,
 
@@ -2796,22 +2795,22 @@ class _BaseTestApi(object):
 
        response = api_call(self, params)
 

	
 
        # list order depends on python sorting hash, which is randomized
 
        assert set(ext_json.loads(response.body)['result']['added']) == set([base.TEST_USER_REGULAR2_LOGIN])
 
        assert set(ext_json.loads(response.body)['result']['already_present']) == set()
 
        assert set(ext_json.loads(response.body)['result']['removed']) == set([base.TEST_USER_REGULAR_LOGIN, base.TEST_USER_ADMIN_LOGIN])
 
        assert User.get_by_username(base.TEST_USER_ADMIN_LOGIN) not in pullrequest.get_reviewer_users()
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) not in pullrequest.get_reviewer_users()
 
        assert User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_ADMIN_LOGIN) not in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) not in pullrequest.get_reviewer_users()
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR2_LOGIN) in pullrequest.get_reviewer_users()
 

	
 
    def test_api_edit_reviewers_invalid_params(self):
 
        pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, 'edit reviewer test')
 
        pullrequest = PullRequest().get(pull_request_id)
 
        assert User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 

	
 
        pullrequest.owner = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        pullrequest = db.PullRequest().get(pull_request_id)
 
        assert db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN) in pullrequest.get_reviewer_users()
 

	
 
        pullrequest.owner = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        random_id = random.randrange(1, 9999)
 
        params = ascii_bytes(ext_json.dumps({
 
            "id": random_id,
 
            "api_key": self.apikey_regular,
 
            "method": "edit_reviewers",
 
            "args": {"pull_request_id": pull_request_id},
kallithea/tests/base.py
Show inline comments
 
@@ -20,13 +20,13 @@ import tempfile
 
import time
 

	
 
import pytest
 
from webtest import TestApp
 

	
 
from kallithea.lib.utils2 import ascii_str
 
from kallithea.model.db import User
 
from kallithea.model import db
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 
skipif = pytest.mark.skipif
 
parametrize = pytest.mark.parametrize
 
@@ -163,18 +163,18 @@ class TestController(object):
 
        self.assert_authenticated_user(response, username)
 

	
 
        response = response.follow()
 
        return response.session['authuser']
 

	
 
    def _get_logged_user(self):
 
        return User.get_by_username(self._logged_username)
 
        return db.User.get_by_username(self._logged_username)
 

	
 
    def assert_authenticated_user(self, response, expected_username):
 
        cookie = response.session.get('authuser')
 
        user = cookie and cookie.get('user_id')
 
        user = user and User.get(user)
 
        user = user and db.User.get(user)
 
        user = user and user.username
 
        assert user == expected_username
 

	
 
    def session_csrf_secret_token(self):
 
        return ascii_str(self.app.get(url('session_csrf_secret_token')).body)
 

	
kallithea/tests/conftest.py
Show inline comments
 
@@ -12,14 +12,13 @@ from routes.util import URLGenerator
 
from tg.util.webtest import test_context
 

	
 
import kallithea.tests.base  # FIXME: needed for setting testapp instance!!!
 
from kallithea.controllers.root import RootController
 
from kallithea.lib import inifile
 
from kallithea.lib.utils import repo2db_mapper
 
from kallithea.model import meta
 
from kallithea.model.db import Setting, User, UserIpMap
 
from kallithea.model import db, meta
 
from kallithea.model.scm import ScmModel
 
from kallithea.model.user import UserModel
 
from kallithea.tests.base import TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS, TEST_USER_REGULAR_LOGIN, TESTS_TMP_PATH, invalidate_all_caches
 

	
 

	
 
def pytest_configure():
 
@@ -111,34 +110,34 @@ def _set_settings(*kvtseq):
 
    session = meta.Session()
 
    for kvt in kvtseq:
 
        assert len(kvt) in (2, 3)
 
        k = kvt[0]
 
        v = kvt[1]
 
        t = kvt[2] if len(kvt) == 3 else 'unicode'
 
        Setting.create_or_update(k, v, t)
 
        db.Setting.create_or_update(k, v, t)
 
    session.commit()
 

	
 

	
 
@pytest.fixture
 
def set_test_settings():
 
    """Restore settings after test is over."""
 
    # Save settings.
 
    settings_snapshot = [
 
        (s.app_settings_name, s.app_settings_value, s.app_settings_type)
 
        for s in Setting.query().all()]
 
        for s in db.Setting.query().all()]
 
    yield _set_settings
 
    # Restore settings.
 
    session = meta.Session()
 
    keys = frozenset(k for (k, v, t) in settings_snapshot)
 
    for s in Setting.query().all():
 
    for s in db.Setting.query().all():
 
        if s.app_settings_name not in keys:
 
            session.delete(s)
 
    for k, v, t in settings_snapshot:
 
        if t == 'list' and hasattr(v, '__iter__'):
 
            v = ','.join(v) # Quirk: must format list value manually.
 
        Setting.create_or_update(k, v, t)
 
        db.Setting.create_or_update(k, v, t)
 
    session.commit()
 

	
 

	
 
@pytest.fixture
 
def auto_clear_ip_permissions():
 
    """Fixture that provides nothing but clearing IP permissions upon test
 
@@ -147,16 +146,16 @@ def auto_clear_ip_permissions():
 
    yield
 
    # cleanup
 
    user_model = UserModel()
 

	
 
    user_ids = []
 
    user_ids.append(kallithea.DEFAULT_USER_ID)
 
    user_ids.append(User.get_by_username(TEST_USER_REGULAR_LOGIN).user_id)
 
    user_ids.append(db.User.get_by_username(TEST_USER_REGULAR_LOGIN).user_id)
 

	
 
    for user_id in user_ids:
 
        for ip in UserIpMap.query().filter(UserIpMap.user_id == user_id):
 
        for ip in db.UserIpMap.query().filter(db.UserIpMap.user_id == user_id):
 
            user_model.delete_extra_ip(user_id, ip.ip_id)
 

	
 
    # IP permissions are cached, need to invalidate this cache explicitly
 
    invalidate_all_caches()
 
    session = meta.Session()
 
    session.commit()
kallithea/tests/fixture.py
Show inline comments
 
@@ -27,16 +27,15 @@ from tg import request
 
from tg.util.webtest import test_context
 

	
 
from kallithea.lib import helpers
 
from kallithea.lib.auth import AuthUser
 
from kallithea.lib.db_manage import DbManage
 
from kallithea.lib.vcs.backends.base import EmptyChangeset
 
from kallithea.model import meta
 
from kallithea.model import db, meta
 
from kallithea.model.changeset_status import ChangesetStatusModel
 
from kallithea.model.comment import ChangesetCommentsModel
 
from kallithea.model.db import ChangesetStatus, Gist, RepoGroup, Repository, User, UserGroup
 
from kallithea.model.gist import GistModel
 
from kallithea.model.pull_request import CreatePullRequestAction  # , CreatePullRequestIterationAction, PullRequestModel
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.repo_group import RepoGroupModel
 
from kallithea.model.scm import ScmModel
 
from kallithea.model.user import UserModel
 
@@ -71,20 +70,20 @@ class Fixture(object):
 
        with fixture.anon_access(False):
 
            stuff
 
        """
 

	
 
        class context(object):
 
            def __enter__(self):
 
                anon = User.get_default_user()
 
                anon = db.User.get_default_user()
 
                self._before = anon.active
 
                anon.active = status
 
                meta.Session().commit()
 
                invalidate_all_caches()
 

	
 
            def __exit__(self, exc_type, exc_val, exc_tb):
 
                anon = User.get_default_user()
 
                anon = db.User.get_default_user()
 
                anon.active = self._before
 
                meta.Session().commit()
 

	
 
        return context()
 

	
 
    def _get_repo_create_params(self, **custom):
 
@@ -95,13 +94,13 @@ class Fixture(object):
 
            clone_uri='',
 
            repo_group='-1',
 
            repo_description='DESC',
 
            repo_private=False,
 
            repo_landing_rev='rev:tip',
 
            repo_copy_permissions=False,
 
            repo_state=Repository.STATE_CREATED,
 
            repo_state=db.Repository.STATE_CREATED,
 
        )
 
        defs.update(custom)
 
        if 'repo_name_full' not in custom:
 
            defs.update({'repo_name_full': defs['repo_name']})
 

	
 
        # fix the repo name if passed as repo_name_full
 
@@ -151,29 +150,29 @@ class Fixture(object):
 

	
 
        return defs
 

	
 
    def create_repo(self, name, repo_group=None, **kwargs):
 
        if 'skip_if_exists' in kwargs:
 
            del kwargs['skip_if_exists']
 
            r = Repository.get_by_repo_name(name)
 
            r = db.Repository.get_by_repo_name(name)
 
            if r:
 
                return r
 

	
 
        if isinstance(repo_group, RepoGroup):
 
        if isinstance(repo_group, db.RepoGroup):
 
            repo_group = repo_group.group_id
 

	
 
        form_data = self._get_repo_create_params(repo_name=name, **kwargs)
 
        form_data['repo_group'] = repo_group # patch form dict so it can be used directly by model
 
        cur_user = kwargs.get('cur_user', TEST_USER_ADMIN_LOGIN)
 
        RepoModel().create(form_data, cur_user)
 
        meta.Session().commit()
 
        ScmModel().mark_for_invalidation(name)
 
        return Repository.get_by_repo_name(name)
 
        return db.Repository.get_by_repo_name(name)
 

	
 
    def create_fork(self, repo_to_fork, fork_name, **kwargs):
 
        repo_to_fork = Repository.get_by_repo_name(repo_to_fork)
 
        repo_to_fork = db.Repository.get_by_repo_name(repo_to_fork)
 

	
 
        form_data = self._get_repo_create_params(repo_name=fork_name,
 
                                            fork_parent_id=repo_to_fork,
 
                                            repo_type=repo_to_fork.repo_type,
 
                                            **kwargs)
 
        # patch form dict so it can be used directly by model
 
@@ -182,84 +181,84 @@ class Fixture(object):
 
        form_data['landing_rev'] = form_data['repo_landing_rev']
 

	
 
        owner = kwargs.get('cur_user', TEST_USER_ADMIN_LOGIN)
 
        RepoModel().create_fork(form_data, cur_user=owner)
 
        meta.Session().commit()
 
        ScmModel().mark_for_invalidation(fork_name)
 
        r = Repository.get_by_repo_name(fork_name)
 
        r = db.Repository.get_by_repo_name(fork_name)
 
        assert r
 
        return r
 

	
 
    def destroy_repo(self, repo_name, **kwargs):
 
        RepoModel().delete(repo_name, **kwargs)
 
        meta.Session().commit()
 

	
 
    def create_repo_group(self, name, parent_group_id=None, **kwargs):
 
        assert '/' not in name, (name, kwargs) # use group_parent_id to make nested groups
 
        if 'skip_if_exists' in kwargs:
 
            del kwargs['skip_if_exists']
 
            gr = RepoGroup.get_by_group_name(group_name=name)
 
            gr = db.RepoGroup.get_by_group_name(group_name=name)
 
            if gr:
 
                return gr
 
        form_data = self._get_repo_group_create_params(group_name=name, **kwargs)
 
        gr = RepoGroupModel().create(
 
            group_name=form_data['group_name'],
 
            group_description=form_data['group_name'],
 
            parent=parent_group_id,
 
            owner=kwargs.get('cur_user', TEST_USER_ADMIN_LOGIN),
 
            )
 
        meta.Session().commit()
 
        gr = RepoGroup.get_by_group_name(gr.group_name)
 
        gr = db.RepoGroup.get_by_group_name(gr.group_name)
 
        return gr
 

	
 
    def destroy_repo_group(self, repogroupid):
 
        RepoGroupModel().delete(repogroupid)
 
        meta.Session().commit()
 

	
 
    def create_user(self, name, **kwargs):
 
        if 'skip_if_exists' in kwargs:
 
            del kwargs['skip_if_exists']
 
            user = User.get_by_username(name)
 
            user = db.User.get_by_username(name)
 
            if user:
 
                return user
 
        form_data = self._get_user_create_params(name, **kwargs)
 
        user = UserModel().create(form_data)
 
        meta.Session().commit()
 
        user = User.get_by_username(user.username)
 
        user = db.User.get_by_username(user.username)
 
        return user
 

	
 
    def destroy_user(self, userid):
 
        UserModel().delete(userid)
 
        meta.Session().commit()
 

	
 
    def create_user_group(self, name, **kwargs):
 
        if 'skip_if_exists' in kwargs:
 
            del kwargs['skip_if_exists']
 
            gr = UserGroup.get_by_group_name(group_name=name)
 
            gr = db.UserGroup.get_by_group_name(group_name=name)
 
            if gr:
 
                return gr
 
        form_data = self._get_user_group_create_params(name, **kwargs)
 
        owner = kwargs.get('cur_user', TEST_USER_ADMIN_LOGIN)
 
        user_group = UserGroupModel().create(
 
            name=form_data['users_group_name'],
 
            description=form_data['user_group_description'],
 
            owner=owner, active=form_data['users_group_active'],
 
            group_data=form_data['user_group_data'])
 
        meta.Session().commit()
 
        user_group = UserGroup.get_by_group_name(user_group.users_group_name)
 
        user_group = db.UserGroup.get_by_group_name(user_group.users_group_name)
 
        return user_group
 

	
 
    def destroy_user_group(self, usergroupid):
 
        UserGroupModel().delete(user_group=usergroupid, force=True)
 
        meta.Session().commit()
 

	
 
    def create_gist(self, **kwargs):
 
        form_data = {
 
            'description': 'new-gist',
 
            'owner': TEST_USER_ADMIN_LOGIN,
 
            'gist_type': Gist.GIST_PUBLIC,
 
            'gist_type': db.Gist.GIST_PUBLIC,
 
            'lifetime': -1,
 
            'gist_mapping': {'filename1.txt': {'content': 'hello world'}}
 
        }
 
        form_data.update(kwargs)
 
        gist = GistModel().create(
 
            description=form_data['description'], owner=form_data['owner'], ip_addr=IP_ADDR,
 
@@ -268,13 +267,13 @@ class Fixture(object):
 
        )
 
        meta.Session().commit()
 

	
 
        return gist
 

	
 
    def destroy_gists(self, gistid=None):
 
        for g in Gist.query():
 
        for g in db.Gist.query():
 
            if gistid:
 
                if gistid == g.gist_access_id:
 
                    GistModel().delete(g)
 
            else:
 
                GistModel().delete(g)
 
        meta.Session().commit()
 
@@ -286,13 +285,13 @@ class Fixture(object):
 
                source = source.strip()
 

	
 
        return source
 

	
 
    def commit_change(self, repo, filename, content, message, vcs_type,
 
                      parent=None, newfile=False, author=None):
 
        repo = Repository.get_by_repo_name(repo)
 
        repo = db.Repository.get_by_repo_name(repo)
 
        _cs = parent
 
        if parent is None:
 
            _cs = EmptyChangeset(alias=vcs_type)
 
        if author is None:
 
            author = '%s <%s>' % (TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_EMAIL)
 

	
 
@@ -323,23 +322,23 @@ class Fixture(object):
 
                f_path=filename
 
            )
 
        return cs
 

	
 
    def review_changeset(self, repo, revision, status, author=TEST_USER_ADMIN_LOGIN):
 
        comment = ChangesetCommentsModel().create("review comment", repo, author, revision=revision, send_email=False)
 
        csm = ChangesetStatusModel().set_status(repo, ChangesetStatus.STATUS_APPROVED, author, comment, revision=revision)
 
        csm = ChangesetStatusModel().set_status(repo, db.ChangesetStatus.STATUS_APPROVED, author, comment, revision=revision)
 
        meta.Session().commit()
 
        return csm
 

	
 
    def create_pullrequest(self, testcontroller, repo_name, pr_src_rev, pr_dst_rev, title='title'):
 
        org_ref = 'branch:stable:%s' % pr_src_rev
 
        other_ref = 'branch:default:%s' % pr_dst_rev
 
        with test_context(testcontroller.app): # needed to be able to mock request user
 
            org_repo = other_repo = Repository.get_by_repo_name(repo_name)
 
            owner_user = User.get_by_username(TEST_USER_ADMIN_LOGIN)
 
            reviewers = [User.get_by_username(TEST_USER_REGULAR_LOGIN)]
 
            org_repo = other_repo = db.Repository.get_by_repo_name(repo_name)
 
            owner_user = db.User.get_by_username(TEST_USER_ADMIN_LOGIN)
 
            reviewers = [db.User.get_by_username(TEST_USER_REGULAR_LOGIN)]
 
            request.authuser = AuthUser(dbuser=owner_user)
 
            # creating a PR sends a message with an absolute URL - without routing that requires mocking
 
            with mock.patch.object(helpers, 'url', (lambda arg, qualified=False, **kwargs: ('https://localhost' if qualified else '') + '/fake/' + arg)):
 
                cmd = CreatePullRequestAction(org_repo, other_repo, org_ref, other_ref, title, 'No description', owner_user, reviewers)
 
                pull_request = cmd.execute()
 
            meta.Session().commit()
kallithea/tests/functional/test_admin.py
Show inline comments
 
import csv
 
import datetime
 
import os
 
from os.path import dirname
 

	
 
from kallithea.model import meta
 
from kallithea.model.db import UserLog
 
from kallithea.model import db, meta
 
from kallithea.tests import base
 

	
 

	
 
FIXTURES = os.path.join(dirname(dirname(os.path.abspath(__file__))), 'fixtures')
 

	
 

	
 
class TestAdminController(base.TestController):
 

	
 
    @classmethod
 
    def setup_class(cls):
 
        UserLog.query().delete()
 
        db.UserLog.query().delete()
 
        meta.Session().commit()
 

	
 
        def strptime(val):
 
            fmt = '%Y-%m-%d %H:%M:%S'
 
            if '.' not in val:
 
                return datetime.datetime.strptime(val, fmt)
 
@@ -29,26 +28,26 @@ class TestAdminController(base.TestContr
 
            frag = frag[:6]  # truncate to microseconds
 
            frag += (6 - len(frag)) * '0'  # add 0s
 
            return date.replace(microsecond=int(frag))
 

	
 
        with open(os.path.join(FIXTURES, 'journal_dump.csv')) as f:
 
            for row in csv.DictReader(f):
 
                ul = UserLog()
 
                ul = db.UserLog()
 
                for k, v in row.items():
 
                    if k == 'action_date':
 
                        v = strptime(v)
 
                    if k in ['user_id', 'repository_id']:
 
                        # nullable due to FK problems
 
                        v = None
 
                    setattr(ul, k, v)
 
                meta.Session().add(ul)
 
            meta.Session().commit()
 

	
 
    @classmethod
 
    def teardown_class(cls):
 
        UserLog.query().delete()
 
        db.UserLog.query().delete()
 
        meta.Session().commit()
 

	
 
    def test_index(self):
 
        self.log_user()
 
        response = self.app.get(base.url(controller='admin/admin', action='index'))
 
        response.mustcontain('Admin Journal')
kallithea/tests/functional/test_admin_auth_settings.py
Show inline comments
 
from kallithea.model.db import Setting
 
from kallithea.model import db
 
from kallithea.tests import base
 

	
 

	
 
class TestAuthSettingsController(base.TestController):
 
    def _enable_plugins(self, plugins_list):
 
        test_url = base.url(controller='admin/auth_settings',
 
@@ -44,13 +44,13 @@ class TestAuthSettingsController(base.Te
 
        test_url = base.url(controller='admin/auth_settings',
 
                       action='auth_settings')
 

	
 
        response = self.app.post(url=test_url, params=params)
 
        self.checkSessionFlash(response, 'Auth settings updated successfully')
 

	
 
        new_settings = Setting.get_auth_settings()
 
        new_settings = db.Setting.get_auth_settings()
 
        assert new_settings['auth_ldap_host'] == 'dc.example.com', 'fail db write compare'
 

	
 
    @base.skipif(not base.ldap_lib_installed, reason='skipping due to missing ldap lib')
 
    def test_ldap_error_form_wrong_port_number(self):
 
        self.log_user()
 

	
 
@@ -235,13 +235,13 @@ class TestAuthSettingsController(base.Te
 
        test_url = base.url(controller='admin/auth_settings',
 
                       action='auth_settings')
 

	
 
        response = self.app.post(url=test_url, params=params)
 
        self.checkSessionFlash(response, 'Auth settings updated successfully')
 

	
 
        new_settings = Setting.get_auth_settings()
 
        new_settings = db.Setting.get_auth_settings()
 
        assert new_settings['auth_crowd_host'] == 'hostname', 'fail db write compare'
 

	
 
    @base.skipif(not base.pam_lib_installed, reason='skipping due to missing pam lib')
 
    def test_pam_save_settings(self):
 
        self.log_user()
 

	
 
@@ -252,8 +252,8 @@ class TestAuthSettingsController(base.Te
 
        test_url = base.url(controller='admin/auth_settings',
 
                       action='auth_settings')
 

	
 
        response = self.app.post(url=test_url, params=params)
 
        self.checkSessionFlash(response, 'Auth settings updated successfully')
 

	
 
        new_settings = Setting.get_auth_settings()
 
        new_settings = db.Setting.get_auth_settings()
 
        assert new_settings['auth_pam_service'] == 'kallithea', 'fail db write compare'
kallithea/tests/functional/test_admin_defaults.py
Show inline comments
 
from kallithea.model.db import Setting
 
from kallithea.model import db
 
from kallithea.tests import base
 

	
 

	
 
class TestDefaultsController(base.TestController):
 

	
 
    def test_index(self):
 
@@ -21,13 +21,13 @@ class TestDefaultsController(base.TestCo
 
            '_session_csrf_secret_token': self.session_csrf_secret_token(),
 
        }
 
        response = self.app.post(base.url('defaults_update', id='default'), params=params)
 
        self.checkSessionFlash(response, 'Default settings updated successfully')
 

	
 
        params.pop('_session_csrf_secret_token')
 
        defs = Setting.get_default_repo_settings()
 
        defs = db.Setting.get_default_repo_settings()
 
        assert params == defs
 

	
 
    def test_update_params_false_git(self):
 
        self.log_user()
 
        params = {
 
            'default_repo_enable_downloads': False,
 
@@ -37,8 +37,8 @@ class TestDefaultsController(base.TestCo
 
            '_session_csrf_secret_token': self.session_csrf_secret_token(),
 
        }
 
        response = self.app.post(base.url('defaults_update', id='default'), params=params)
 
        self.checkSessionFlash(response, 'Default settings updated successfully')
 

	
 
        params.pop('_session_csrf_secret_token')
 
        defs = Setting.get_default_repo_settings()
 
        defs = db.Setting.get_default_repo_settings()
 
        assert params == defs
kallithea/tests/functional/test_admin_gists.py
Show inline comments
 
from kallithea.model import meta
 
from kallithea.model.db import Gist, User
 
from kallithea.model import db, meta
 
from kallithea.model.gist import GistModel
 
from kallithea.tests import base
 

	
 

	
 
def _create_gist(f_name, content='some gist', lifetime=-1,
 
                 description='gist-desc', gist_type='public',
 
                 owner=base.TEST_USER_ADMIN_LOGIN):
 
    gist_mapping = {
 
        f_name: {'content': content}
 
    }
 
    owner = User.get_by_username(owner)
 
    owner = db.User.get_by_username(owner)
 
    gist = GistModel().create(description, owner=owner, ip_addr=base.IP_ADDR,
 
                       gist_mapping=gist_mapping, gist_type=gist_type,
 
                       lifetime=lifetime)
 
    meta.Session().commit()
 
    return gist
 

	
 

	
 
class TestGistsController(base.TestController):
 

	
 
    def teardown_method(self, method):
 
        for g in Gist.query():
 
        for g in db.Gist.query():
 
            GistModel().delete(g)
 
        meta.Session().commit()
 

	
 
    def test_index(self):
 
        self.log_user()
 
        response = self.app.get(base.url('gists'))
kallithea/tests/functional/test_admin_permissions.py
Show inline comments
 
import kallithea
 
from kallithea.model.db import User, UserIpMap
 
from kallithea.model import db
 
from kallithea.tests import base
 

	
 

	
 
class TestAdminPermissionsController(base.TestController):
 

	
 
    def test_index(self):
 
@@ -43,24 +43,24 @@ class TestAdminPermissionsController(bas
 

	
 
        response = self.app.get(base.url('admin_permissions_ips'),
 
                                extra_environ={'REMOTE_ADDR': '0.0.1.1'})
 

	
 
        # Delete latest IP and verify same IP is rejected again
 

	
 
        x = UserIpMap.query().filter_by(ip_addr='0.0.1.0/24').first()
 
        x = db.UserIpMap.query().filter_by(ip_addr='0.0.1.0/24').first()
 
        response = self.app.post(base.url('edit_user_ips_delete', id=default_user_id),
 
                                 params=dict(del_ip_id=x.ip_id,
 
                                             _session_csrf_secret_token=self.session_csrf_secret_token()))
 
        base.invalidate_all_caches()
 

	
 
        response = self.app.get(base.url('admin_permissions_ips'),
 
                                extra_environ={'REMOTE_ADDR': '0.0.1.1'}, status=403)
 

	
 
        # Delete first IP and verify unlimited access again
 

	
 
        x = UserIpMap.query().filter_by(ip_addr='0.0.0.0/24').first()
 
        x = db.UserIpMap.query().filter_by(ip_addr='0.0.0.0/24').first()
 
        response = self.app.post(base.url('edit_user_ips_delete', id=default_user_id),
 
                                 params=dict(del_ip_id=x.ip_id,
 
                                             _session_csrf_secret_token=self.session_csrf_secret_token()))
 
        base.invalidate_all_caches()
 

	
 
        response = self.app.get(base.url('admin_permissions_ips'),
 
@@ -69,13 +69,13 @@ class TestAdminPermissionsController(bas
 
    def test_index_overview(self):
 
        self.log_user()
 
        response = self.app.get(base.url('admin_permissions_perms'))
 
        # Test response...
 

	
 
    def test_edit_permissions_permissions(self):
 
        user = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 

	
 
        # Test unauthenticated access - it will redirect to login page
 
        response = self.app.post(
 
            base.url('edit_repo_perms_update', repo_name=base.HG_REPO),
 
            params=dict(
 
                perm_new_member_1='repository.read',
kallithea/tests/functional/test_admin_repos.py
Show inline comments
 
@@ -5,29 +5,28 @@ import urllib.parse
 

	
 
import mock
 
import pytest
 

	
 
import kallithea
 
from kallithea.lib import vcs
 
from kallithea.model import meta
 
from kallithea.model.db import Permission, Repository, Ui, User, UserRepoToPerm
 
from kallithea.model import db, meta
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.repo_group import RepoGroupModel
 
from kallithea.model.user import UserModel
 
from kallithea.tests import base
 
from kallithea.tests.fixture import Fixture, raise_exception
 

	
 

	
 
fixture = Fixture()
 

	
 

	
 
def _get_permission_for_user(user, repo):
 
    perm = UserRepoToPerm.query() \
 
                .filter(UserRepoToPerm.repository ==
 
                        Repository.get_by_repo_name(repo)) \
 
                .filter(UserRepoToPerm.user == User.get_by_username(user)) \
 
    perm = db.UserRepoToPerm.query() \
 
                .filter(db.UserRepoToPerm.repository ==
 
                        db.Repository.get_by_repo_name(repo)) \
 
                .filter(db.UserRepoToPerm.user == db.User.get_by_username(user)) \
 
                .all()
 
    return perm
 

	
 

	
 
class _BaseTestCase(base.TestController):
 
    """
 
@@ -58,26 +57,26 @@ class _BaseTestCase(base.TestController)
 
        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 = meta.Session().query(Repository) \
 
            .filter(Repository.repo_name == repo_name).one()
 
        new_repo = meta.Session().query(db.Repository) \
 
            .filter(db.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))
 
            vcs.get_repo(os.path.join(db.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)
 
        meta.Session().commit()
 

	
 
@@ -128,31 +127,31 @@ class _BaseTestCase(base.TestController)
 
        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 = meta.Session().query(Repository) \
 
            .filter(Repository.repo_name == repo_name_full).one()
 
        new_repo = meta.Session().query(db.Repository) \
 
            .filter(db.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()
 
        inherited_perms = db.UserRepoToPerm.query() \
 
            .filter(db.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))
 
            vcs.get_repo(os.path.join(db.Ui.get_by_key('paths', '/').ui_value, repo_name_full))
 
        except vcs.exceptions.VCSError:
 
            RepoGroupModel().delete(group_name)
 
            meta.Session().commit()
 
            pytest.fail('no repo %s in filesystem' % repo_name)
 

	
 
        RepoModel().delete(repo_name_full)
 
@@ -163,16 +162,16 @@ class _BaseTestCase(base.TestController)
 
        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')
 
        user_model.revoke_perm(db.User.DEFAULT_USER_NAME, 'hg.create.repository')
 
        user_model.grant_perm(db.User.DEFAULT_USER_NAME, 'hg.create.none')
 
        user_model.revoke_perm(db.User.DEFAULT_USER_NAME, 'hg.fork.repository')
 
        user_model.grant_perm(db.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')
 
@@ -220,31 +219,31 @@ class _BaseTestCase(base.TestController)
 
        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 = meta.Session().query(Repository) \
 
            .filter(Repository.repo_name == repo_name_full).one()
 
        new_repo = meta.Session().query(db.Repository) \
 
            .filter(db.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()
 
        inherited_perms = db.UserRepoToPerm.query() \
 
            .filter(db.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))
 
            vcs.get_repo(os.path.join(db.Ui.get_by_key('paths', '/').ui_value, repo_name_full))
 
        except vcs.exceptions.VCSError:
 
            RepoGroupModel().delete(group_name)
 
            meta.Session().commit()
 
            pytest.fail('no repo %s in filesystem' % repo_name)
 

	
 
        RepoModel().delete(repo_name_full)
 
@@ -257,13 +256,13 @@ class _BaseTestCase(base.TestController)
 

	
 
        ## 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)
 
        perm = Permission.get_by_key('repository.write')
 
        perm = db.Permission.get_by_key('repository.write')
 
        RepoGroupModel().grant_user_permission(gr, base.TEST_USER_REGULAR_LOGIN, perm)
 

	
 
        ## add repo permissions
 
        meta.Session().commit()
 

	
 
        repo_name = 'ingroup_inherited_%s' % self.REPO_TYPE
 
@@ -281,35 +280,35 @@ class _BaseTestCase(base.TestController)
 
        ## run the check page that triggers the flash message
 
        response = self.app.get(base.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 = meta.Session().query(Repository) \
 
            .filter(Repository.repo_name == repo_name_full).one()
 
        new_repo = meta.Session().query(db.Repository) \
 
            .filter(db.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)
 

	
 
        # 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))
 
            vcs.get_repo(os.path.join(db.Ui.get_by_key('paths', '/').ui_value, repo_name_full))
 
        except vcs.exceptions.VCSError:
 
            RepoGroupModel().delete(group_name)
 
            meta.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()
 
        inherited_perms = db.UserRepoToPerm.query() \
 
            .filter(db.UserRepoToPerm.repository_id == new_repo_id).all()
 
        assert len(inherited_perms) == 2
 

	
 
        assert base.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]
 
@@ -370,43 +369,43 @@ class _BaseTestCase(base.TestController)
 
        ## run the check page that triggers the flash message
 
        response = self.app.get(base.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 = meta.Session().query(Repository) \
 
            .filter(Repository.repo_name == repo_name).one()
 
        new_repo = meta.Session().query(db.Repository) \
 
            .filter(db.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))
 
            vcs.get_repo(os.path.join(db.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 = meta.Session().query(Repository) \
 
            .filter(Repository.repo_name == repo_name).scalar()
 
        deleted_repo = meta.Session().query(db.Repository) \
 
            .filter(db.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
 
        assert os.path.isdir(os.path.join(db.Ui.get_by_key('paths', '/').ui_value, repo_name)) == False
 

	
 
    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
 
@@ -420,41 +419,41 @@ class _BaseTestCase(base.TestController)
 
        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 = meta.Session().query(Repository) \
 
            .filter(Repository.repo_name == repo_name).one()
 
        new_repo = meta.Session().query(db.Repository) \
 
            .filter(db.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))
 
            vcs.get_repo(os.path.join(db.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 = meta.Session().query(Repository) \
 
            .filter(Repository.repo_name == repo_name).scalar()
 
        deleted_repo = meta.Session().query(db.Repository) \
 
            .filter(db.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
 
        assert os.path.isdir(os.path.join(db.Ui.get_by_key('paths', '/').ui_value, repo_name)) == False
 

	
 
    def test_delete_repo_with_group(self):
 
        # TODO:
 
        pass
 

	
 
    def test_delete_browser_fakeout(self):
 
@@ -471,23 +470,23 @@ class _BaseTestCase(base.TestController)
 
    def test_set_private_flag_sets_default_to_none(self):
 
        self.log_user()
 
        # initially repository perm should be read
 
        perm = _get_permission_for_user(user='default', repo=self.REPO)
 
        assert len(perm), 1
 
        assert perm[0].permission.permission_name == 'repository.read'
 
        assert Repository.get_by_repo_name(self.REPO).private == False
 
        assert db.Repository.get_by_repo_name(self.REPO).private == False
 

	
 
        response = self.app.post(base.url('update_repo', repo_name=self.REPO),
 
                        fixture._get_repo_create_params(repo_private=1,
 
                                                repo_name=self.REPO,
 
                                                repo_type=self.REPO_TYPE,
 
                                                owner=base.TEST_USER_ADMIN_LOGIN,
 
                                                _session_csrf_secret_token=self.session_csrf_secret_token()))
 
        self.checkSessionFlash(response,
 
                               msg='Repository %s updated successfully' % (self.REPO))
 
        assert Repository.get_by_repo_name(self.REPO).private == True
 
        assert db.Repository.get_by_repo_name(self.REPO).private == True
 

	
 
        # now the repo default permission should be None
 
        perm = _get_permission_for_user(user='default', repo=self.REPO)
 
        assert len(perm), 1
 
        assert perm[0].permission.permission_name == 'repository.none'
 

	
 
@@ -496,40 +495,40 @@ class _BaseTestCase(base.TestController)
 
                                                repo_name=self.REPO,
 
                                                repo_type=self.REPO_TYPE,
 
                                                owner=base.TEST_USER_ADMIN_LOGIN,
 
                                                _session_csrf_secret_token=self.session_csrf_secret_token()))
 
        self.checkSessionFlash(response,
 
                               msg='Repository %s updated successfully' % (self.REPO))
 
        assert Repository.get_by_repo_name(self.REPO).private == False
 
        assert db.Repository.get_by_repo_name(self.REPO).private == False
 

	
 
        # we turn off private now the repo default permission should stay None
 
        perm = _get_permission_for_user(user='default', repo=self.REPO)
 
        assert len(perm), 1
 
        assert perm[0].permission.permission_name == 'repository.none'
 

	
 
        # update this permission back
 
        perm[0].permission = Permission.get_by_key('repository.read')
 
        perm[0].permission = db.Permission.get_by_key('repository.read')
 
        meta.Session().commit()
 

	
 
    def test_set_repo_fork_has_no_self_id(self):
 
        self.log_user()
 
        repo = Repository.get_by_repo_name(self.REPO)
 
        repo = db.Repository.get_by_repo_name(self.REPO)
 
        response = self.app.get(base.url('edit_repo_advanced', repo_name=self.REPO))
 
        opt = """<option value="%s">%s</option>""" % (repo.repo_id, self.REPO)
 
        response.mustcontain(no=[opt])
 

	
 
    def test_set_fork_of_other_repo(self):
 
        self.log_user()
 
        other_repo = 'other_%s' % self.REPO_TYPE
 
        fixture.create_repo(other_repo, repo_type=self.REPO_TYPE)
 
        repo = Repository.get_by_repo_name(self.REPO)
 
        repo2 = Repository.get_by_repo_name(other_repo)
 
        repo = db.Repository.get_by_repo_name(self.REPO)
 
        repo2 = db.Repository.get_by_repo_name(other_repo)
 
        response = self.app.post(base.url('edit_repo_advanced_fork', repo_name=self.REPO),
 
                                params=dict(id_fork_of=repo2.repo_id, _session_csrf_secret_token=self.session_csrf_secret_token()))
 
        repo = Repository.get_by_repo_name(self.REPO)
 
        repo2 = Repository.get_by_repo_name(other_repo)
 
        repo = db.Repository.get_by_repo_name(self.REPO)
 
        repo2 = db.Repository.get_by_repo_name(other_repo)
 
        self.checkSessionFlash(response,
 
            'Marked repository %s as fork of %s' % (repo.repo_name, repo2.repo_name))
 

	
 
        assert repo.fork == repo2
 
        response = response.follow()
 
        # check if given repo is selected
 
@@ -539,60 +538,60 @@ class _BaseTestCase(base.TestController)
 
        response.mustcontain(opt)
 

	
 
        fixture.destroy_repo(other_repo, forks='detach')
 

	
 
    def test_set_fork_of_other_type_repo(self):
 
        self.log_user()
 
        repo = Repository.get_by_repo_name(self.REPO)
 
        repo2 = Repository.get_by_repo_name(self.OTHER_TYPE_REPO)
 
        repo = db.Repository.get_by_repo_name(self.REPO)
 
        repo2 = db.Repository.get_by_repo_name(self.OTHER_TYPE_REPO)
 
        response = self.app.post(base.url('edit_repo_advanced_fork', repo_name=self.REPO),
 
                                params=dict(id_fork_of=repo2.repo_id, _session_csrf_secret_token=self.session_csrf_secret_token()))
 
        repo = Repository.get_by_repo_name(self.REPO)
 
        repo2 = Repository.get_by_repo_name(self.OTHER_TYPE_REPO)
 
        repo = db.Repository.get_by_repo_name(self.REPO)
 
        repo2 = db.Repository.get_by_repo_name(self.OTHER_TYPE_REPO)
 
        self.checkSessionFlash(response,
 
            'Cannot set repository as fork of repository with other type')
 

	
 
    def test_set_fork_of_none(self):
 
        self.log_user()
 
        ## mark it as None
 
        response = self.app.post(base.url('edit_repo_advanced_fork', repo_name=self.REPO),
 
                                params=dict(id_fork_of=None, _session_csrf_secret_token=self.session_csrf_secret_token()))
 
        repo = Repository.get_by_repo_name(self.REPO)
 
        repo2 = Repository.get_by_repo_name(self.OTHER_TYPE_REPO)
 
        repo = db.Repository.get_by_repo_name(self.REPO)
 
        repo2 = db.Repository.get_by_repo_name(self.OTHER_TYPE_REPO)
 
        self.checkSessionFlash(response,
 
                               'Marked repository %s as fork of %s'
 
                               % (repo.repo_name, "Nothing"))
 
        assert repo.fork is None
 

	
 
    def test_set_fork_of_same_repo(self):
 
        self.log_user()
 
        repo = Repository.get_by_repo_name(self.REPO)
 
        repo = db.Repository.get_by_repo_name(self.REPO)
 
        response = self.app.post(base.url('edit_repo_advanced_fork', repo_name=self.REPO),
 
                                params=dict(id_fork_of=repo.repo_id, _session_csrf_secret_token=self.session_csrf_secret_token()))
 
        self.checkSessionFlash(response,
 
                               'An error occurred during this operation')
 

	
 
    def test_create_on_top_level_without_permissions(self):
 
        usr = self.log_user(base.TEST_USER_REGULAR_LOGIN, base.TEST_USER_REGULAR_PASS)
 
        # 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')
 
        user_model.revoke_perm(db.User.DEFAULT_USER_NAME, 'hg.create.repository')
 
        user_model.grant_perm(db.User.DEFAULT_USER_NAME, 'hg.create.none')
 
        user_model.revoke_perm(db.User.DEFAULT_USER_NAME, 'hg.fork.repository')
 
        user_model.grant_perm(db.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')
 
        meta.Session().commit()
 

	
 

	
 
        user = User.get(usr['user_id'])
 
        user = db.User.get(usr['user_id'])
 

	
 
        repo_name = self.NEW_REPO + 'no_perms'
 
        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,
 
@@ -618,17 +617,17 @@ class _BaseTestCase(base.TestController)
 
                                                repo_description=description,
 
                                                _session_csrf_secret_token=self.session_csrf_secret_token()))
 

	
 
        self.checkSessionFlash(response,
 
                               'Error creating repository %s' % repo_name)
 
        # repo must not be in db
 
        repo = Repository.get_by_repo_name(repo_name)
 
        repo = db.Repository.get_by_repo_name(repo_name)
 
        assert repo is None
 

	
 
        # repo must not be in filesystem !
 
        assert not os.path.isdir(os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name))
 
        assert not os.path.isdir(os.path.join(db.Ui.get_by_key('paths', '/').ui_value, repo_name))
 

	
 

	
 
class TestAdminReposControllerGIT(_BaseTestCase):
 
    REPO = base.GIT_REPO
 
    REPO_TYPE = 'git'
 
    NEW_REPO = base.NEW_GIT_REPO
 
@@ -641,13 +640,13 @@ class TestAdminReposControllerHG(_BaseTe
 
    REPO_TYPE = 'hg'
 
    NEW_REPO = base.NEW_HG_REPO
 
    OTHER_TYPE_REPO = base.GIT_REPO
 
    OTHER_TYPE = 'git'
 

	
 
    def test_permanent_url_protocol_access(self):
 
        repo = Repository.get_by_repo_name(self.REPO)
 
        repo = db.Repository.get_by_repo_name(self.REPO)
 
        permanent_name = '_%d' % repo.repo_id
 

	
 
        # 400 Bad Request - Unable to detect pull/push action
 
        self.app.get(base.url('summary_home', repo_name=permanent_name),
 
            extra_environ={'HTTP_ACCEPT': 'application/mercurial'},
 
            status=400,
kallithea/tests/functional/test_admin_settings.py
Show inline comments
 
# -*- coding: utf-8 -*-
 

	
 
from kallithea.model.db import Setting, Ui
 
from kallithea.model import db
 
from kallithea.tests import base
 
from kallithea.tests.fixture import Fixture
 

	
 

	
 
fixture = Fixture()
 

	
 
@@ -77,13 +77,13 @@ class TestAdminSettingsController(base.T
 

	
 
        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
 
        hook_id = db.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])
 
@@ -121,13 +121,13 @@ class TestAdminSettingsController(base.T
 
                                 captcha_public_key='',
 
                                 _session_csrf_secret_token=self.session_csrf_secret_token(),
 
                                 ))
 

	
 
        self.checkSessionFlash(response, 'Updated application settings')
 

	
 
        assert Setting.get_app_settings()['ga_code'] == new_ga_code
 
        assert db.Setting.get_app_settings()['ga_code'] == new_ga_code
 

	
 
        response = response.follow()
 
        response.mustcontain("""_gaq.push(['_setAccount', '%s']);""" % new_ga_code)
 

	
 
    def test_ga_code_inactive(self):
 
        self.log_user()
 
@@ -141,13 +141,13 @@ class TestAdminSettingsController(base.T
 
                                 captcha_private_key='',
 
                                 captcha_public_key='',
 
                                 _session_csrf_secret_token=self.session_csrf_secret_token(),
 
                                 ))
 

	
 
        self.checkSessionFlash(response, 'Updated application settings')
 
        assert Setting.get_app_settings()['ga_code'] == new_ga_code
 
        assert db.Setting.get_app_settings()['ga_code'] == new_ga_code
 

	
 
        response = response.follow()
 
        response.mustcontain(no=["_gaq.push(['_setAccount', '%s']);" % new_ga_code])
 

	
 
    def test_captcha_activate(self):
 
        self.log_user()
 
@@ -161,13 +161,13 @@ class TestAdminSettingsController(base.T
 
                                 captcha_private_key='1234567890',
 
                                 captcha_public_key='1234567890',
 
                                 _session_csrf_secret_token=self.session_csrf_secret_token(),
 
                                 ))
 

	
 
        self.checkSessionFlash(response, 'Updated application settings')
 
        assert Setting.get_app_settings()['captcha_private_key'] == '1234567890'
 
        assert db.Setting.get_app_settings()['captcha_private_key'] == '1234567890'
 

	
 
        response = self.app.get(base.url('register'))
 
        response.mustcontain('captcha')
 

	
 
    def test_captcha_deactivate(self):
 
        self.log_user()
 
@@ -181,13 +181,13 @@ class TestAdminSettingsController(base.T
 
                                 captcha_private_key='',
 
                                 captcha_public_key='1234567890',
 
                                 _session_csrf_secret_token=self.session_csrf_secret_token(),
 
                                 ))
 

	
 
        self.checkSessionFlash(response, 'Updated application settings')
 
        assert Setting.get_app_settings()['captcha_private_key'] == ''
 
        assert db.Setting.get_app_settings()['captcha_private_key'] == ''
 

	
 
        response = self.app.get(base.url('register'))
 
        response.mustcontain(no=['captcha'])
 

	
 
    def test_title_change(self):
 
        self.log_user()
 
@@ -203,10 +203,10 @@ class TestAdminSettingsController(base.T
 
                                 captcha_private_key='',
 
                                 captcha_public_key='',
 
                                 _session_csrf_secret_token=self.session_csrf_secret_token(),
 
                                ))
 

	
 
            self.checkSessionFlash(response, 'Updated application settings')
 
            assert Setting.get_app_settings()['title'] == new_title
 
            assert db.Setting.get_app_settings()['title'] == new_title
 

	
 
            response = response.follow()
 
            response.mustcontain("""<span class="branding">%s</span>""" % new_title)
kallithea/tests/functional/test_admin_user_groups.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
from kallithea.model import meta
 
from kallithea.model.db import Permission, UserGroup, UserGroupToPerm
 
from kallithea.model import db, meta
 
from kallithea.tests import base
 

	
 

	
 
TEST_USER_GROUP = 'admins_test'
 

	
 

	
 
@@ -49,20 +48,20 @@ class TestAdminUsersGroupsController(bas
 
                                  '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        response.follow()
 

	
 
        self.checkSessionFlash(response,
 
                               'Created user group ')
 

	
 
        gr = meta.Session().query(UserGroup) \
 
            .filter(UserGroup.users_group_name == users_group_name).one()
 
        gr = meta.Session().query(db.UserGroup) \
 
            .filter(db.UserGroup.users_group_name == users_group_name).one()
 

	
 
        response = self.app.post(base.url('delete_users_group', id=gr.users_group_id),
 
            params={'_session_csrf_secret_token': self.session_csrf_secret_token()})
 

	
 
        gr = meta.Session().query(UserGroup) \
 
            .filter(UserGroup.users_group_name == users_group_name).scalar()
 
        gr = meta.Session().query(db.UserGroup) \
 
            .filter(db.UserGroup.users_group_name == users_group_name).scalar()
 

	
 
        assert gr is None
 

	
 
    def test_default_perms_enable_repository_read_on_group(self):
 
        self.log_user()
 
        users_group_name = TEST_USER_GROUP + 'another2'
 
@@ -70,67 +69,67 @@ class TestAdminUsersGroupsController(bas
 
                                 {'users_group_name': users_group_name,
 
                                  'user_group_description': 'DESC',
 
                                  'active': True,
 
                                  '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        response.follow()
 

	
 
        ug = UserGroup.get_by_group_name(users_group_name)
 
        ug = db.UserGroup.get_by_group_name(users_group_name)
 
        self.checkSessionFlash(response,
 
                               'Created user group ')
 
        ## ENABLE REPO CREATE ON A GROUP
 
        response = self.app.post(base.url('edit_user_group_default_perms_update',
 
                                     id=ug.users_group_id),
 
                                 {'create_repo_perm': True,
 
                                  '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        response.follow()
 
        ug = UserGroup.get_by_group_name(users_group_name)
 
        p = Permission.get_by_key('hg.create.repository')
 
        p2 = Permission.get_by_key('hg.usergroup.create.false')
 
        p3 = Permission.get_by_key('hg.fork.none')
 
        ug = db.UserGroup.get_by_group_name(users_group_name)
 
        p = db.Permission.get_by_key('hg.create.repository')
 
        p2 = db.Permission.get_by_key('hg.usergroup.create.false')
 
        p3 = db.Permission.get_by_key('hg.fork.none')
 
        # check if user has this perms, they should be here since
 
        # defaults are on
 
        perms = UserGroupToPerm.query() \
 
            .filter(UserGroupToPerm.users_group == ug).all()
 
        perms = db.UserGroupToPerm.query() \
 
            .filter(db.UserGroupToPerm.users_group == ug).all()
 

	
 
        assert sorted([[x.users_group_id, x.permission_id, ] for x in perms]) == sorted([[ug.users_group_id, p.permission_id],
 
                    [ug.users_group_id, p2.permission_id],
 
                    [ug.users_group_id, p3.permission_id]])
 

	
 
        ## DISABLE REPO CREATE ON A GROUP
 
        response = self.app.post(
 
            base.url('edit_user_group_default_perms_update', id=ug.users_group_id),
 
            params={'_session_csrf_secret_token': self.session_csrf_secret_token()})
 

	
 
        response.follow()
 
        ug = UserGroup.get_by_group_name(users_group_name)
 
        p = Permission.get_by_key('hg.create.none')
 
        p2 = Permission.get_by_key('hg.usergroup.create.false')
 
        p3 = Permission.get_by_key('hg.fork.none')
 
        ug = db.UserGroup.get_by_group_name(users_group_name)
 
        p = db.Permission.get_by_key('hg.create.none')
 
        p2 = db.Permission.get_by_key('hg.usergroup.create.false')
 
        p3 = db.Permission.get_by_key('hg.fork.none')
 

	
 
        # check if user has this perms, they should be here since
 
        # defaults are on
 
        perms = UserGroupToPerm.query() \
 
            .filter(UserGroupToPerm.users_group == ug).all()
 
        perms = db.UserGroupToPerm.query() \
 
            .filter(db.UserGroupToPerm.users_group == ug).all()
 

	
 
        assert sorted([[x.users_group_id, x.permission_id, ] for x in perms]) == sorted([[ug.users_group_id, p.permission_id],
 
                    [ug.users_group_id, p2.permission_id],
 
                    [ug.users_group_id, p3.permission_id]])
 

	
 
        # DELETE !
 
        ug = UserGroup.get_by_group_name(users_group_name)
 
        ug = db.UserGroup.get_by_group_name(users_group_name)
 
        ugid = ug.users_group_id
 
        response = self.app.post(base.url('delete_users_group', id=ug.users_group_id),
 
            params={'_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        response = response.follow()
 
        gr = meta.Session().query(UserGroup) \
 
            .filter(UserGroup.users_group_name == users_group_name).scalar()
 
        gr = meta.Session().query(db.UserGroup) \
 
            .filter(db.UserGroup.users_group_name == users_group_name).scalar()
 

	
 
        assert gr is None
 
        p = Permission.get_by_key('hg.create.repository')
 
        perms = UserGroupToPerm.query() \
 
            .filter(UserGroupToPerm.users_group_id == ugid).all()
 
        p = db.Permission.get_by_key('hg.create.repository')
 
        perms = db.UserGroupToPerm.query() \
 
            .filter(db.UserGroupToPerm.users_group_id == ugid).all()
 
        perms = [[x.users_group_id,
 
                  x.permission_id, ] for x in perms]
 
        assert perms == []
 

	
 
    def test_default_perms_enable_repository_fork_on_group(self):
 
        self.log_user()
 
@@ -139,66 +138,66 @@ class TestAdminUsersGroupsController(bas
 
                                 {'users_group_name': users_group_name,
 
                                  'user_group_description': 'DESC',
 
                                  'active': True,
 
                                  '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        response.follow()
 

	
 
        ug = UserGroup.get_by_group_name(users_group_name)
 
        ug = db.UserGroup.get_by_group_name(users_group_name)
 
        self.checkSessionFlash(response,
 
                               'Created user group ')
 
        ## ENABLE REPO CREATE ON A GROUP
 
        response = self.app.post(base.url('edit_user_group_default_perms_update',
 
                                     id=ug.users_group_id),
 
                                 {'fork_repo_perm': True, '_session_csrf_secret_token': self.session_csrf_secret_token()})
 

	
 
        response.follow()
 
        ug = UserGroup.get_by_group_name(users_group_name)
 
        p = Permission.get_by_key('hg.create.none')
 
        p2 = Permission.get_by_key('hg.usergroup.create.false')
 
        p3 = Permission.get_by_key('hg.fork.repository')
 
        ug = db.UserGroup.get_by_group_name(users_group_name)
 
        p = db.Permission.get_by_key('hg.create.none')
 
        p2 = db.Permission.get_by_key('hg.usergroup.create.false')
 
        p3 = db.Permission.get_by_key('hg.fork.repository')
 
        # check if user has this perms, they should be here since
 
        # defaults are on
 
        perms = UserGroupToPerm.query() \
 
            .filter(UserGroupToPerm.users_group == ug).all()
 
        perms = db.UserGroupToPerm.query() \
 
            .filter(db.UserGroupToPerm.users_group == ug).all()
 

	
 
        assert sorted([[x.users_group_id, x.permission_id, ] for x in perms]) == sorted([[ug.users_group_id, p.permission_id],
 
                    [ug.users_group_id, p2.permission_id],
 
                    [ug.users_group_id, p3.permission_id]])
 

	
 
        ## DISABLE REPO CREATE ON A GROUP
 
        response = self.app.post(base.url('edit_user_group_default_perms_update', id=ug.users_group_id),
 
            params={'_session_csrf_secret_token': self.session_csrf_secret_token()})
 

	
 
        response.follow()
 
        ug = UserGroup.get_by_group_name(users_group_name)
 
        p = Permission.get_by_key('hg.create.none')
 
        p2 = Permission.get_by_key('hg.usergroup.create.false')
 
        p3 = Permission.get_by_key('hg.fork.none')
 
        ug = db.UserGroup.get_by_group_name(users_group_name)
 
        p = db.Permission.get_by_key('hg.create.none')
 
        p2 = db.Permission.get_by_key('hg.usergroup.create.false')
 
        p3 = db.Permission.get_by_key('hg.fork.none')
 
        # check if user has this perms, they should be here since
 
        # defaults are on
 
        perms = UserGroupToPerm.query() \
 
            .filter(UserGroupToPerm.users_group == ug).all()
 
        perms = db.UserGroupToPerm.query() \
 
            .filter(db.UserGroupToPerm.users_group == ug).all()
 

	
 
        assert sorted([[x.users_group_id, x.permission_id, ] for x in perms]) == sorted([[ug.users_group_id, p.permission_id],
 
                    [ug.users_group_id, p2.permission_id],
 
                    [ug.users_group_id, p3.permission_id]])
 

	
 
        # DELETE !
 
        ug = UserGroup.get_by_group_name(users_group_name)
 
        ug = db.UserGroup.get_by_group_name(users_group_name)
 
        ugid = ug.users_group_id
 
        response = self.app.post(base.url('delete_users_group', id=ug.users_group_id),
 
            params={'_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        response = response.follow()
 
        gr = meta.Session().query(UserGroup) \
 
                           .filter(UserGroup.users_group_name ==
 
        gr = meta.Session().query(db.UserGroup) \
 
                           .filter(db.UserGroup.users_group_name ==
 
                                   users_group_name).scalar()
 

	
 
        assert gr is None
 
        p = Permission.get_by_key('hg.fork.repository')
 
        perms = UserGroupToPerm.query() \
 
            .filter(UserGroupToPerm.users_group_id == ugid).all()
 
        p = db.Permission.get_by_key('hg.fork.repository')
 
        perms = db.UserGroupToPerm.query() \
 
            .filter(db.UserGroupToPerm.users_group_id == ugid).all()
 
        perms = [[x.users_group_id,
 
                  x.permission_id, ] for x in perms]
 
        assert perms == []
 

	
 
    def test_delete_browser_fakeout(self):
 
        response = self.app.post(base.url('delete_users_group', id=1),
kallithea/tests/functional/test_admin_users.py
Show inline comments
 
@@ -18,14 +18,13 @@ from tg.util.webtest import test_context
 
from webob.exc import HTTPNotFound
 

	
 
import kallithea
 
from kallithea.controllers.admin.users import UsersController
 
from kallithea.lib import helpers as h
 
from kallithea.lib.auth import check_password
 
from kallithea.model import meta, validators
 
from kallithea.model.db import Permission, RepoGroup, User, UserApiKeys, UserSshKeys
 
from kallithea.model import db, meta, validators
 
from kallithea.model.user import UserModel
 
from kallithea.tests import base
 
from kallithea.tests.fixture import Fixture
 

	
 

	
 
fixture = Fixture()
 
@@ -36,22 +35,22 @@ def user_and_repo_group_fail():
 
    username = 'repogrouperr'
 
    groupname = 'repogroup_fail'
 
    user = fixture.create_user(name=username)
 
    repo_group = fixture.create_repo_group(name=groupname, cur_user=username)
 
    yield user, repo_group
 
    # cleanup
 
    if RepoGroup.get_by_group_name(groupname):
 
    if db.RepoGroup.get_by_group_name(groupname):
 
        fixture.destroy_repo_group(repo_group)
 

	
 

	
 
class TestAdminUsersController(base.TestController):
 
    test_user_1 = 'testme'
 

	
 
    @classmethod
 
    def teardown_class(cls):
 
        if User.get_by_username(cls.test_user_1):
 
        if db.User.get_by_username(cls.test_user_1):
 
            UserModel().delete(cls.test_user_1)
 
            meta.Session().commit()
 

	
 
    def test_index(self):
 
        self.log_user()
 
        response = self.app.get(base.url('users'))
 
@@ -82,14 +81,14 @@ class TestAdminUsersController(base.Test
 

	
 
        self.checkSessionFlash(response, '''Created user %s''' % username)
 

	
 
        response = response.follow()
 
        response.mustcontain("""%s user settings""" % username) # in <title>
 

	
 
        new_user = meta.Session().query(User). \
 
            filter(User.username == username).one()
 
        new_user = meta.Session().query(db.User). \
 
            filter(db.User.username == username).one()
 

	
 
        assert new_user.username == username
 
        assert check_password(password, new_user.password) == True
 
        assert new_user.name == name
 
        assert new_user.lastname == lastname
 
        assert new_user.email == email
 
@@ -116,13 +115,13 @@ class TestAdminUsersController(base.Test
 
        msg = h.html_escape(msg % {'username': 'new_user'})
 
        response.mustcontain("""<span class="error-message">%s</span>""" % msg)
 
        response.mustcontain("""<span class="error-message">Please enter a value</span>""")
 
        response.mustcontain("""<span class="error-message">An email address must contain a single @</span>""")
 

	
 
        def get_user():
 
            meta.Session().query(User).filter(User.username == username).one()
 
            meta.Session().query(db.User).filter(db.User.username == username).one()
 

	
 
        with pytest.raises(NoResultFound):
 
            get_user(), 'found user in database'
 

	
 
    def test_new(self):
 
        self.log_user()
 
@@ -168,27 +167,27 @@ class TestAdminUsersController(base.Test
 

	
 
        params.update({'_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        response = self.app.post(base.url('update_user', id=usr.user_id), params)
 
        self.checkSessionFlash(response, 'User updated successfully')
 
        params.pop('_session_csrf_secret_token')
 

	
 
        updated_user = User.get_by_username(self.test_user_1)
 
        updated_user = db.User.get_by_username(self.test_user_1)
 
        updated_params = updated_user.get_api_data(True)
 
        updated_params.update({'password_confirmation': ''})
 
        updated_params.update({'new_password': ''})
 

	
 
        assert params == updated_params
 

	
 
    def test_delete(self):
 
        self.log_user()
 
        username = 'newtestuserdeleteme'
 

	
 
        fixture.create_user(name=username)
 

	
 
        new_user = meta.Session().query(User) \
 
            .filter(User.username == username).one()
 
        new_user = meta.Session().query(db.User) \
 
            .filter(db.User.username == username).one()
 
        response = self.app.post(base.url('delete_user', id=new_user.user_id),
 
            params={'_session_csrf_secret_token': self.session_csrf_secret_token()})
 

	
 
        self.checkSessionFlash(response, 'Successfully deleted user')
 

	
 
    def test_delete_repo_err(self):
 
@@ -196,14 +195,14 @@ class TestAdminUsersController(base.Test
 
        username = 'repoerr'
 
        reponame = 'repoerr_fail'
 

	
 
        fixture.create_user(name=username)
 
        fixture.create_repo(name=reponame, cur_user=username)
 

	
 
        new_user = meta.Session().query(User) \
 
            .filter(User.username == username).one()
 
        new_user = meta.Session().query(db.User) \
 
            .filter(db.User.username == username).one()
 
        response = self.app.post(base.url('delete_user', id=new_user.user_id),
 
            params={'_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'User &quot;%s&quot; still '
 
                               'owns 1 repositories and cannot be removed. '
 
                               'Switch owners or remove those repositories: '
 
                               '%s' % (username, reponame))
 
@@ -228,13 +227,13 @@ class TestAdminUsersController(base.Test
 
        self.checkSessionFlash(response, 'User &quot;%s&quot; still '
 
                               'owns 1 repository groups and cannot be removed. '
 
                               'Switch owners or remove those repository groups: '
 
                               '%s' % (username, groupname))
 

	
 
        # Relevant _if_ the user deletion succeeded to make sure we can render groups without owner
 
        # rg = RepoGroup.get_by_group_name(group_name=groupname)
 
        # rg = db.RepoGroup.get_by_group_name(group_name=groupname)
 
        # response = self.app.get(base.url('repos_groups', id=rg.group_id))
 

	
 
        response = self.app.post(base.url('delete_repo_group', group_name=groupname),
 
            params={'_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'Removed repository group %s' % groupname)
 

	
 
@@ -247,14 +246,14 @@ class TestAdminUsersController(base.Test
 
        username = 'usergrouperr'
 
        groupname = 'usergroup_fail'
 

	
 
        fixture.create_user(name=username)
 
        ug = fixture.create_user_group(name=groupname, cur_user=username)
 

	
 
        new_user = meta.Session().query(User) \
 
            .filter(User.username == username).one()
 
        new_user = meta.Session().query(db.User) \
 
            .filter(db.User.username == username).one()
 
        response = self.app.post(base.url('delete_user', id=new_user.user_id),
 
            params={'_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'User &quot;%s&quot; still '
 
                               'owns 1 user groups and cannot be removed. '
 
                               'Switch owners or remove those user groups: '
 
                               '%s' % (username, groupname))
 
@@ -268,19 +267,19 @@ class TestAdminUsersController(base.Test
 
        response = self.app.post(base.url('delete_user', id=new_user.user_id),
 
            params={'_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'Successfully deleted user')
 

	
 
    def test_edit(self):
 
        self.log_user()
 
        user = User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        user = db.User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        response = self.app.get(base.url('edit_user', id=user.user_id))
 

	
 
    def test_add_perm_create_repo(self):
 
        self.log_user()
 
        perm_none = Permission.get_by_key('hg.create.none')
 
        perm_create = Permission.get_by_key('hg.create.repository')
 
        perm_none = db.Permission.get_by_key('hg.create.none')
 
        perm_create = db.Permission.get_by_key('hg.create.repository')
 

	
 
        user = UserModel().create_or_update(username='dummy', password='qwe',
 
                                            email='dummy', firstname='a',
 
                                            lastname='b')
 
        meta.Session().commit()
 
        uid = user.user_id
 
@@ -291,26 +290,26 @@ class TestAdminUsersController(base.Test
 
            assert UserModel().has_perm(user, perm_create) == False
 

	
 
            response = self.app.post(base.url('edit_user_perms_update', id=uid),
 
                                     params=dict(create_repo_perm=True,
 
                                                 _session_csrf_secret_token=self.session_csrf_secret_token()))
 

	
 
            perm_none = Permission.get_by_key('hg.create.none')
 
            perm_create = Permission.get_by_key('hg.create.repository')
 
            perm_none = db.Permission.get_by_key('hg.create.none')
 
            perm_create = db.Permission.get_by_key('hg.create.repository')
 

	
 
            # User should have None permission on creation repository
 
            assert UserModel().has_perm(uid, perm_none) == False
 
            assert UserModel().has_perm(uid, perm_create) == True
 
        finally:
 
            UserModel().delete(uid)
 
            meta.Session().commit()
 

	
 
    def test_revoke_perm_create_repo(self):
 
        self.log_user()
 
        perm_none = Permission.get_by_key('hg.create.none')
 
        perm_create = Permission.get_by_key('hg.create.repository')
 
        perm_none = db.Permission.get_by_key('hg.create.none')
 
        perm_create = db.Permission.get_by_key('hg.create.repository')
 

	
 
        user = UserModel().create_or_update(username='dummy', password='qwe',
 
                                            email='dummy', firstname='a',
 
                                            lastname='b')
 
        meta.Session().commit()
 
        uid = user.user_id
 
@@ -320,26 +319,26 @@ class TestAdminUsersController(base.Test
 
            assert UserModel().has_perm(user, perm_none) == False
 
            assert UserModel().has_perm(user, perm_create) == False
 

	
 
            response = self.app.post(base.url('edit_user_perms_update', id=uid),
 
                                     params=dict(_session_csrf_secret_token=self.session_csrf_secret_token()))
 

	
 
            perm_none = Permission.get_by_key('hg.create.none')
 
            perm_create = Permission.get_by_key('hg.create.repository')
 
            perm_none = db.Permission.get_by_key('hg.create.none')
 
            perm_create = db.Permission.get_by_key('hg.create.repository')
 

	
 
            # User should have None permission on creation repository
 
            assert UserModel().has_perm(uid, perm_none) == True
 
            assert UserModel().has_perm(uid, perm_create) == False
 
        finally:
 
            UserModel().delete(uid)
 
            meta.Session().commit()
 

	
 
    def test_add_perm_fork_repo(self):
 
        self.log_user()
 
        perm_none = Permission.get_by_key('hg.fork.none')
 
        perm_fork = Permission.get_by_key('hg.fork.repository')
 
        perm_none = db.Permission.get_by_key('hg.fork.none')
 
        perm_fork = db.Permission.get_by_key('hg.fork.repository')
 

	
 
        user = UserModel().create_or_update(username='dummy', password='qwe',
 
                                            email='dummy', firstname='a',
 
                                            lastname='b')
 
        meta.Session().commit()
 
        uid = user.user_id
 
@@ -350,26 +349,26 @@ class TestAdminUsersController(base.Test
 
            assert UserModel().has_perm(user, perm_fork) == False
 

	
 
            response = self.app.post(base.url('edit_user_perms_update', id=uid),
 
                                     params=dict(create_repo_perm=True,
 
                                                 _session_csrf_secret_token=self.session_csrf_secret_token()))
 

	
 
            perm_none = Permission.get_by_key('hg.create.none')
 
            perm_create = Permission.get_by_key('hg.create.repository')
 
            perm_none = db.Permission.get_by_key('hg.create.none')
 
            perm_create = db.Permission.get_by_key('hg.create.repository')
 

	
 
            # User should have None permission on creation repository
 
            assert UserModel().has_perm(uid, perm_none) == False
 
            assert UserModel().has_perm(uid, perm_create) == True
 
        finally:
 
            UserModel().delete(uid)
 
            meta.Session().commit()
 

	
 
    def test_revoke_perm_fork_repo(self):
 
        self.log_user()
 
        perm_none = Permission.get_by_key('hg.fork.none')
 
        perm_fork = Permission.get_by_key('hg.fork.repository')
 
        perm_none = db.Permission.get_by_key('hg.fork.none')
 
        perm_fork = db.Permission.get_by_key('hg.fork.repository')
 

	
 
        user = UserModel().create_or_update(username='dummy', password='qwe',
 
                                            email='dummy', firstname='a',
 
                                            lastname='b')
 
        meta.Session().commit()
 
        uid = user.user_id
 
@@ -379,25 +378,25 @@ class TestAdminUsersController(base.Test
 
            assert UserModel().has_perm(user, perm_none) == False
 
            assert UserModel().has_perm(user, perm_fork) == False
 

	
 
            response = self.app.post(base.url('edit_user_perms_update', id=uid),
 
                                     params=dict(_session_csrf_secret_token=self.session_csrf_secret_token()))
 

	
 
            perm_none = Permission.get_by_key('hg.create.none')
 
            perm_create = Permission.get_by_key('hg.create.repository')
 
            perm_none = db.Permission.get_by_key('hg.create.none')
 
            perm_create = db.Permission.get_by_key('hg.create.repository')
 

	
 
            # User should have None permission on creation repository
 
            assert UserModel().has_perm(uid, perm_none) == True
 
            assert UserModel().has_perm(uid, perm_create) == False
 
        finally:
 
            UserModel().delete(uid)
 
            meta.Session().commit()
 

	
 
    def test_ips(self):
 
        self.log_user()
 
        user = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        response = self.app.get(base.url('edit_user_ips', id=user.user_id))
 
        response.mustcontain('All IP addresses are allowed')
 

	
 
    @base.parametrize('test_name,ip,ip_range,failure', [
 
        ('127/24', '127.0.0.1/24', '127.0.0.0 - 127.0.0.255', False),
 
        ('10/32', '10.0.0.10/32', '10.0.0.10 - 10.0.0.10', False),
 
@@ -405,13 +404,13 @@ class TestAdminUsersController(base.Test
 
        ('0/8', '0.0.0.0/8', '0.0.0.0 - 0.255.255.255', False),
 
        ('127_bad_mask', '127.0.0.1/99', '127.0.0.1 - 127.0.0.1', True),
 
        ('127_bad_ip', 'foobar', 'foobar', True),
 
    ])
 
    def test_add_ip(self, test_name, ip, ip_range, failure, auto_clear_ip_permissions):
 
        self.log_user()
 
        user = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user_id = user.user_id
 

	
 
        response = self.app.post(base.url('edit_user_ips_update', id=user_id),
 
                                 params=dict(new_ip=ip, _session_csrf_secret_token=self.session_csrf_secret_token()))
 

	
 
        if failure:
 
@@ -424,13 +423,13 @@ class TestAdminUsersController(base.Test
 
            response = self.app.get(base.url('edit_user_ips', id=user_id))
 
            response.mustcontain(ip)
 
            response.mustcontain(ip_range)
 

	
 
    def test_delete_ip(self, auto_clear_ip_permissions):
 
        self.log_user()
 
        user = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user_id = user.user_id
 
        ip = '127.0.0.1/32'
 
        ip_range = '127.0.0.1 - 127.0.0.1'
 
        with test_context(self.app):
 
            new_ip = UserModel().add_extra_ip(user_id, ip)
 
            meta.Session().commit()
 
@@ -448,63 +447,63 @@ class TestAdminUsersController(base.Test
 
        response.mustcontain(no=[ip])
 
        response.mustcontain(no=[ip_range])
 

	
 
    def test_api_keys(self):
 
        self.log_user()
 

	
 
        user = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        response = self.app.get(base.url('edit_user_api_keys', id=user.user_id))
 
        response.mustcontain(user.api_key)
 
        response.mustcontain('Expires: Never')
 

	
 
    @base.parametrize('desc,lifetime', [
 
        ('forever', -1),
 
        ('5mins', 60*5),
 
        ('30days', 60*60*24*30),
 
    ])
 
    def test_add_api_keys(self, desc, lifetime):
 
        self.log_user()
 
        user = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user_id = user.user_id
 

	
 
        response = self.app.post(base.url('edit_user_api_keys_update', id=user_id),
 
                 {'description': desc, 'lifetime': lifetime, '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'API key successfully created')
 
        try:
 
            response = response.follow()
 
            user = User.get(user_id)
 
            user = db.User.get(user_id)
 
            for api_key in user.api_keys:
 
                response.mustcontain(api_key)
 
        finally:
 
            for api_key in UserApiKeys.query().filter(UserApiKeys.user_id == user_id).all():
 
            for api_key in db.UserApiKeys.query().filter(db.UserApiKeys.user_id == user_id).all():
 
                meta.Session().delete(api_key)
 
                meta.Session().commit()
 

	
 
    def test_remove_api_key(self):
 
        self.log_user()
 
        user = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user_id = user.user_id
 

	
 
        response = self.app.post(base.url('edit_user_api_keys_update', id=user_id),
 
                {'description': 'desc', 'lifetime': -1, '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'API key successfully created')
 
        response = response.follow()
 

	
 
        # now delete our key
 
        keys = UserApiKeys.query().filter(UserApiKeys.user_id == user_id).all()
 
        keys = db.UserApiKeys.query().filter(db.UserApiKeys.user_id == user_id).all()
 
        assert 1 == len(keys)
 

	
 
        response = self.app.post(base.url('edit_user_api_keys_delete', id=user_id),
 
                 {'del_api_key': keys[0].api_key, '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'API key successfully deleted')
 
        keys = UserApiKeys.query().filter(UserApiKeys.user_id == user_id).all()
 
        keys = db.UserApiKeys.query().filter(db.UserApiKeys.user_id == user_id).all()
 
        assert 0 == len(keys)
 

	
 
    def test_reset_main_api_key(self):
 
        self.log_user()
 
        user = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user_id = user.user_id
 
        api_key = user.api_key
 
        response = self.app.get(base.url('edit_user_api_keys', id=user_id))
 
        response.mustcontain(api_key)
 
        response.mustcontain('Expires: Never')
 

	
 
@@ -517,52 +516,52 @@ class TestAdminUsersController(base.Test
 
    def test_add_ssh_key(self):
 
        description = 'something'
 
        public_key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC6Ycnc2oUZHQnQwuqgZqTTdMDZD7ataf3JM7oG2Fw8JR6cdmz4QZLe5mfDwaFwG2pWHLRpVqzfrD/Pn3rIO++bgCJH5ydczrl1WScfryV1hYMJ/4EzLGM657J1/q5EI+b9SntKjf4ax+KP322L0TNQGbZUHLbfG2MwHMrYBQpHUQ== me@localhost'
 
        fingerprint = 'Ke3oUCNJM87P0jJTb3D+e3shjceP2CqMpQKVd75E9I8'
 

	
 
        self.log_user()
 
        user = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user_id = user.user_id
 

	
 
        response = self.app.post(base.url('edit_user_ssh_keys', id=user_id),
 
                                 {'description': description,
 
                                  'public_key': public_key,
 
                                  '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'SSH key %s successfully added' % fingerprint)
 

	
 
        response = response.follow()
 
        response.mustcontain(fingerprint)
 
        ssh_key = UserSshKeys.query().filter(UserSshKeys.user_id == user_id).one()
 
        ssh_key = db.UserSshKeys.query().filter(db.UserSshKeys.user_id == user_id).one()
 
        assert ssh_key.fingerprint == fingerprint
 
        assert ssh_key.description == description
 
        meta.Session().delete(ssh_key)
 
        meta.Session().commit()
 

	
 
    def test_remove_ssh_key(self):
 
        description = ''
 
        public_key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC6Ycnc2oUZHQnQwuqgZqTTdMDZD7ataf3JM7oG2Fw8JR6cdmz4QZLe5mfDwaFwG2pWHLRpVqzfrD/Pn3rIO++bgCJH5ydczrl1WScfryV1hYMJ/4EzLGM657J1/q5EI+b9SntKjf4ax+KP322L0TNQGbZUHLbfG2MwHMrYBQpHUQ== me@localhost'
 
        fingerprint = 'Ke3oUCNJM87P0jJTb3D+e3shjceP2CqMpQKVd75E9I8'
 

	
 
        self.log_user()
 
        user = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user_id = user.user_id
 

	
 
        response = self.app.post(base.url('edit_user_ssh_keys', id=user_id),
 
                                 {'description': description,
 
                                  'public_key': public_key,
 
                                  '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'SSH key %s successfully added' % fingerprint)
 
        response.follow()
 
        ssh_key = UserSshKeys.query().filter(UserSshKeys.user_id == user_id).one()
 
        ssh_key = db.UserSshKeys.query().filter(db.UserSshKeys.user_id == user_id).one()
 
        assert ssh_key.description == 'me@localhost'
 

	
 
        response = self.app.post(base.url('edit_user_ssh_keys_delete', id=user_id),
 
                                 {'del_public_key_fingerprint': ssh_key.fingerprint,
 
                                  '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'SSH key successfully deleted')
 
        keys = UserSshKeys.query().all()
 
        keys = db.UserSshKeys.query().all()
 
        assert 0 == len(keys)
 

	
 

	
 
class TestAdminUsersController_unittest(base.TestController):
 
    """ Unit tests for the users controller """
 

	
 
@@ -571,13 +570,13 @@ class TestAdminUsersController_unittest(
 
        def flash_mock(*args, **kwargs):
 
            pass
 
        monkeypatch.setattr(h, 'flash', flash_mock)
 

	
 
        u = UsersController()
 
        # a regular user should work correctly
 
        user = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        assert u._get_user_or_raise_if_default(user.user_id) == user
 
        # the default user should raise
 
        with pytest.raises(HTTPNotFound):
 
            u._get_user_or_raise_if_default(kallithea.DEFAULT_USER_ID)
 

	
 

	
 
@@ -585,69 +584,69 @@ class TestAdminUsersControllerForDefault
 
    """
 
    Edit actions on the default user are not allowed.
 
    Validate that they throw a 404 exception.
 
    """
 
    def test_edit_default_user(self):
 
        self.log_user()
 
        user = User.get_default_user()
 
        user = db.User.get_default_user()
 
        response = self.app.get(base.url('edit_user', id=user.user_id), status=404)
 

	
 
    def test_edit_advanced_default_user(self):
 
        self.log_user()
 
        user = User.get_default_user()
 
        user = db.User.get_default_user()
 
        response = self.app.get(base.url('edit_user_advanced', id=user.user_id), status=404)
 

	
 
    # API keys
 
    def test_edit_api_keys_default_user(self):
 
        self.log_user()
 
        user = User.get_default_user()
 
        user = db.User.get_default_user()
 
        response = self.app.get(base.url('edit_user_api_keys', id=user.user_id), status=404)
 

	
 
    def test_add_api_keys_default_user(self):
 
        self.log_user()
 
        user = User.get_default_user()
 
        user = db.User.get_default_user()
 
        response = self.app.post(base.url('edit_user_api_keys_update', id=user.user_id),
 
                 {'_session_csrf_secret_token': self.session_csrf_secret_token()}, status=404)
 

	
 
    def test_delete_api_keys_default_user(self):
 
        self.log_user()
 
        user = User.get_default_user()
 
        user = db.User.get_default_user()
 
        response = self.app.post(base.url('edit_user_api_keys_delete', id=user.user_id),
 
                 {'_session_csrf_secret_token': self.session_csrf_secret_token()}, status=404)
 

	
 
    # Permissions
 
    def test_edit_perms_default_user(self):
 
        self.log_user()
 
        user = User.get_default_user()
 
        user = db.User.get_default_user()
 
        response = self.app.get(base.url('edit_user_perms', id=user.user_id), status=404)
 

	
 
    def test_update_perms_default_user(self):
 
        self.log_user()
 
        user = User.get_default_user()
 
        user = db.User.get_default_user()
 
        response = self.app.post(base.url('edit_user_perms_update', id=user.user_id),
 
                 {'_session_csrf_secret_token': self.session_csrf_secret_token()}, status=404)
 

	
 
    # Emails
 
    def test_edit_emails_default_user(self):
 
        self.log_user()
 
        user = User.get_default_user()
 
        user = db.User.get_default_user()
 
        response = self.app.get(base.url('edit_user_emails', id=user.user_id), status=404)
 

	
 
    def test_add_emails_default_user(self):
 
        self.log_user()
 
        user = User.get_default_user()
 
        user = db.User.get_default_user()
 
        response = self.app.post(base.url('edit_user_emails_update', id=user.user_id),
 
                 {'_session_csrf_secret_token': self.session_csrf_secret_token()}, status=404)
 

	
 
    def test_delete_emails_default_user(self):
 
        self.log_user()
 
        user = User.get_default_user()
 
        user = db.User.get_default_user()
 
        response = self.app.post(base.url('edit_user_emails_delete', id=user.user_id),
 
                 {'_session_csrf_secret_token': self.session_csrf_secret_token()}, status=404)
 

	
 
    # IP addresses
 
    # Add/delete of IP addresses for the default user is used to maintain
 
    # the global IP whitelist and thus allowed. Only 'edit' is forbidden.
 
    def test_edit_ip_default_user(self):
 
        self.log_user()
 
        user = User.get_default_user()
 
        user = db.User.get_default_user()
 
        response = self.app.get(base.url('edit_user_ips', id=user.user_id), status=404)
kallithea/tests/functional/test_changeset_pullrequests_comments.py
Show inline comments
 
import re
 

	
 
from kallithea.model import meta
 
from kallithea.model import db, meta
 
from kallithea.model.changeset_status import ChangesetStatusModel
 
from kallithea.model.db import ChangesetComment, PullRequest
 
from kallithea.tests import base
 

	
 

	
 
class TestChangeSetCommentsController(base.TestController):
 

	
 
    def setup_method(self, method):
 
        for x in ChangesetComment.query().all():
 
        for x in db.ChangesetComment.query().all():
 
            meta.Session().delete(x)
 
        meta.Session().commit()
 

	
 
    def test_create(self):
 
        self.log_user()
 
        rev = '27cd5cce30c96924232dffcd24178a07ffeb5dfc'
 
@@ -31,13 +30,13 @@ class TestChangeSetCommentsController(ba
 
            '''<div class="comments-number">'''
 
            ''' 1 comment (0 inline, 1 general)'''
 
        )
 
        response.mustcontain(text)
 

	
 
        # test DB
 
        assert ChangesetComment.query().count() == 1
 
        assert db.ChangesetComment.query().count() == 1
 

	
 
    def test_create_inline(self):
 
        self.log_user()
 
        rev = '27cd5cce30c96924232dffcd24178a07ffeb5dfc'
 
        text = 'inline comment on changeset'
 
        f_path = 'vcs/web/simplevcs/views/repository.py'
 
@@ -61,13 +60,13 @@ class TestChangeSetCommentsController(ba
 
            '''data-f_path="vcs/web/simplevcs/views/repository.py" '''
 
            '''data-line_no="n1" data-target-id="vcswebsimplevcsviewsrepositorypy_n1">'''
 
        )
 
        response.mustcontain(text)
 

	
 
        # test DB
 
        assert ChangesetComment.query().count() == 1
 
        assert db.ChangesetComment.query().count() == 1
 

	
 
    def test_create_with_mention(self):
 
        self.log_user()
 

	
 
        rev = '27cd5cce30c96924232dffcd24178a07ffeb5dfc'
 
        text = '@%s check CommentOnRevision' % base.TEST_USER_REGULAR_LOGIN
 
@@ -85,13 +84,13 @@ class TestChangeSetCommentsController(ba
 
            '''<div class="comments-number">'''
 
            ''' 1 comment (0 inline, 1 general)'''
 
        )
 
        response.mustcontain('<b>@%s</b> check CommentOnRevision' % base.TEST_USER_REGULAR_LOGIN)
 

	
 
        # test DB
 
        assert ChangesetComment.query().count() == 1
 
        assert db.ChangesetComment.query().count() == 1
 

	
 
    def test_create_status_change(self):
 
        self.log_user()
 
        rev = '27cd5cce30c96924232dffcd24178a07ffeb5dfc'
 
        text = 'general comment on changeset'
 

	
 
@@ -109,13 +108,13 @@ class TestChangeSetCommentsController(ba
 
            '''<div class="comments-number">'''
 
            ''' 1 comment (0 inline, 1 general)'''
 
        )
 
        response.mustcontain(text)
 

	
 
        # test DB
 
        assert ChangesetComment.query().count() == 1
 
        assert db.ChangesetComment.query().count() == 1
 

	
 
        # check status
 
        status = ChangesetStatusModel().get_status(repo=base.HG_REPO, revision=rev)
 
        assert status == 'rejected'
 

	
 
    def test_delete(self):
 
@@ -125,22 +124,22 @@ class TestChangeSetCommentsController(ba
 

	
 
        params = {'text': text, '_session_csrf_secret_token': self.session_csrf_secret_token()}
 
        response = self.app.post(base.url(controller='changeset', action='comment',
 
                                     repo_name=base.HG_REPO, revision=rev),
 
                                     params=params, extra_environ={'HTTP_X_PARTIAL_XHR': '1'})
 

	
 
        comments = ChangesetComment.query().all()
 
        comments = db.ChangesetComment.query().all()
 
        assert len(comments) == 1
 
        comment_id = comments[0].comment_id
 

	
 
        self.app.post(base.url("changeset_comment_delete",
 
                                    repo_name=base.HG_REPO,
 
                                    comment_id=comment_id),
 
            params={'_session_csrf_secret_token': self.session_csrf_secret_token()})
 

	
 
        comments = ChangesetComment.query().all()
 
        comments = db.ChangesetComment.query().all()
 
        assert len(comments) == 0
 

	
 
        response = self.app.get(base.url(controller='changeset', action='index',
 
                                repo_name=base.HG_REPO, revision=rev))
 
        response.mustcontain(
 
            '''<div class="comments-number">'''
 
@@ -149,13 +148,13 @@ class TestChangeSetCommentsController(ba
 
        response.mustcontain(no=text)
 

	
 

	
 
class TestPullrequestsCommentsController(base.TestController):
 

	
 
    def setup_method(self, method):
 
        for x in ChangesetComment.query().all():
 
        for x in db.ChangesetComment.query().all():
 
            meta.Session().delete(x)
 
        meta.Session().commit()
 

	
 
    def _create_pr(self):
 
        response = self.app.post(base.url(controller='pullrequests', action='create',
 
                                     repo_name=base.HG_REPO),
 
@@ -192,13 +191,13 @@ class TestPullrequestsCommentsController
 
            '''<div class="comments-number">'''
 
            ''' 2 comments (0 inline, 2 general)'''
 
        )
 
        response.mustcontain(text)
 

	
 
        # test DB
 
        assert ChangesetComment.query().count() == 2
 
        assert db.ChangesetComment.query().count() == 2
 

	
 
    def test_create_inline(self):
 
        self.log_user()
 
        pr_id = self._create_pr()
 

	
 
        text = 'inline comment on changeset'
 
@@ -222,13 +221,13 @@ class TestPullrequestsCommentsController
 
            '''data-f_path="vcs/web/simplevcs/views/repository.py" '''
 
            '''data-line_no="n1" data-target-id="vcswebsimplevcsviewsrepositorypy_n1">'''
 
        )
 
        response.mustcontain(text)
 

	
 
        # test DB
 
        assert ChangesetComment.query().count() == 2
 
        assert db.ChangesetComment.query().count() == 2
 

	
 
    def test_create_with_mention(self):
 
        self.log_user()
 
        pr_id = self._create_pr()
 

	
 
        text = '@%s check CommentOnRevision' % base.TEST_USER_REGULAR_LOGIN
 
@@ -245,13 +244,13 @@ class TestPullrequestsCommentsController
 
            '''<div class="comments-number">'''
 
            ''' 2 comments (0 inline, 2 general)'''
 
        )
 
        response.mustcontain('<b>@%s</b> check CommentOnRevision' % base.TEST_USER_REGULAR_LOGIN)
 

	
 
        # test DB
 
        assert ChangesetComment.query().count() == 2
 
        assert db.ChangesetComment.query().count() == 2
 

	
 
    def test_create_status_change(self):
 
        self.log_user()
 
        pr_id = self._create_pr()
 

	
 
        text = 'general comment on pullrequest'
 
@@ -272,13 +271,13 @@ class TestPullrequestsCommentsController
 
            '''<div class="comments-number">'''
 
            ''' 2 comments (0 inline, 2 general)'''
 
        )
 
        response.mustcontain(text)
 

	
 
        # test DB
 
        assert ChangesetComment.query().count() == 2
 
        assert db.ChangesetComment.query().count() == 2
 

	
 
        # check status
 
        status = ChangesetStatusModel().get_status(repo=base.HG_REPO, pull_request=pr_id)
 
        assert status == 'rejected'
 

	
 
    def test_delete(self):
 
@@ -288,22 +287,22 @@ class TestPullrequestsCommentsController
 
        text = 'general comment on changeset to be deleted'
 
        params = {'text': text, '_session_csrf_secret_token': self.session_csrf_secret_token()}
 
        response = self.app.post(base.url(controller='pullrequests', action='comment',
 
                                     repo_name=base.HG_REPO, pull_request_id=pr_id),
 
                                     params=params, extra_environ={'HTTP_X_PARTIAL_XHR': '1'})
 

	
 
        comments = ChangesetComment.query().all()
 
        comments = db.ChangesetComment.query().all()
 
        assert len(comments) == 2
 
        comment_id = comments[-1].comment_id
 

	
 
        self.app.post(base.url("pullrequest_comment_delete",
 
                                    repo_name=base.HG_REPO,
 
                                    comment_id=comment_id),
 
            params={'_session_csrf_secret_token': self.session_csrf_secret_token()})
 

	
 
        comments = ChangesetComment.query().all()
 
        comments = db.ChangesetComment.query().all()
 
        assert len(comments) == 1
 

	
 
        response = self.app.get(base.url(controller='pullrequests', action='show',
 
                                repo_name=base.HG_REPO, pull_request_id=pr_id, extra=''))
 
        response.mustcontain(
 
            '''<div class="comments-number">'''
 
@@ -329,13 +328,13 @@ class TestPullrequestsCommentsController
 
        response.mustcontain(
 
            '''title (Closed)'''
 
        )
 
        response.mustcontain(text)
 

	
 
        # test DB
 
        assert PullRequest.get(pr_id).status == PullRequest.STATUS_CLOSED
 
        assert db.PullRequest.get(pr_id).status == db.PullRequest.STATUS_CLOSED
 

	
 
    def test_delete_pr(self):
 
        self.log_user()
 
        pr_id = self._create_pr()
 

	
 
        text = 'general comment on pullrequest'
 
@@ -348,13 +347,13 @@ class TestPullrequestsCommentsController
 
        assert response.status == '200 OK'
 

	
 
        response = self.app.get(base.url(controller='pullrequests', action='show',
 
                                repo_name=base.HG_REPO, pull_request_id=pr_id, extra=''), status=404)
 

	
 
        # test DB
 
        assert PullRequest.get(pr_id) is None
 
        assert db.PullRequest.get(pr_id) is None
 

	
 
    def test_delete_closed_pr(self):
 
        self.log_user()
 
        pr_id = self._create_pr()
 

	
 
        # first close
 
@@ -371,7 +370,7 @@ class TestPullrequestsCommentsController
 
                '_session_csrf_secret_token': self.session_csrf_secret_token()}
 
        response = self.app.post(base.url(controller='pullrequests', action='comment',
 
                                     repo_name=base.HG_REPO, pull_request_id=pr_id),
 
                                     params=params, extra_environ={'HTTP_X_PARTIAL_XHR': '1'}, status=403)
 

	
 
        # verify that PR still exists, in closed state
 
        assert PullRequest.get(pr_id).status == PullRequest.STATUS_CLOSED
 
        assert db.PullRequest.get(pr_id).status == db.PullRequest.STATUS_CLOSED
kallithea/tests/functional/test_files.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
import json
 
import mimetypes
 
import posixpath
 

	
 
from kallithea.model import meta
 
from kallithea.model.db import Repository
 
from kallithea.model import db, meta
 
from kallithea.tests import base
 
from kallithea.tests.fixture import Fixture
 

	
 

	
 
fixture = Fixture()
 

	
 
@@ -19,13 +18,13 @@ ARCHIVE_SPECS = {
 

	
 
HG_NODE_HISTORY = fixture.load_resource('hg_node_history_response.json')
 
GIT_NODE_HISTORY = fixture.load_resource('git_node_history_response.json')
 

	
 

	
 
def _set_downloads(repo_name, set_to):
 
    repo = Repository.get_by_repo_name(repo_name)
 
    repo = db.Repository.get_by_repo_name(repo_name)
 
    repo.enable_downloads = set_to
 
    meta.Session().commit()
 

	
 

	
 
class TestFilesController(base.TestController):
 

	
kallithea/tests/functional/test_forks.py
Show inline comments
 
# -*- coding: utf-8 -*-
 

	
 
import urllib.parse
 

	
 
from kallithea.model import meta
 
from kallithea.model.db import Repository, User
 
from kallithea.model import db, meta
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.user import UserModel
 
from kallithea.tests import base
 
from kallithea.tests.fixture import Fixture
 

	
 

	
 
@@ -42,34 +41,34 @@ class _BaseTestCase(base.TestController)
 
        response.mustcontain("""There are no forks yet""")
 

	
 
    def test_no_permissions_to_fork(self):
 
        self.log_user(base.TEST_USER_REGULAR_LOGIN, base.TEST_USER_REGULAR_PASS)['user_id']
 
        try:
 
            user_model = UserModel()
 
            usr = User.get_default_user()
 
            usr = db.User.get_default_user()
 
            user_model.revoke_perm(usr, 'hg.fork.repository')
 
            user_model.grant_perm(usr, 'hg.fork.none')
 
            meta.Session().commit()
 
            # try create a fork
 
            repo_name = self.REPO
 
            self.app.post(base.url(controller='forks', action='fork_create',
 
                              repo_name=repo_name), {'_session_csrf_secret_token': self.session_csrf_secret_token()}, status=403)
 
        finally:
 
            usr = User.get_default_user()
 
            usr = db.User.get_default_user()
 
            user_model.revoke_perm(usr, 'hg.fork.none')
 
            user_model.grant_perm(usr, 'hg.fork.repository')
 
            meta.Session().commit()
 

	
 
    def test_index_with_fork(self):
 
        self.log_user()
 

	
 
        # create a fork
 
        fork_name = self.REPO_FORK
 
        description = 'fork of vcs test'
 
        repo_name = self.REPO
 
        org_repo = Repository.get_by_repo_name(repo_name)
 
        org_repo = db.Repository.get_by_repo_name(repo_name)
 
        creation_args = {
 
            'repo_name': fork_name,
 
            'repo_group': '-1',
 
            'fork_parent_id': org_repo.repo_id,
 
            'repo_type': self.REPO_TYPE,
 
            'description': description,
 
@@ -96,37 +95,37 @@ class _BaseTestCase(base.TestController)
 
        group = fixture.create_repo_group('vc')
 
        group_id = group.group_id
 
        fork_name = self.REPO_FORK
 
        fork_name_full = 'vc/%s' % fork_name
 
        description = 'fork of vcs test'
 
        repo_name = self.REPO
 
        org_repo = Repository.get_by_repo_name(repo_name)
 
        org_repo = db.Repository.get_by_repo_name(repo_name)
 
        creation_args = {
 
            'repo_name': fork_name,
 
            'repo_group': group_id,
 
            'fork_parent_id': org_repo.repo_id,
 
            'repo_type': self.REPO_TYPE,
 
            'description': description,
 
            'private': 'False',
 
            'landing_rev': 'rev:tip',
 
            '_session_csrf_secret_token': self.session_csrf_secret_token()}
 
        self.app.post(base.url(controller='forks', action='fork_create',
 
                          repo_name=repo_name), creation_args)
 
        repo = Repository.get_by_repo_name(fork_name_full)
 
        repo = db.Repository.get_by_repo_name(fork_name_full)
 
        assert repo.fork.repo_name == self.REPO
 

	
 
        ## run the check page that triggers the flash message
 
        response = self.app.get(base.url('repo_check_home', repo_name=fork_name_full))
 
        # test if we have a message that fork is ok
 
        self.checkSessionFlash(response,
 
                'Forked repository %s as <a href="/%s">%s</a>'
 
                % (repo_name, fork_name_full, fork_name_full))
 

	
 
        # test if the fork was created in the database
 
        fork_repo = meta.Session().query(Repository) \
 
            .filter(Repository.repo_name == fork_name_full).one()
 
        fork_repo = meta.Session().query(db.Repository) \
 
            .filter(db.Repository.repo_name == fork_name_full).one()
 

	
 
        assert fork_repo.repo_name == fork_name_full
 
        assert fork_repo.fork.repo_name == repo_name
 

	
 
        # test if the repository is visible in the list ?
 
        response = self.app.get(base.url('summary_home', repo_name=fork_name_full))
 
@@ -139,13 +138,13 @@ class _BaseTestCase(base.TestController)
 

	
 
    def test_fork_unicode(self):
 
        self.log_user()
 

	
 
        # create a fork
 
        repo_name = self.REPO
 
        org_repo = Repository.get_by_repo_name(repo_name)
 
        org_repo = db.Repository.get_by_repo_name(repo_name)
 
        fork_name = self.REPO_FORK + '-rødgrød'
 
        creation_args = {
 
            'repo_name': fork_name,
 
            'repo_group': '-1',
 
            'fork_parent_id': org_repo.repo_id,
 
            'repo_type': self.REPO_TYPE,
 
@@ -157,13 +156,13 @@ class _BaseTestCase(base.TestController)
 
                          repo_name=repo_name), creation_args)
 
        response = self.app.get(base.url(controller='forks', action='forks',
 
                                    repo_name=repo_name))
 
        response.mustcontain(
 
            """<a href="/%s">%s</a>""" % (urllib.parse.quote(fork_name), fork_name)
 
        )
 
        fork_repo = Repository.get_by_repo_name(fork_name)
 
        fork_repo = db.Repository.get_by_repo_name(fork_name)
 
        assert fork_repo
 

	
 
        # fork the fork
 
        fork_name_2 = self.REPO_FORK + '-blåbærgrød'
 
        creation_args = {
 
            'repo_name': fork_name_2,
 
@@ -190,52 +189,52 @@ class _BaseTestCase(base.TestController)
 

	
 
    def test_fork_create_and_permissions(self):
 
        self.log_user()
 
        fork_name = self.REPO_FORK
 
        description = 'fork of vcs test'
 
        repo_name = self.REPO
 
        org_repo = Repository.get_by_repo_name(repo_name)
 
        org_repo = db.Repository.get_by_repo_name(repo_name)
 
        creation_args = {
 
            'repo_name': fork_name,
 
            'repo_group': '-1',
 
            'fork_parent_id': org_repo.repo_id,
 
            'repo_type': self.REPO_TYPE,
 
            'description': description,
 
            'private': 'False',
 
            'landing_rev': 'rev:tip',
 
            '_session_csrf_secret_token': self.session_csrf_secret_token()}
 
        self.app.post(base.url(controller='forks', action='fork_create',
 
                          repo_name=repo_name), creation_args)
 
        repo = Repository.get_by_repo_name(self.REPO_FORK)
 
        repo = db.Repository.get_by_repo_name(self.REPO_FORK)
 
        assert repo.fork.repo_name == self.REPO
 

	
 
        ## run the check page that triggers the flash message
 
        response = self.app.get(base.url('repo_check_home', repo_name=fork_name))
 
        # test if we have a message that fork is ok
 
        self.checkSessionFlash(response,
 
                'Forked repository %s as <a href="/%s">%s</a>'
 
                % (repo_name, fork_name, fork_name))
 

	
 
        # test if the fork was created in the database
 
        fork_repo = meta.Session().query(Repository) \
 
            .filter(Repository.repo_name == fork_name).one()
 
        fork_repo = meta.Session().query(db.Repository) \
 
            .filter(db.Repository.repo_name == fork_name).one()
 

	
 
        assert fork_repo.repo_name == fork_name
 
        assert fork_repo.fork.repo_name == repo_name
 

	
 
        # test if the repository is visible in the list ?
 
        response = self.app.get(base.url('summary_home', repo_name=fork_name))
 
        response.mustcontain(fork_name)
 
        response.mustcontain(self.REPO_TYPE)
 
        response.mustcontain('Fork of "<a href="/%s">%s</a>"' % (repo_name, repo_name))
 

	
 
        usr = self.log_user(self.username, self.password)['user_id']
 

	
 
        forks = Repository.query() \
 
            .filter(Repository.repo_type == self.REPO_TYPE) \
 
            .filter(Repository.fork_id != None).all()
 
        forks = db.Repository.query() \
 
            .filter(db.Repository.repo_type == self.REPO_TYPE) \
 
            .filter(db.Repository.fork_id != None).all()
 
        assert 1 == len(forks)
 

	
 
        # set read permissions for this
 
        RepoModel().grant_user_permission(repo=forks[0],
 
                                          user=usr,
 
                                          perm='repository.read')
 
@@ -244,13 +243,13 @@ class _BaseTestCase(base.TestController)
 
        response = self.app.get(base.url(controller='forks', action='forks',
 
                                    repo_name=repo_name))
 

	
 
        response.mustcontain('<div>fork of vcs test</div>')
 

	
 
        # remove permissions
 
        default_user = User.get_default_user()
 
        default_user = db.User.get_default_user()
 
        try:
 
            RepoModel().grant_user_permission(repo=forks[0],
 
                                              user=usr, perm='repository.none')
 
            RepoModel().grant_user_permission(repo=forks[0],
 
                                              user=default_user, perm='repository.none')
 
            meta.Session().commit()
kallithea/tests/functional/test_journal.py
Show inline comments
 
@@ -10,18 +10,18 @@ class TestJournalController(base.TestCon
 
        response = self.app.get(base.url(controller='journal', action='index'))
 

	
 
        response.mustcontain("""<h4>%s</h4>""" % datetime.date.today())
 

	
 
    def test_stop_following_repository(self):
 
        session = self.log_user()
 
#        usr = Session().query(User).filter(User.username == TEST_USER_ADMIN_LOGIN).one()
 
#        repo = Session().query(Repository).filter(Repository.repo_name == HG_REPO).one()
 
#        usr = Session().query(User).filter(db.User.username == TEST_USER_ADMIN_LOGIN).one()
 
#        repo = Session().query(db.Repository).filter(db.Repository.repo_name == HG_REPO).one()
 
#
 
#        followings = Session().query(UserFollowing) \
 
#            .filter(UserFollowing.user == usr) \
 
#            .filter(UserFollowing.follows_repository == repo).all()
 
#        followings = Session().query(db.UserFollowing) \
 
#            .filter(db.UserFollowing.user == usr) \
 
#            .filter(db.UserFollowing.follows_repository == repo).all()
 
#
 
#        assert len(followings) == 1, 'Not following any repository'
 
#
 
#        response = self.app.post(base.url(controller='journal',
 
#                                     action='toggle_following'),
 
#                                     {'follows_repository_id':repo.repo_id})
kallithea/tests/functional/test_login.py
Show inline comments
 
@@ -7,15 +7,14 @@ import mock
 
from tg.util.webtest import test_context
 

	
 
import kallithea.lib.celerylib.tasks
 
from kallithea.lib import helpers as h
 
from kallithea.lib.auth import check_password
 
from kallithea.lib.utils2 import generate_api_key
 
from kallithea.model import meta, validators
 
from kallithea.model import db, meta, validators
 
from kallithea.model.api_key import ApiKeyModel
 
from kallithea.model.db import User
 
from kallithea.model.user import UserModel
 
from kallithea.tests import base
 
from kallithea.tests.fixture import Fixture
 

	
 

	
 
fixture = Fixture()
 
@@ -358,13 +357,13 @@ class TestLoginController(base.TestContr
 
                                             'lastname': lastname,
 
                                             'admin': True,
 
                                             '_session_csrf_secret_token': self.session_csrf_secret_token()})  # This should be overridden
 
        assert response.status == '302 Found'
 
        self.checkSessionFlash(response, 'You have successfully registered with Kallithea')
 

	
 
        ret = meta.Session().query(User).filter(User.username == 'test_regular4').one()
 
        ret = meta.Session().query(db.User).filter(db.User.username == 'test_regular4').one()
 
        assert ret.username == username
 
        assert check_password(password, ret.password) == True
 
        assert ret.email == email
 
        assert ret.name == name
 
        assert ret.lastname == lastname
 
        assert ret.api_key is not None
 
@@ -392,24 +391,24 @@ class TestLoginController(base.TestContr
 
        password = 'qweqwe'
 
        email = 'username@example.com'
 
        name = 'passwd'
 
        lastname = 'reset'
 
        timestamp = int(time.time())
 

	
 
        new = User()
 
        new = db.User()
 
        new.username = username
 
        new.password = password
 
        new.email = email
 
        new.name = name
 
        new.lastname = lastname
 
        new.api_key = generate_api_key()
 
        meta.Session().add(new)
 
        meta.Session().commit()
 

	
 
        token = UserModel().get_reset_password_token(
 
            User.get_by_username(username), timestamp, self.session_csrf_secret_token())
 
            db.User.get_by_username(username), timestamp, self.session_csrf_secret_token())
 

	
 
        collected = []
 
        def mock_send_email(recipients, subject, body='', html_body='', headers=None, from_name=None):
 
            collected.append((recipients, subject, body, html_body))
 

	
 
        with mock.patch.object(kallithea.lib.celerylib.tasks, 'send_email', mock_send_email), \
 
@@ -492,13 +491,13 @@ class TestLoginController(base.TestContr
 
        with fixture.anon_access(False):
 
            if api_key is None:
 
                params = {}
 
                headers = {}
 
            else:
 
                if api_key is True:
 
                    api_key = User.get_first_admin().api_key
 
                    api_key = db.User.get_first_admin().api_key
 
                params = {'api_key': api_key}
 
                headers = {'Authorization': 'Bearer ' + str(api_key)}
 

	
 
            self.app.get(base.url(controller='changeset', action='changeset_raw',
 
                             repo_name=base.HG_REPO, revision='tip', **params),
 
                         status=status)
kallithea/tests/functional/test_my_account.py
Show inline comments
 
# -*- coding: utf-8 -*-
 

	
 
from tg.util.webtest import test_context
 

	
 
from kallithea.lib import helpers as h
 
from kallithea.model import meta
 
from kallithea.model.db import Repository, User, UserApiKeys, UserFollowing, UserSshKeys
 
from kallithea.model import db, meta
 
from kallithea.model.user import UserModel
 
from kallithea.tests import base
 
from kallithea.tests.fixture import Fixture
 

	
 

	
 
fixture = Fixture()
 
@@ -15,36 +14,36 @@ fixture = Fixture()
 

	
 
class TestMyAccountController(base.TestController):
 
    test_user_1 = 'testme'
 

	
 
    @classmethod
 
    def teardown_class(cls):
 
        if User.get_by_username(cls.test_user_1):
 
        if db.User.get_by_username(cls.test_user_1):
 
            UserModel().delete(cls.test_user_1)
 
            meta.Session().commit()
 

	
 
    def test_my_account(self):
 
        self.log_user()
 
        response = self.app.get(base.url('my_account'))
 

	
 
        response.mustcontain('value="%s' % base.TEST_USER_ADMIN_LOGIN)
 

	
 
    def test_my_account_my_repos(self):
 
        self.log_user()
 
        response = self.app.get(base.url('my_account_repos'))
 
        cnt = Repository.query().filter(Repository.owner ==
 
                           User.get_by_username(base.TEST_USER_ADMIN_LOGIN)).count()
 
        cnt = db.Repository.query().filter(db.Repository.owner ==
 
                           db.User.get_by_username(base.TEST_USER_ADMIN_LOGIN)).count()
 
        response.mustcontain('"raw_name": "%s"' % base.HG_REPO)
 
        response.mustcontain('"just_name": "%s"' % base.GIT_REPO)
 

	
 
    def test_my_account_my_watched(self):
 
        self.log_user()
 
        response = self.app.get(base.url('my_account_watched'))
 

	
 
        cnt = UserFollowing.query().filter(UserFollowing.user ==
 
                            User.get_by_username(base.TEST_USER_ADMIN_LOGIN)).count()
 
        cnt = db.UserFollowing.query().filter(db.UserFollowing.user ==
 
                            db.User.get_by_username(base.TEST_USER_ADMIN_LOGIN)).count()
 
        response.mustcontain('"raw_name": "%s"' % base.HG_REPO)
 
        response.mustcontain('"just_name": "%s"' % base.GIT_REPO)
 

	
 
    def test_my_account_my_emails(self):
 
        self.log_user()
 
        response = self.app.get(base.url('my_account_emails'))
 
@@ -73,16 +72,15 @@ class TestMyAccountController(base.TestC
 

	
 
        response = self.app.post(base.url('my_account_emails'),
 
                                 {'new_email': 'barz@example.com', '_session_csrf_secret_token': self.session_csrf_secret_token()})
 

	
 
        response = self.app.get(base.url('my_account_emails'))
 

	
 
        from kallithea.model.db import UserEmailMap
 
        email_id = UserEmailMap.query() \
 
            .filter(UserEmailMap.user == User.get_by_username(base.TEST_USER_ADMIN_LOGIN)) \
 
            .filter(UserEmailMap.email == 'barz@example.com').one().email_id
 
        email_id = db.UserEmailMap.query() \
 
            .filter(db.UserEmailMap.user == db.User.get_by_username(base.TEST_USER_ADMIN_LOGIN)) \
 
            .filter(db.UserEmailMap.email == 'barz@example.com').one().email_id
 

	
 
        response.mustcontain('barz@example.com')
 
        response.mustcontain('<input id="del_email_id" name="del_email_id" type="hidden" value="%s" />' % email_id)
 

	
 
        response = self.app.post(base.url('my_account_emails_delete'),
 
                                 {'del_email_id': email_id, '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
@@ -125,13 +123,13 @@ class TestMyAccountController(base.TestC
 
        params.update(attrs)
 
        response = self.app.post(base.url('my_account'), params)
 

	
 
        self.checkSessionFlash(response,
 
                               'Your account was updated successfully')
 

	
 
        updated_user = User.get_by_username(self.test_user_1)
 
        updated_user = db.User.get_by_username(self.test_user_1)
 
        updated_params = updated_user.get_api_data(True)
 
        updated_params.update({'password_confirmation': ''})
 
        updated_params.update({'new_password': ''})
 

	
 
        params['last_login'] = updated_params['last_login']
 
        if name == 'email':
 
@@ -190,59 +188,59 @@ class TestMyAccountController(base.TestC
 
                    ._messages['username_exists']
 
        msg = h.html_escape(msg % {'username': base.TEST_USER_ADMIN_LOGIN})
 
        response.mustcontain(msg)
 

	
 
    def test_my_account_api_keys(self):
 
        usr = self.log_user(base.TEST_USER_REGULAR2_LOGIN, base.TEST_USER_REGULAR2_PASS)
 
        user = User.get(usr['user_id'])
 
        user = db.User.get(usr['user_id'])
 
        response = self.app.get(base.url('my_account_api_keys'))
 
        response.mustcontain(user.api_key)
 
        response.mustcontain('Expires: Never')
 

	
 
    @base.parametrize('desc,lifetime', [
 
        ('forever', -1),
 
        ('5mins', 60*5),
 
        ('30days', 60*60*24*30),
 
    ])
 
    def test_my_account_add_api_keys(self, desc, lifetime):
 
        usr = self.log_user(base.TEST_USER_REGULAR2_LOGIN, base.TEST_USER_REGULAR2_PASS)
 
        user = User.get(usr['user_id'])
 
        user = db.User.get(usr['user_id'])
 
        response = self.app.post(base.url('my_account_api_keys'),
 
                                 {'description': desc, 'lifetime': lifetime, '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'API key successfully created')
 
        try:
 
            response = response.follow()
 
            user = User.get(usr['user_id'])
 
            user = db.User.get(usr['user_id'])
 
            for api_key in user.api_keys:
 
                response.mustcontain(api_key)
 
        finally:
 
            for api_key in UserApiKeys.query().all():
 
            for api_key in db.UserApiKeys.query().all():
 
                meta.Session().delete(api_key)
 
                meta.Session().commit()
 

	
 
    def test_my_account_remove_api_key(self):
 
        usr = self.log_user(base.TEST_USER_REGULAR2_LOGIN, base.TEST_USER_REGULAR2_PASS)
 
        user = User.get(usr['user_id'])
 
        user = db.User.get(usr['user_id'])
 
        response = self.app.post(base.url('my_account_api_keys'),
 
                                 {'description': 'desc', 'lifetime': -1, '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'API key successfully created')
 
        response = response.follow()
 

	
 
        # now delete our key
 
        keys = UserApiKeys.query().all()
 
        keys = db.UserApiKeys.query().all()
 
        assert 1 == len(keys)
 

	
 
        response = self.app.post(base.url('my_account_api_keys_delete'),
 
                 {'del_api_key': keys[0].api_key, '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'API key successfully deleted')
 
        keys = UserApiKeys.query().all()
 
        keys = db.UserApiKeys.query().all()
 
        assert 0 == len(keys)
 

	
 
    def test_my_account_reset_main_api_key(self):
 
        usr = self.log_user(base.TEST_USER_REGULAR2_LOGIN, base.TEST_USER_REGULAR2_PASS)
 
        user = User.get(usr['user_id'])
 
        user = db.User.get(usr['user_id'])
 
        api_key = user.api_key
 
        response = self.app.get(base.url('my_account_api_keys'))
 
        response.mustcontain(api_key)
 
        response.mustcontain('Expires: Never')
 

	
 
        response = self.app.post(base.url('my_account_api_keys_delete'),
 
@@ -263,13 +261,13 @@ class TestMyAccountController(base.TestC
 
                                  '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'SSH key %s successfully added' % fingerprint)
 

	
 
        response = response.follow()
 
        response.mustcontain(fingerprint)
 
        user_id = response.session['authuser']['user_id']
 
        ssh_key = UserSshKeys.query().filter(UserSshKeys.user_id == user_id).one()
 
        ssh_key = db.UserSshKeys.query().filter(db.UserSshKeys.user_id == user_id).one()
 
        assert ssh_key.fingerprint == fingerprint
 
        assert ssh_key.description == description
 
        meta.Session().delete(ssh_key)
 
        meta.Session().commit()
 

	
 
    def test_my_account_remove_ssh_key(self):
 
@@ -282,15 +280,15 @@ class TestMyAccountController(base.TestC
 
                                 {'description': description,
 
                                  'public_key': public_key,
 
                                  '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'SSH key %s successfully added' % fingerprint)
 
        response.follow()
 
        user_id = response.session['authuser']['user_id']
 
        ssh_key = UserSshKeys.query().filter(UserSshKeys.user_id == user_id).one()
 
        ssh_key = db.UserSshKeys.query().filter(db.UserSshKeys.user_id == user_id).one()
 
        assert ssh_key.description == 'me@localhost'
 

	
 
        response = self.app.post(base.url('my_account_ssh_keys_delete'),
 
                                 {'del_public_key_fingerprint': ssh_key.fingerprint,
 
                                  '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'SSH key successfully deleted')
 
        keys = UserSshKeys.query().all()
 
        keys = db.UserSshKeys.query().all()
 
        assert 0 == len(keys)
kallithea/tests/functional/test_pullrequests.py
Show inline comments
 
import re
 

	
 
import pytest
 

	
 
from kallithea.controllers.pullrequests import PullrequestsController
 
from kallithea.model import meta
 
from kallithea.model.db import PullRequest, User
 
from kallithea.model import db, meta
 
from kallithea.tests import base
 
from kallithea.tests.fixture import Fixture
 

	
 

	
 
fixture = Fixture()
 

	
 
@@ -88,15 +87,15 @@ class TestPullrequestsController(base.Te
 
        assert response.status == '200 OK'
 
        response.mustcontain('No additional changesets found for iterating on this pull request')
 
        response.mustcontain('href="/vcs_test_hg/changeset/4f7e2131323e0749a740c0a56ab68ae9269c562a"')
 

	
 
    def test_update_reviewers(self):
 
        self.log_user()
 
        regular_user = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        regular_user2 = User.get_by_username(base.TEST_USER_REGULAR2_LOGIN)
 
        admin_user = User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        regular_user = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        regular_user2 = db.User.get_by_username(base.TEST_USER_REGULAR2_LOGIN)
 
        admin_user = db.User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 

	
 
        # create initial PR
 
        response = self.app.post(base.url(controller='pullrequests', action='create',
 
                                     repo_name=base.HG_REPO),
 
                                 {'org_repo': base.HG_REPO,
 
                                  'org_ref': 'rev:94f45ed825a1:94f45ed825a113e61af7e141f44ca578374abef0',
 
@@ -248,13 +247,13 @@ class TestPullrequestsController(base.Te
 
                'pullrequest_title': 'title',
 
                'pullrequest_desc': 'description',
 
                '_session_csrf_secret_token': self.session_csrf_secret_token(),
 
            },
 
            status=302)
 
        pr1_id = int(re.search(r'/pull-request/(\d+)/', response.location).group(1))
 
        pr1 = PullRequest.get(pr1_id)
 
        pr1 = db.PullRequest.get(pr1_id)
 

	
 
        assert pr1.org_ref == 'branch:webvcs:9e6119747791ff886a5abe1193a730b6bf874e1c'
 
        assert pr1.other_ref == 'branch:default:948da46b29c125838a717f6a8496eb409717078d'
 

	
 
        meta.Session().rollback() # invalidate loaded PR objects before issuing next request.
 

	
 
@@ -267,17 +266,17 @@ class TestPullrequestsController(base.Te
 
                'pullrequest_desc': 'description',
 
                'owner': base.TEST_USER_REGULAR_LOGIN,
 
                '_session_csrf_secret_token': self.session_csrf_secret_token(),
 
             },
 
             status=302)
 
        pr2_id = int(re.search(r'/pull-request/(\d+)/', response.location).group(1))
 
        pr1 = PullRequest.get(pr1_id)
 
        pr2 = PullRequest.get(pr2_id)
 
        pr1 = db.PullRequest.get(pr1_id)
 
        pr2 = db.PullRequest.get(pr2_id)
 

	
 
        assert pr2_id != pr1_id
 
        assert pr1.status == PullRequest.STATUS_CLOSED
 
        assert pr1.status == db.PullRequest.STATUS_CLOSED
 
        assert pr2.org_ref == 'branch:webvcs:5ec21f21aafe95220f1fc4843a4a57c378498b71'
 
        assert pr2.other_ref == pr1.other_ref
 

	
 
        meta.Session().rollback() # invalidate loaded PR objects before issuing next request.
 

	
 
        # create PR 3 (new iteration with new ancestor)
 
@@ -289,17 +288,17 @@ class TestPullrequestsController(base.Te
 
                'pullrequest_desc': 'description',
 
                'owner': base.TEST_USER_REGULAR_LOGIN,
 
                '_session_csrf_secret_token': self.session_csrf_secret_token(),
 
             },
 
             status=302)
 
        pr3_id = int(re.search(r'/pull-request/(\d+)/', response.location).group(1))
 
        pr2 = PullRequest.get(pr2_id)
 
        pr3 = PullRequest.get(pr3_id)
 
        pr2 = db.PullRequest.get(pr2_id)
 
        pr3 = db.PullRequest.get(pr3_id)
 

	
 
        assert pr3_id != pr2_id
 
        assert pr2.status == PullRequest.STATUS_CLOSED
 
        assert pr2.status == db.PullRequest.STATUS_CLOSED
 
        assert pr3.org_ref == 'branch:webvcs:fb95b340e0d03fa51f33c56c991c08077c99303e'
 
        assert pr3.other_ref == 'branch:default:41d2568309a05f422cffb8008e599d385f8af439'
 

	
 

	
 
@pytest.mark.usefixtures("test_context_fixture") # apply fixture for all test methods
 
class TestPullrequestsGetRepoRefs(base.TestController):
kallithea/tests/functional/test_summary.py
Show inline comments
 
@@ -11,14 +11,13 @@
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import pytest
 

	
 
from kallithea.model import meta
 
from kallithea.model.db import Repository
 
from kallithea.model import db, meta
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.scm import ScmModel
 
from kallithea.tests import base
 
from kallithea.tests.fixture import Fixture
 

	
 

	
 
@@ -33,13 +32,13 @@ def custom_settings(set_test_settings):
 

	
 

	
 
class TestSummaryController(base.TestController):
 

	
 
    def test_index_hg(self, custom_settings):
 
        self.log_user()
 
        ID = Repository.get_by_repo_name(base.HG_REPO).repo_id
 
        ID = db.Repository.get_by_repo_name(base.HG_REPO).repo_id
 
        response = self.app.get(base.url(controller='summary',
 
                                    action='index',
 
                                    repo_name=base.HG_REPO))
 

	
 
        # repo type
 
        response.mustcontain(
 
@@ -63,13 +62,13 @@ class TestSummaryController(base.TestCon
 
            (base.HG_REPO)
 
        )
 

	
 

	
 
    def test_index_git(self, custom_settings):
 
        self.log_user()
 
        ID = Repository.get_by_repo_name(base.GIT_REPO).repo_id
 
        ID = db.Repository.get_by_repo_name(base.GIT_REPO).repo_id
 
        response = self.app.get(base.url(controller='summary',
 
                                    action='index',
 
                                    repo_name=base.GIT_REPO))
 

	
 
        # repo type
 
        response.mustcontain(
 
@@ -92,13 +91,13 @@ class TestSummaryController(base.TestCon
 
            '''<input id="ssh_url" class="form-control" size="80" readonly="readonly" value="ssh://ssh_user@ssh_hostname/%s"/>''' %
 
            (base.GIT_REPO)
 
        )
 

	
 
    def test_index_by_id_hg(self):
 
        self.log_user()
 
        ID = Repository.get_by_repo_name(base.HG_REPO).repo_id
 
        ID = db.Repository.get_by_repo_name(base.HG_REPO).repo_id
 
        response = self.app.get(base.url(controller='summary',
 
                                    action='index',
 
                                    repo_name='_%s' % ID))
 

	
 
        # repo type
 
        response.mustcontain(
 
@@ -116,18 +115,18 @@ class TestSummaryController(base.TestCon
 
                                    action='index',
 
                                    repo_name='repo_1'))
 

	
 
        try:
 
            response.mustcontain("repo_1")
 
        finally:
 
            RepoModel().delete(Repository.get_by_repo_name('repo_1'))
 
            RepoModel().delete(db.Repository.get_by_repo_name('repo_1'))
 
            meta.Session().commit()
 

	
 
    def test_index_by_id_git(self):
 
        self.log_user()
 
        ID = Repository.get_by_repo_name(base.GIT_REPO).repo_id
 
        ID = db.Repository.get_by_repo_name(base.GIT_REPO).repo_id
 
        response = self.app.get(base.url(controller='summary',
 
                                    action='index',
 
                                    repo_name='_%s' % ID))
 

	
 
        # repo type
 
        response.mustcontain(
 
@@ -136,13 +135,13 @@ class TestSummaryController(base.TestCon
 
        # public/private
 
        response.mustcontain(
 
            """<i class="icon-globe">"""
 
        )
 

	
 
    def _enable_stats(self, repo):
 
        r = Repository.get_by_repo_name(repo)
 
        r = db.Repository.get_by_repo_name(repo)
 
        r.enable_statistics = True
 
        meta.Session().commit()
 

	
 
    def test_index_trending(self):
 
        self.log_user()
 
        # codes stats
kallithea/tests/models/common.py
Show inline comments
 
from kallithea.lib.auth import AuthUser
 
from kallithea.model import meta
 
from kallithea.model.db import RepoGroup, Repository, User
 
from kallithea.model import db, meta
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.repo_group import RepoGroupModel
 
from kallithea.model.user import UserModel
 
from kallithea.tests.fixture import Fixture
 

	
 

	
 
fixture = Fixture()
 

	
 

	
 
def _destroy_project_tree(test_u1_id):
 
    meta.Session.remove()
 
    repo_group = RepoGroup.get_by_group_name(group_name='g0')
 
    repo_group = db.RepoGroup.get_by_group_name(group_name='g0')
 
    for el in reversed(repo_group.recursive_groups_and_repos()):
 
        if isinstance(el, Repository):
 
        if isinstance(el, db.Repository):
 
            RepoModel().delete(el)
 
        elif isinstance(el, RepoGroup):
 
        elif isinstance(el, db.RepoGroup):
 
            RepoGroupModel().delete(el, force_delete=True)
 

	
 
    u = User.get(test_u1_id)
 
    u = db.User.get(test_u1_id)
 
    meta.Session().delete(u)
 
    meta.Session().commit()
 

	
 

	
 
def _create_project_tree():
 
    """
 
@@ -67,13 +66,13 @@ def _create_project_tree():
 
    g0_3_r2_private = fixture.create_repo('g0/g0_3/g0_3_r1_private',
 
                                          repo_group=g0_3, repo_private=True)
 
    return test_u1
 

	
 

	
 
def expected_count(group_name, objects=False):
 
    repo_group = RepoGroup.get_by_group_name(group_name=group_name)
 
    repo_group = db.RepoGroup.get_by_group_name(group_name=group_name)
 
    objs = repo_group.recursive_groups_and_repos()
 
    if objects:
 
        return objs
 
    return len(objs)
 

	
 

	
kallithea/tests/models/test_changeset_status.py
Show inline comments
 
from kallithea.model import db
 
from kallithea.model.changeset_status import ChangesetStatusModel
 
from kallithea.model.db import ChangesetStatus as CS
 
from kallithea.tests import base
 

	
 

	
 
STATUS_UNDER_REVIEW = db.ChangesetStatus.STATUS_UNDER_REVIEW
 
STATUS_APPROVED = db.ChangesetStatus.STATUS_APPROVED
 
STATUS_REJECTED = db.ChangesetStatus.STATUS_REJECTED
 
STATUS_NOT_REVIEWED = db.ChangesetStatus.STATUS_NOT_REVIEWED
 

	
 

	
 
class CSM(object): # ChangesetStatusMock
 

	
 
    def __init__(self, status):
 
        self.status = status
 

	
 

	
 
class TestChangesetStatusCalculation(base.TestController):
 

	
 
    def setup_method(self, method):
 
        self.m = ChangesetStatusModel()
 

	
 
    @base.parametrize('name,expected_result,statuses', [
 
        ('empty list', CS.STATUS_UNDER_REVIEW, []),
 
        ('approve', CS.STATUS_APPROVED, [CSM(CS.STATUS_APPROVED)]),
 
        ('approve2', CS.STATUS_APPROVED, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_APPROVED)]),
 
        ('approve_reject', CS.STATUS_REJECTED, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_REJECTED)]),
 
        ('approve_underreview', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_UNDER_REVIEW)]),
 
        ('approve_notreviewed', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_NOT_REVIEWED)]),
 
        ('underreview', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_UNDER_REVIEW), CSM(CS.STATUS_UNDER_REVIEW)]),
 
        ('reject', CS.STATUS_REJECTED, [CSM(CS.STATUS_REJECTED)]),
 
        ('reject_underreview', CS.STATUS_REJECTED, [CSM(CS.STATUS_REJECTED), CSM(CS.STATUS_UNDER_REVIEW)]),
 
        ('reject_notreviewed', CS.STATUS_REJECTED, [CSM(CS.STATUS_REJECTED), CSM(CS.STATUS_NOT_REVIEWED)]),
 
        ('notreviewed', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_NOT_REVIEWED)]),
 
        ('approve_none', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_APPROVED), None]),
 
        ('approve2_none', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_APPROVED), None]),
 
        ('approve_reject_none', CS.STATUS_REJECTED, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_REJECTED), None]),
 
        ('approve_underreview_none', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_UNDER_REVIEW), None]),
 
        ('approve_notreviewed_none', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_APPROVED), CSM(CS.STATUS_NOT_REVIEWED), None]),
 
        ('underreview_none', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_UNDER_REVIEW), CSM(CS.STATUS_UNDER_REVIEW), None]),
 
        ('reject_none', CS.STATUS_REJECTED, [CSM(CS.STATUS_REJECTED), None]),
 
        ('reject_underreview_none', CS.STATUS_REJECTED, [CSM(CS.STATUS_REJECTED), CSM(CS.STATUS_UNDER_REVIEW), None]),
 
        ('reject_notreviewed_none', CS.STATUS_REJECTED, [CSM(CS.STATUS_REJECTED), CSM(CS.STATUS_NOT_REVIEWED), None]),
 
        ('notreviewed_none', CS.STATUS_UNDER_REVIEW, [CSM(CS.STATUS_NOT_REVIEWED), None]),
 
        ('empty list', STATUS_UNDER_REVIEW, []),
 
        ('approve', STATUS_APPROVED, [CSM(STATUS_APPROVED)]),
 
        ('approve2', STATUS_APPROVED, [CSM(STATUS_APPROVED), CSM(STATUS_APPROVED)]),
 
        ('approve_reject', STATUS_REJECTED, [CSM(STATUS_APPROVED), CSM(STATUS_REJECTED)]),
 
        ('approve_underreview', STATUS_UNDER_REVIEW, [CSM(STATUS_APPROVED), CSM(STATUS_UNDER_REVIEW)]),
 
        ('approve_notreviewed', STATUS_UNDER_REVIEW, [CSM(STATUS_APPROVED), CSM(STATUS_NOT_REVIEWED)]),
 
        ('underreview', STATUS_UNDER_REVIEW, [CSM(STATUS_UNDER_REVIEW), CSM(STATUS_UNDER_REVIEW)]),
 
        ('reject', STATUS_REJECTED, [CSM(STATUS_REJECTED)]),
 
        ('reject_underreview', STATUS_REJECTED, [CSM(STATUS_REJECTED), CSM(STATUS_UNDER_REVIEW)]),
 
        ('reject_notreviewed', STATUS_REJECTED, [CSM(STATUS_REJECTED), CSM(STATUS_NOT_REVIEWED)]),
 
        ('notreviewed', STATUS_UNDER_REVIEW, [CSM(STATUS_NOT_REVIEWED)]),
 
        ('approve_none', STATUS_UNDER_REVIEW, [CSM(STATUS_APPROVED), None]),
 
        ('approve2_none', STATUS_UNDER_REVIEW, [CSM(STATUS_APPROVED), CSM(STATUS_APPROVED), None]),
 
        ('approve_reject_none', STATUS_REJECTED, [CSM(STATUS_APPROVED), CSM(STATUS_REJECTED), None]),
 
        ('approve_underreview_none', STATUS_UNDER_REVIEW, [CSM(STATUS_APPROVED), CSM(STATUS_UNDER_REVIEW), None]),
 
        ('approve_notreviewed_none', STATUS_UNDER_REVIEW, [CSM(STATUS_APPROVED), CSM(STATUS_NOT_REVIEWED), None]),
 
        ('underreview_none', STATUS_UNDER_REVIEW, [CSM(STATUS_UNDER_REVIEW), CSM(STATUS_UNDER_REVIEW), None]),
 
        ('reject_none', STATUS_REJECTED, [CSM(STATUS_REJECTED), None]),
 
        ('reject_underreview_none', STATUS_REJECTED, [CSM(STATUS_REJECTED), CSM(STATUS_UNDER_REVIEW), None]),
 
        ('reject_notreviewed_none', STATUS_REJECTED, [CSM(STATUS_REJECTED), CSM(STATUS_NOT_REVIEWED), None]),
 
        ('notreviewed_none', STATUS_UNDER_REVIEW, [CSM(STATUS_NOT_REVIEWED), None]),
 
    ])
 
    def test_result(self, name, expected_result, statuses):
 
        result = self.m._calculate_status(statuses)
 
        assert result == expected_result
kallithea/tests/models/test_comments.py
Show inline comments
 
import pytest
 
from tg.util.webtest import test_context
 

	
 
from kallithea.model import db
 
from kallithea.model.comment import ChangesetCommentsModel
 
from kallithea.model.db import Repository
 
from kallithea.tests import base
 

	
 

	
 
class TestComments(base.TestController):
 

	
 
    def _check_comment_count(self, repo_id, revision,
 
@@ -20,13 +20,13 @@ class TestComments(base.TestController):
 
        assert len(inline_comments) == expected_len_inline_comments
 

	
 
        return comments, inline_comments
 

	
 
    def test_create_delete_general_comment(self):
 
        with test_context(self.app):
 
            repo_id = Repository.get_by_repo_name(base.HG_REPO).repo_id
 
            repo_id = db.Repository.get_by_repo_name(base.HG_REPO).repo_id
 
            revision = '9a7b4ff9e8b40bbda72fc75f162325b9baa45cda'
 

	
 
            self._check_comment_count(repo_id, revision,
 
                    expected_len_comments=0, expected_len_inline_comments=0)
 

	
 
            text = 'a comment'
 
@@ -44,13 +44,13 @@ class TestComments(base.TestController):
 

	
 
            self._check_comment_count(repo_id, revision,
 
                    expected_len_comments=0, expected_len_inline_comments=0)
 

	
 
    def test_create_delete_inline_comment(self):
 
        with test_context(self.app):
 
            repo_id = Repository.get_by_repo_name(base.HG_REPO).repo_id
 
            repo_id = db.Repository.get_by_repo_name(base.HG_REPO).repo_id
 
            revision = '9a7b4ff9e8b40bbda72fc75f162325b9baa45cda'
 

	
 
            self._check_comment_count(repo_id, revision,
 
                    expected_len_comments=0, expected_len_inline_comments=0)
 

	
 
            text = 'an inline comment'
 
@@ -78,13 +78,13 @@ class TestComments(base.TestController):
 

	
 
            self._check_comment_count(repo_id, revision,
 
                    expected_len_comments=0, expected_len_inline_comments=0)
 

	
 
    def test_create_delete_multiple_inline_comments(self):
 
        with test_context(self.app):
 
            repo_id = Repository.get_by_repo_name(base.HG_REPO).repo_id
 
            repo_id = db.Repository.get_by_repo_name(base.HG_REPO).repo_id
 
            revision = '9a7b4ff9e8b40bbda72fc75f162325b9baa45cda'
 

	
 
            self._check_comment_count(repo_id, revision,
 
                    expected_len_comments=0, expected_len_inline_comments=0)
 

	
 
            text = 'an inline comment'
 
@@ -158,13 +158,13 @@ class TestComments(base.TestController):
 

	
 
            self._check_comment_count(repo_id, revision,
 
                    expected_len_comments=0, expected_len_inline_comments=0)
 

	
 
    def test_selective_retrieval_of_inline_comments(self):
 
        with test_context(self.app):
 
            repo_id = Repository.get_by_repo_name(base.HG_REPO).repo_id
 
            repo_id = db.Repository.get_by_repo_name(base.HG_REPO).repo_id
 
            revision = '9a7b4ff9e8b40bbda72fc75f162325b9baa45cda'
 

	
 
            self._check_comment_count(repo_id, revision,
 
                    expected_len_comments=0, expected_len_inline_comments=0)
 

	
 
            text = 'an inline comment'
kallithea/tests/models/test_notifications.py
Show inline comments
 
@@ -4,14 +4,13 @@ import re
 
import mock
 
from tg.util.webtest import test_context
 

	
 
import kallithea.lib.celerylib
 
import kallithea.lib.celerylib.tasks
 
from kallithea.lib import helpers as h
 
from kallithea.model import meta
 
from kallithea.model.db import User
 
from kallithea.model import db, meta
 
from kallithea.model.notification import EmailNotificationModel, NotificationModel
 
from kallithea.model.user import UserModel
 
from kallithea.tests import base
 

	
 

	
 
class TestNotifications(base.TestController):
 
@@ -81,13 +80,13 @@ class TestNotifications(base.TestControl
 
                    pr_title_short='The Title',
 
                    pr_url='http://pr.org/7',
 
                    pr_target_repo='http://mainline.com/repo',
 
                    pr_target_branch='trunk',
 
                    pr_source_repo='https://dev.org/repo',
 
                    pr_source_branch='devbranch',
 
                    pr_owner=User.get(self.u2),
 
                    pr_owner=db.User.get(self.u2),
 
                    pr_owner_username='u2'
 
                    )
 

	
 
                for type_, body, kwargs in [
 
                        (NotificationModel.TYPE_CHANGESET_COMMENT,
 
                         'This is the new \'comment\'.\n\n - and here it ends indented.',
 
@@ -100,14 +99,14 @@ class TestNotifications(base.TestControl
 
                            is_mention=[False, True],
 
                            message='This changeset did something clever which is hard to explain',
 
                            message_short='This changeset did something cl...',
 
                            status_change=[None, 'Approved'],
 
                            cs_target_repo='http://example.com/repo_target',
 
                            cs_url='http://changeset.com',
 
                            cs_author_username=User.get(self.u2).username,
 
                            cs_author=User.get(self.u2))),
 
                            cs_author_username=db.User.get(self.u2).username,
 
                            cs_author=db.User.get(self.u2))),
 
                        (NotificationModel.TYPE_MESSAGE,
 
                         'This is the \'body\' of the "test" message\n - nothing interesting here except indentation.',
 
                         dict()),
 
                        #(NotificationModel.TYPE_MENTION, '$body', None), # not used
 
                        (NotificationModel.TYPE_REGISTRATION,
 
                         'Registration body',
 
@@ -157,13 +156,13 @@ class TestNotifications(base.TestControl
 
                desc = 'TYPE_PASSWORD_RESET'
 
                kwargs = dict(user='John Doe', reset_token='decbf64715098db5b0bd23eab44bd792670ab746', reset_url='http://reset.com/decbf64715098db5b0bd23eab44bd792670ab746')
 
                kallithea.lib.celerylib.tasks.send_email(['john@doe.com'],
 
                    "Password reset link",
 
                    EmailNotificationModel().get_email_tmpl(EmailNotificationModel.TYPE_PASSWORD_RESET, 'txt', **kwargs),
 
                    EmailNotificationModel().get_email_tmpl(EmailNotificationModel.TYPE_PASSWORD_RESET, 'html', **kwargs),
 
                    from_name=User.get(self.u1).full_name_or_username)
 
                    from_name=db.User.get(self.u1).full_name_or_username)
 

	
 
        out = '<!doctype html>\n<html lang="en">\n<head><title>Notifications</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>\n<body>\n%s\n</body>\n</html>\n' % \
 
            re.sub(r'<(/?(?:!doctype|html|head|title|meta|body)\b[^>]*)>', r'<!--\1-->', ''.join(l))
 

	
 
        outfn = os.path.join(os.path.dirname(__file__), 'test_dump_html_mails.out.html')
 
        reffn = os.path.join(os.path.dirname(__file__), 'test_dump_html_mails.ref.html')
kallithea/tests/models/test_permissions.py
Show inline comments
 
import kallithea
 
from kallithea.lib.auth import AuthUser
 
from kallithea.model import meta
 
from kallithea.model.db import Permission, User, UserGroupRepoGroupToPerm, UserToPerm
 
from kallithea.model import db, meta
 
from kallithea.model.permission import PermissionModel
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.repo_group import RepoGroupModel
 
from kallithea.model.user import UserModel
 
from kallithea.model.user_group import UserGroupModel
 
from kallithea.tests import base
 
@@ -16,13 +15,13 @@ fixture = Fixture()
 

	
 
class TestPermissions(base.TestController):
 

	
 
    @classmethod
 
    def setup_class(cls):
 
        # recreate default user to get a clean start
 
        PermissionModel().create_default_permissions(user=User.DEFAULT_USER_NAME,
 
        PermissionModel().create_default_permissions(user=db.User.DEFAULT_USER_NAME,
 
                                                     force=True)
 
        meta.Session().commit()
 

	
 
    def setup_method(self, method):
 
        self.u1 = UserModel().create_or_update(
 
            username='u1', password='qweqwe',
 
@@ -33,13 +32,13 @@ class TestPermissions(base.TestControlle
 
            email='u2@example.com', firstname='u2', lastname='u2'
 
        )
 
        self.u3 = UserModel().create_or_update(
 
            username='u3', password='qweqwe',
 
            email='u3@example.com', firstname='u3', lastname='u3'
 
        )
 
        self.anon = User.get_default_user()
 
        self.anon = db.User.get_default_user()
 
        self.a1 = UserModel().create_or_update(
 
            username='a1', password='qweqwe',
 
            email='a1@example.com', firstname='a1', lastname='a1', admin=True
 
        )
 
        meta.Session().commit()
 

	
 
@@ -93,13 +92,13 @@ class TestPermissions(base.TestControlle
 
        self.g1 = fixture.create_repo_group('test1', skip_if_exists=True)
 
        self.g2 = fixture.create_repo_group('test2', skip_if_exists=True)
 
        u1_auth = AuthUser(user_id=self.u1.user_id)
 
        assert u1_auth.repository_permissions[base.HG_REPO] == 'repository.read'
 
        assert u1_auth.repository_group_permissions.get('test1') == 'group.read'
 
        assert u1_auth.repository_group_permissions.get('test2') == 'group.read'
 
        assert u1_auth.global_permissions == set(Permission.DEFAULT_USER_PERMISSIONS)
 
        assert u1_auth.global_permissions == set(db.Permission.DEFAULT_USER_PERMISSIONS)
 

	
 
    def test_default_admin_group_perms(self):
 
        self.g1 = fixture.create_repo_group('test1', skip_if_exists=True)
 
        self.g2 = fixture.create_repo_group('test2', skip_if_exists=True)
 
        a1_auth = AuthUser(user_id=self.a1.user_id)
 
        assert a1_auth.repository_permissions[base.HG_REPO] == 'repository.admin'
 
@@ -259,15 +258,15 @@ class TestPermissions(base.TestControlle
 
        # grant ug1 read permissions for
 
        RepoGroupModel().grant_user_group_permission(repo_group=self.g1,
 
                                                      group_name=self.ug1,
 
                                                      perm='group.read')
 
        meta.Session().commit()
 
        # check if the
 
        obj = meta.Session().query(UserGroupRepoGroupToPerm) \
 
            .filter(UserGroupRepoGroupToPerm.group == self.g1) \
 
            .filter(UserGroupRepoGroupToPerm.users_group == self.ug1) \
 
        obj = meta.Session().query(db.UserGroupRepoGroupToPerm) \
 
            .filter(db.UserGroupRepoGroupToPerm.group == self.g1) \
 
            .filter(db.UserGroupRepoGroupToPerm.users_group == self.ug1) \
 
            .scalar()
 
        assert obj.permission.permission_name == 'group.read'
 

	
 
        a1_auth = AuthUser(user_id=self.anon.user_id)
 

	
 
        assert a1_auth.repository_group_permissions.get('group1') == 'group.none'
 
@@ -589,27 +588,27 @@ class TestPermissions(base.TestControlle
 
                                          perm='repository.none')
 
        meta.Session().commit()
 
        u1_auth = AuthUser(user_id=self.u1.user_id)
 
        assert u1_auth.repository_permissions['myownrepo'] == 'repository.admin'
 

	
 
    def _test_def_perm_equal(self, user, change_factor=0):
 
        perms = UserToPerm.query() \
 
                .filter(UserToPerm.user == user) \
 
        perms = db.UserToPerm.query() \
 
                .filter(db.UserToPerm.user == user) \
 
                .all()
 
        assert len(perms) == len(Permission.DEFAULT_USER_PERMISSIONS,)+change_factor, perms
 
        assert len(perms) == len(db.Permission.DEFAULT_USER_PERMISSIONS,)+change_factor, perms
 

	
 
    def test_set_default_permissions(self):
 
        PermissionModel().create_default_permissions(user=self.u1)
 
        self._test_def_perm_equal(user=self.u1)
 

	
 
    def test_set_default_permissions_after_one_is_missing(self):
 
        PermissionModel().create_default_permissions(user=self.u1)
 
        self._test_def_perm_equal(user=self.u1)
 
        # now we delete one, it should be re-created after another call
 
        perms = UserToPerm.query() \
 
                .filter(UserToPerm.user == self.u1) \
 
        perms = db.UserToPerm.query() \
 
                .filter(db.UserToPerm.user == self.u1) \
 
                .all()
 
        meta.Session().delete(perms[0])
 
        meta.Session().commit()
 

	
 
        self._test_def_perm_equal(user=self.u1, change_factor=-1)
 

	
 
@@ -626,21 +625,21 @@ class TestPermissions(base.TestControlle
 
        ('hg.register.manual_activate', 'hg.register.auto_activate',)
 
    ])
 
    def test_set_default_permissions_after_modification(self, perm, modify_to):
 
        PermissionModel().create_default_permissions(user=self.u1)
 
        self._test_def_perm_equal(user=self.u1)
 

	
 
        old = Permission.get_by_key(perm)
 
        new = Permission.get_by_key(modify_to)
 
        old = db.Permission.get_by_key(perm)
 
        new = db.Permission.get_by_key(modify_to)
 
        assert old is not None
 
        assert new is not None
 

	
 
        # now modify permissions
 
        p = UserToPerm.query() \
 
                .filter(UserToPerm.user == self.u1) \
 
                .filter(UserToPerm.permission == old) \
 
        p = db.UserToPerm.query() \
 
                .filter(db.UserToPerm.user == self.u1) \
 
                .filter(db.UserToPerm.permission == old) \
 
                .one()
 
        p.permission = new
 
        meta.Session().commit()
 

	
 
        PermissionModel().create_default_permissions(user=self.u1)
 
        self._test_def_perm_equal(user=self.u1)
kallithea/tests/models/test_repo_groups.py
Show inline comments
 
import os
 

	
 
import pytest
 
from sqlalchemy.exc import IntegrityError
 

	
 
import kallithea
 
from kallithea.model import meta
 
from kallithea.model.db import RepoGroup
 
from kallithea.model import db, meta
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.repo_group import RepoGroupModel
 
from kallithea.tests import base
 
from kallithea.tests.fixture import Fixture
 

	
 

	
 
@@ -80,44 +79,44 @@ class TestRepoGroups(base.TestController
 
        assert self.__check_path('test1', 'sub1', 'subsub1')
 

	
 
    def test_remove_group(self):
 
        sg1 = fixture.create_repo_group('deleteme')
 
        self.__delete_group(sg1.group_id)
 

	
 
        assert RepoGroup.get(sg1.group_id) is None
 
        assert db.RepoGroup.get(sg1.group_id) is None
 
        assert not self.__check_path('deteteme')
 

	
 
        sg1 = fixture.create_repo_group('deleteme', parent_group_id=self.g1.group_id)
 
        self.__delete_group(sg1.group_id)
 

	
 
        assert RepoGroup.get(sg1.group_id) is None
 
        assert db.RepoGroup.get(sg1.group_id) is None
 
        assert not self.__check_path('test1', 'deteteme')
 

	
 
    def test_rename_single_group(self):
 
        sg1 = fixture.create_repo_group('initial')
 

	
 
        new_sg1 = _update_repo_group(sg1.group_id, 'after')
 
        assert self.__check_path('after')
 
        assert RepoGroup.get_by_group_name('initial') is None
 
        assert db.RepoGroup.get_by_group_name('initial') is None
 

	
 
    def test_update_group_parent(self):
 

	
 
        sg1 = fixture.create_repo_group('initial', parent_group_id=self.g1.group_id)
 

	
 
        new_sg1 = _update_repo_group(sg1.group_id, 'after', parent_id=self.g1.group_id)
 
        assert self.__check_path('test1', 'after')
 
        assert RepoGroup.get_by_group_name('test1/initial') is None
 
        assert db.RepoGroup.get_by_group_name('test1/initial') is None
 

	
 
        new_sg1 = _update_repo_group(sg1.group_id, 'after', parent_id=self.g3.group_id)
 
        assert self.__check_path('test3', 'after')
 
        assert RepoGroup.get_by_group_name('test3/initial') == None
 
        assert db.RepoGroup.get_by_group_name('test3/initial') == None
 

	
 
        new_sg1 = _update_repo_group(sg1.group_id, 'hello')
 
        assert self.__check_path('hello')
 

	
 
        assert RepoGroup.get_by_group_name('hello') == new_sg1
 
        assert db.RepoGroup.get_by_group_name('hello') == new_sg1
 

	
 
    def test_subgrouping_with_repo(self):
 

	
 
        g1 = fixture.create_repo_group('g1')
 
        g2 = fixture.create_repo_group('g2')
 
        # create new repo
kallithea/tests/models/test_repos.py
Show inline comments
 
import pytest
 

	
 
from kallithea.lib.exceptions import AttachedForksError
 
from kallithea.model import meta
 
from kallithea.model.db import Repository
 
from kallithea.model import db, meta
 
from kallithea.model.repo import RepoModel
 
from kallithea.tests import base
 
from kallithea.tests.fixture import Fixture
 

	
 

	
 
fixture = Fixture()
 
@@ -20,13 +19,13 @@ class TestRepos(base.TestController):
 
        repo = fixture.create_repo(name='test-repo-1')
 
        meta.Session().commit()
 

	
 
        RepoModel().delete(repo=repo)
 
        meta.Session().commit()
 

	
 
        assert Repository.get_by_repo_name(repo_name='test-repo-1') is None
 
        assert db.Repository.get_by_repo_name(repo_name='test-repo-1') is None
 

	
 
    def test_remove_repo_repo_raises_exc_when_attached_forks(self):
 
        repo = fixture.create_repo(name='test-repo-1')
 
        meta.Session().commit()
 

	
 
        fixture.create_fork(repo.repo_name, 'test-repo-fork-1')
 
@@ -50,15 +49,15 @@ class TestRepos(base.TestController):
 
        fixture.create_fork(fork.repo_name, 'test-repo-fork-fork-1')
 
        meta.Session().commit()
 

	
 
        RepoModel().delete(repo=repo, forks='delete')
 
        meta.Session().commit()
 

	
 
        assert Repository.get_by_repo_name(repo_name='test-repo-1') is None
 
        assert Repository.get_by_repo_name(repo_name='test-repo-fork-1') is None
 
        assert Repository.get_by_repo_name(repo_name='test-repo-fork-fork-1') is None
 
        assert db.Repository.get_by_repo_name(repo_name='test-repo-1') is None
 
        assert db.Repository.get_by_repo_name(repo_name='test-repo-fork-1') is None
 
        assert db.Repository.get_by_repo_name(repo_name='test-repo-fork-fork-1') is None
 

	
 
    def test_remove_repo_detach_forks(self):
 
        repo = fixture.create_repo(name='test-repo-1')
 
        meta.Session().commit()
 

	
 
        fork = fixture.create_fork(repo.repo_name, 'test-repo-fork-1')
 
@@ -69,13 +68,13 @@ class TestRepos(base.TestController):
 
        meta.Session().commit()
 

	
 
        RepoModel().delete(repo=repo, forks='detach')
 
        meta.Session().commit()
 

	
 
        try:
 
            assert Repository.get_by_repo_name(repo_name='test-repo-1') is None
 
            assert Repository.get_by_repo_name(repo_name='test-repo-fork-1') is not None
 
            assert Repository.get_by_repo_name(repo_name='test-repo-fork-fork-1') is not None
 
            assert db.Repository.get_by_repo_name(repo_name='test-repo-1') is None
 
            assert db.Repository.get_by_repo_name(repo_name='test-repo-fork-1') is not None
 
            assert db.Repository.get_by_repo_name(repo_name='test-repo-fork-fork-1') is not None
 
        finally:
 
            RepoModel().delete(repo='test-repo-fork-fork-1')
 
            RepoModel().delete(repo='test-repo-fork-1')
 
            meta.Session().commit()
kallithea/tests/models/test_settings.py
Show inline comments
 
from kallithea.model import meta
 
from kallithea.model.db import Setting
 
from kallithea.model import db, meta
 

	
 

	
 
name = 'spam-setting-name'
 

	
 

	
 
def test_passing_list_setting_value_results_in_string_valued_setting():
 
    assert Setting.get_by_name(name) is None
 
    setting = Setting.create_or_update(name, ['spam', 'eggs'])
 
    assert db.Setting.get_by_name(name) is None
 
    setting = db.Setting.create_or_update(name, ['spam', 'eggs'])
 
    meta.Session().flush() # must flush so we can delete it below
 
    try:
 
        assert Setting.get_by_name(name) is not None
 
        assert db.Setting.get_by_name(name) is not None
 
        # Quirk: list value is stringified.
 
        assert Setting.get_by_name(name).app_settings_value \
 
        assert db.Setting.get_by_name(name).app_settings_value \
 
               == "['spam', 'eggs']"
 
        assert Setting.get_by_name(name).app_settings_type == 'unicode'
 
        assert db.Setting.get_by_name(name).app_settings_type == 'unicode'
 
    finally:
 
        meta.Session().delete(setting)
 

	
 

	
 
def test_list_valued_setting_creation_requires_manual_value_formatting():
 
    assert Setting.get_by_name(name) is None
 
    assert db.Setting.get_by_name(name) is None
 
    # Quirk: need manual formatting of list setting value.
 
    setting = Setting.create_or_update(name, 'spam,eggs', type='list')
 
    setting = db.Setting.create_or_update(name, 'spam,eggs', type='list')
 
    meta.Session().flush() # must flush so we can delete it below
 
    try:
 
        assert setting.app_settings_value == ['spam', 'eggs']
 
    finally:
 
        meta.Session().delete(setting)
 

	
 

	
 
def test_list_valued_setting_update():
 
    assert Setting.get_by_name(name) is None
 
    setting = Setting.create_or_update(name, 'spam', type='list')
 
    assert db.Setting.get_by_name(name) is None
 
    setting = db.Setting.create_or_update(name, 'spam', type='list')
 
    meta.Session().flush() # must flush so we can delete it below
 
    try:
 
        assert setting.app_settings_value == ['spam']
 
        # Assign back setting value.
 
        setting.app_settings_value = setting.app_settings_value
 
        # Quirk: value is stringified on write and listified on read.
kallithea/tests/models/test_user_group_permissions_on_repo_groups.py
Show inline comments
 
import functools
 

	
 
from kallithea.model import meta
 
from kallithea.model.db import RepoGroup
 
from kallithea.model import db, meta
 
from kallithea.model.repo_group import RepoGroupModel
 
from kallithea.model.user_group import UserGroupModel
 
from kallithea.tests.fixture import Fixture
 
from kallithea.tests.models.common import _check_expected_count, _create_project_tree, _destroy_project_tree, _get_perms, check_tree_perms, expected_count
 

	
 

	
 
@@ -17,13 +16,13 @@ _get_group_perms = None
 

	
 

	
 
def permissions_setup_func(group_name='g0', perm='group.read', recursive='all'):
 
    """
 
    Resets all permissions to perm attribute
 
    """
 
    repo_group = RepoGroup.get_by_group_name(group_name=group_name)
 
    repo_group = db.RepoGroup.get_by_group_name(group_name=group_name)
 
    if not repo_group:
 
        raise Exception('Cannot get group %s' % group_name)
 

	
 
    # Start with a baseline that current group can read recursive
 
    perms_updates = [[test_u2_gr_id, 'group.read', 'users_group']]
 
    RepoGroupModel()._update_permissions(repo_group,
kallithea/tests/models/test_user_groups.py
Show inline comments
 
from kallithea.model import meta
 
from kallithea.model.db import User, UserGroup
 
from kallithea.model import db, meta
 
from kallithea.model.user_group import UserGroupModel
 
from kallithea.tests import base
 
from kallithea.tests.fixture import Fixture
 

	
 

	
 
fixture = Fixture()
 

	
 

	
 
class TestUserGroups(base.TestController):
 

	
 
    def teardown_method(self, method):
 
        # delete all groups
 
        for gr in UserGroup.query():
 
        for gr in db.UserGroup.query():
 
            fixture.destroy_user_group(gr)
 
        meta.Session().commit()
 

	
 
    @base.parametrize('pre_existing,regular_should_be,external_should_be,groups,expected', [
 
        ([], [], [], [], []),
 
        ([], ['regular'], [], [], ['regular']),  # no changes of regular
 
@@ -25,17 +24,17 @@ class TestUserGroups(base.TestController
 
        ([], ['regular'], ['other'], [], ['regular']),  # remove not used
 
        (['some_other'], ['regular'], ['other', 'container'], ['container', 'container2'], ['regular', 'container', 'container2']),
 
    ])
 
    def test_enforce_groups(self, pre_existing, regular_should_be,
 
                            external_should_be, groups, expected):
 
        # delete all groups
 
        for gr in UserGroup.query():
 
        for gr in db.UserGroup.query():
 
            fixture.destroy_user_group(gr)
 
        meta.Session().commit()
 

	
 
        user = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        for gr in pre_existing:
 
            gr = fixture.create_user_group(gr)
 
        meta.Session().commit()
 

	
 
        # make sure use is just in those groups
 
        for gr in regular_should_be:
 
@@ -51,9 +50,9 @@ class TestUserGroups(base.TestController
 
            UserGroupModel().add_user_to_group(gr, user)
 
            meta.Session().commit()
 

	
 
        UserGroupModel().enforce_groups(user, groups, 'container')
 
        meta.Session().commit()
 

	
 
        user = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        user = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        in_groups = user.group_member
 
        assert sorted(expected) == sorted(x.users_group.users_group_name for x in in_groups)
kallithea/tests/models/test_user_permissions_on_repo_groups.py
Show inline comments
 
import functools
 

	
 
import kallithea
 
from kallithea.model import meta
 
from kallithea.model.db import RepoGroup, Repository
 
from kallithea.model import db, meta
 
from kallithea.model.repo_group import RepoGroupModel
 
from kallithea.tests.models.common import _check_expected_count, _create_project_tree, _destroy_project_tree, _get_perms, check_tree_perms, expected_count
 

	
 

	
 
test_u1_id = None
 
_get_repo_perms = None
 
@@ -19,13 +18,13 @@ def permissions_setup_func(group_name='g
 
    """
 
    if not user_id:
 
        user_id = test_u1_id
 
        permissions_setup_func(group_name, perm, recursive,
 
                               user_id=kallithea.DEFAULT_USER_ID)
 

	
 
    repo_group = RepoGroup.get_by_group_name(group_name=group_name)
 
    repo_group = db.RepoGroup.get_by_group_name(group_name=group_name)
 
    if not repo_group:
 
        raise Exception('Cannot get group %s' % group_name)
 

	
 
    # Start with a baseline that current group can read recursive
 
    perms_updates = [[user_id, 'group.read', 'user']]
 
    RepoGroupModel()._update_permissions(repo_group,
 
@@ -130,13 +129,13 @@ def test_user_permissions_on_group_with_
 
    repo_items = [x for x in _get_repo_perms(group, recursive)]
 
    items = [x for x in _get_group_perms(group, recursive)]
 
    _check_expected_count(items, repo_items, expected_count(group, True))
 

	
 
    for name, perm in repo_items:
 
        # default user permissions do not "recurse into" private repos
 
        is_private = Repository.get_by_repo_name(name).private
 
        is_private = db.Repository.get_by_repo_name(name).private
 
        check_tree_perms(name, perm, group, 'repository.none' if is_private else 'repository.write')
 

	
 
    for name, perm in items:
 
        check_tree_perms(name, perm, group, 'group.write')
 

	
 

	
kallithea/tests/models/test_user_ssh_keys.py
Show inline comments
 
from kallithea.model.db import UserSshKeys
 
from kallithea.model import db
 
from kallithea.tests.base import TestController
 
from kallithea.tests.fixture import Fixture
 

	
 

	
 
fixture = Fixture()
 

	
 
public_key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC6Ycnc2oUZHQnQwuqgZqTTdMDZD7ataf3JM7oG2Fw8JR6cdmz4QZLe5mfDwaFwG2pWHLRpVqzfrD/Pn3rIO++bgCJH5ydczrl1WScfryV1hYMJ/4EzLGM657J1/q5EI+b9SntKjf4ax+KP322L0TNQGbZUHLbfG2MwHMrYBQpHUQ== kallithea@localhost'
 

	
 

	
 
class TestUserSshKeys(TestController):
 

	
 
    def test_fingerprint_generation(self):
 
        key_model = UserSshKeys()
 
        key_model = db.UserSshKeys()
 
        key_model.public_key = public_key
 
        expected = 'Ke3oUCNJM87P0jJTb3D+e3shjceP2CqMpQKVd75E9I8'
 
        assert expected == key_model.fingerprint
kallithea/tests/models/test_users.py
Show inline comments
 
import pytest
 

	
 
from kallithea.model import meta
 
from kallithea.model.db import Permission, User, UserEmailMap, UserGroup, UserGroupMember
 
from kallithea.model import db, meta
 
from kallithea.model.user import UserModel
 
from kallithea.model.user_group import UserGroupModel
 
from kallithea.tests import base
 
from kallithea.tests.fixture import Fixture
 

	
 

	
 
@@ -23,43 +22,43 @@ class TestUser(base.TestController):
 
    def test_create_and_remove(self):
 
        usr = UserModel().create_or_update(username='test_user',
 
                                           password='qweqwe',
 
                                           email='u232@example.com',
 
                                           firstname='u1', lastname='u1')
 
        meta.Session().commit()
 
        assert User.get_by_username('test_user') == usr
 
        assert User.get_by_username('test_USER', case_insensitive=True) == usr
 
        assert db.User.get_by_username('test_user') == usr
 
        assert db.User.get_by_username('test_USER', case_insensitive=True) == usr
 
        # User.get_by_username without explicit request for case insensitivty
 
        # will use database case sensitivity. The following will thus return
 
        # None on for example PostgreSQL but find test_user on MySQL - we are
 
        # fine with leaving that as undefined as long as it doesn't crash.
 
        User.get_by_username('test_USER', case_insensitive=False)
 
        db.User.get_by_username('test_USER', case_insensitive=False)
 

	
 
        # make user group
 
        user_group = fixture.create_user_group('some_example_group')
 
        meta.Session().commit()
 

	
 
        UserGroupModel().add_user_to_group(user_group, usr)
 
        meta.Session().commit()
 

	
 
        assert UserGroup.get(user_group.users_group_id) == user_group
 
        assert UserGroupMember.query().count() == 1
 
        assert db.UserGroup.get(user_group.users_group_id) == user_group
 
        assert db.UserGroupMember.query().count() == 1
 
        UserModel().delete(usr.user_id)
 
        meta.Session().commit()
 

	
 
        assert UserGroupMember.query().all() == []
 
        assert db.UserGroupMember.query().all() == []
 

	
 
    def test_additional_email_as_main(self):
 
        usr = UserModel().create_or_update(username='test_user',
 
                                           password='qweqwe',
 
                                     email='main_email@example.com',
 
                                     firstname='u1', lastname='u1')
 
        meta.Session().commit()
 

	
 
        with pytest.raises(AttributeError):
 
            m = UserEmailMap()
 
            m = db.UserEmailMap()
 
            m.email = 'main_email@example.com'
 
            m.user = usr
 
            meta.Session().add(m)
 
            meta.Session().commit()
 

	
 
        UserModel().delete(usr.user_id)
 
@@ -69,35 +68,35 @@ class TestUser(base.TestController):
 
        usr = UserModel().create_or_update(username='test_user',
 
                                           password='qweqwe',
 
                                     email='main_email@example.com',
 
                                     firstname='u1', lastname='u1')
 
        meta.Session().commit()
 

	
 
        m = UserEmailMap()
 
        m = db.UserEmailMap()
 
        m.email = 'main_email2@example.com'
 
        m.user = usr
 
        meta.Session().add(m)
 
        meta.Session().commit()
 

	
 
        u = User.get_by_email(email='MAIN_email@example.com')
 
        u = db.User.get_by_email(email='MAIN_email@example.com')
 
        assert usr.user_id == u.user_id
 
        assert usr.username == u.username
 

	
 
        u = User.get_by_email(email='main_email@example.com')
 
        u = db.User.get_by_email(email='main_email@example.com')
 
        assert usr.user_id == u.user_id
 
        assert usr.username == u.username
 

	
 
        u = User.get_by_email(email='main_email2@example.com')
 
        u = db.User.get_by_email(email='main_email2@example.com')
 
        assert usr.user_id == u.user_id
 
        assert usr.username == u.username
 
        u = User.get_by_email(email='main_email3@example.com')
 
        u = db.User.get_by_email(email='main_email3@example.com')
 
        assert u is None
 

	
 
        u = User.get_by_email(email='main_e%ail@example.com')
 
        u = db.User.get_by_email(email='main_e%ail@example.com')
 
        assert u is None
 
        u = User.get_by_email(email='main_emai_@example.com')
 
        u = db.User.get_by_email(email='main_emai_@example.com')
 
        assert u is None
 

	
 
        UserModel().delete(usr.user_id)
 
        meta.Session().commit()
 

	
 

	
 
@@ -107,34 +106,34 @@ class TestUsers(base.TestController):
 
        self.u1 = UserModel().create_or_update(username='u1',
 
                                        password='qweqwe',
 
                                        email='u1@example.com',
 
                                        firstname='u1', lastname='u1')
 

	
 
    def teardown_method(self, method):
 
        perm = Permission.query().all()
 
        perm = db.Permission.query().all()
 
        for p in perm:
 
            UserModel().revoke_perm(self.u1, p)
 

	
 
        UserModel().delete(self.u1)
 
        meta.Session().commit()
 
        meta.Session.remove()
 

	
 
    def test_add_perm(self):
 
        perm = Permission.query().all()[0]
 
        perm = db.Permission.query().all()[0]
 
        UserModel().grant_perm(self.u1, perm)
 
        meta.Session().commit()
 
        assert UserModel().has_perm(self.u1, perm) == True
 

	
 
    def test_has_perm(self):
 
        perm = Permission.query().all()
 
        perm = db.Permission.query().all()
 
        for p in perm:
 
            has_p = UserModel().has_perm(self.u1, p)
 
            assert False == has_p
 

	
 
    def test_revoke_perm(self):
 
        perm = Permission.query().all()[0]
 
        perm = db.Permission.query().all()[0]
 
        UserModel().grant_perm(self.u1, perm)
 
        meta.Session().commit()
 
        assert UserModel().has_perm(self.u1, perm) == True
 

	
 
        # revoke
 
        UserModel().revoke_perm(self.u1, perm)
kallithea/tests/other/test_auth_ldap.py
Show inline comments
 
import uuid
 

	
 
import pytest
 

	
 
from kallithea.lib.auth_modules import auth_ldap, authenticate
 
from kallithea.model.db import User
 
from kallithea.model import db
 

	
 

	
 
@pytest.fixture
 
def arrange_ldap_auth(set_test_settings):
 
    set_test_settings(
 
        ('auth_plugins', 'kallithea.lib.auth_modules.auth_ldap', 'list'),
 
@@ -32,13 +32,13 @@ def test_update_user_attributes_from_lda
 
    """Authenticate user with mocked LDAP, verify attributes are updated.
 
    """
 

	
 
    # Arrange test user.
 
    uniqifier = uuid.uuid4()
 
    username = 'test-user-{0}'.format(uniqifier)
 
    assert User.get_by_username(username) is None
 
    assert db.User.get_by_username(username) is None
 
    user_input = dict(username='test-user-{0}'.format(uniqifier),
 
                      password='spam password',
 
                      email='spam-email-{0}'.format(uniqifier),
 
                      firstname='spam first name',
 
                      lastname='spam last name',
 
                      active=True,
 
@@ -69,13 +69,13 @@ def test_init_user_attributes_from_ldap(
 
    """Authenticate unknown user with mocked LDAP, verify user is created.
 
    """
 

	
 
    # Arrange test user.
 
    uniqifier = uuid.uuid4()
 
    username = 'test-user-{0}'.format(uniqifier)
 
    assert User.get_by_username(username) is None
 
    assert db.User.get_by_username(username) is None
 

	
 
    # Arrange LDAP auth.
 
    monkeypatch.setattr(auth_ldap, 'AuthLdap', _AuthLdapMock)
 

	
 
    # Authenticate with LDAP.
 
    user_data = authenticate(username, 'password')
 
@@ -86,13 +86,13 @@ def test_init_user_attributes_from_ldap(
 
    assert user_data.get('firstname') == 'spam ldap first name'
 
    assert user_data.get('lastname') == 'spam ldap last name'
 
    assert user_data.get('email') == '%s ldap email' % username
 

	
 
    # Verify that authentication created new user with attributes
 
    # retrieved from LDAP.
 
    new_user = User.get_by_username(username)
 
    new_user = db.User.get_by_username(username)
 
    assert new_user is not None
 
    assert new_user.firstname == 'spam ldap first name'
 
    assert new_user.lastname == 'spam ldap last name'
 
    assert new_user.email == '%s ldap email' % username
 

	
 

	
 
@@ -112,13 +112,13 @@ def test_init_user_attributes_from_ldap_
 
    """Authenticate unknown user with mocked LDAP where email is missing.
 
    """
 

	
 
    # Arrange test user.
 
    uniqifier = uuid.uuid4()
 
    username = 'test-user-{0}'.format(uniqifier)
 
    assert User.get_by_username(username) is None
 
    assert db.User.get_by_username(username) is None
 

	
 
    # Arrange LDAP auth.
 
    monkeypatch.setattr(auth_ldap, 'AuthLdap', _AuthLdapNoEmailMock)
 

	
 
    # Authenticate with LDAP.
 
    user_data = authenticate(username, 'password')
 
@@ -129,11 +129,11 @@ def test_init_user_attributes_from_ldap_
 
    assert user_data.get('firstname') == 'spam ldap first name'
 
    assert user_data.get('lastname') == 'spam ldap last name'
 
    assert user_data.get('email') == ''
 

	
 
    # Verify that authentication created new user with attributes
 
    # retrieved from LDAP, with email == None.
 
    new_user = User.get_by_username(username)
 
    new_user = db.User.get_by_username(username)
 
    assert new_user is not None
 
    assert new_user.firstname == 'spam ldap first name'
 
    assert new_user.lastname == 'spam ldap last name'
 
    assert new_user.email is None
kallithea/tests/other/test_libs.py
Show inline comments
 
@@ -29,13 +29,13 @@ import datetime
 
import hashlib
 

	
 
import mock
 
from tg.util.webtest import test_context
 

	
 
from kallithea.lib.utils2 import AttributeDict, safe_bytes
 
from kallithea.model.db import Repository
 
from kallithea.model import db
 
from kallithea.tests import base
 

	
 

	
 
proto = 'http'
 
TEST_URLS = [
 
    ('%s://127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
 
@@ -248,19 +248,19 @@ class TestLibs(base.TestController):
 
            with mock.patch('tg.tmpl_context', fake):
 
                em = 'test@example.com'
 
                grav = gravatar_url(email_address=em, size=24)
 
                assert grav == 'https://example.com/%s/%s' % (_md5(em), 24)
 

	
 
    @base.parametrize('clone_uri_tmpl,repo_name,username,prefix,expected', [
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', None, '', 'http://vps1:8000/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', 'username', '', 'http://username@vps1:8000/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', None, '/prefix', 'http://vps1:8000/prefix/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', 'user', '/prefix', 'http://user@vps1:8000/prefix/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', 'username', '/prefix', 'http://username@vps1:8000/prefix/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', 'user', '/prefix/', 'http://user@vps1:8000/prefix/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', 'username', '/prefix/', 'http://username@vps1:8000/prefix/group/repo1'),
 
        (db.Repository.DEFAULT_CLONE_URI, 'group/repo1', None, '', 'http://vps1:8000/group/repo1'),
 
        (db.Repository.DEFAULT_CLONE_URI, 'group/repo1', 'username', '', 'http://username@vps1:8000/group/repo1'),
 
        (db.Repository.DEFAULT_CLONE_URI, 'group/repo1', None, '/prefix', 'http://vps1:8000/prefix/group/repo1'),
 
        (db.Repository.DEFAULT_CLONE_URI, 'group/repo1', 'user', '/prefix', 'http://user@vps1:8000/prefix/group/repo1'),
 
        (db.Repository.DEFAULT_CLONE_URI, 'group/repo1', 'username', '/prefix', 'http://username@vps1:8000/prefix/group/repo1'),
 
        (db.Repository.DEFAULT_CLONE_URI, 'group/repo1', 'user', '/prefix/', 'http://user@vps1:8000/prefix/group/repo1'),
 
        (db.Repository.DEFAULT_CLONE_URI, 'group/repo1', 'username', '/prefix/', 'http://username@vps1:8000/prefix/group/repo1'),
 
        ('{scheme}://{user}@{netloc}/_{repoid}', 'group/repo1', None, '', 'http://vps1:8000/_23'),
 
        ('{scheme}://{user}@{netloc}/_{repoid}', 'group/repo1', 'username', '', 'http://username@vps1:8000/_23'),
 
        ('http://{user}@{netloc}/_{repoid}', 'group/repo1', 'username', '', 'http://username@vps1:8000/_23'),
 
        ('http://{netloc}/_{repoid}', 'group/repo1', 'username', '', 'http://vps1:8000/_23'),
 
        ('https://{user}@proxy1.example.com/{repo}', 'group/repo1', 'username', '', 'https://username@proxy1.example.com/group/repo1'),
 
        ('https://{user}@proxy1.example.com/{repo}', 'group/repo1', None, '', 'https://proxy1.example.com/group/repo1'),
 
@@ -537,13 +537,13 @@ class TestLibs(base.TestController):
 
      ("_ID", 'NAME'),
 
      ("_ID/", 'NAME/'),
 
      ("_ID/1/2", 'NAME/1/2'),
 
      ("_IDa", '_IDa'),
 
    ])
 
    def test_fix_repo_id_name(self, test, expected):
 
        repo = Repository.get_by_repo_name(base.HG_REPO)
 
        repo = db.Repository.get_by_repo_name(base.HG_REPO)
 
        test = test.replace('ID', str(repo.repo_id))
 
        expected = expected.replace('NAME', repo.repo_name).replace('ID', str(repo.repo_id))
 
        from kallithea.lib.utils import fix_repo_id_name
 
        replaced = fix_repo_id_name(test)
 
        assert replaced == expected, 'url:%s, got:`%s` expected: `%s`' % (test, replaced, expected)
 

	
kallithea/tests/other/test_mail.py
Show inline comments
 
# -*- coding: utf-8 -*-
 

	
 
import mock
 

	
 
import kallithea
 
from kallithea.model.db import User
 
from kallithea.model import db
 
from kallithea.tests import base
 

	
 

	
 
class smtplib_mock(object):
 

	
 
    @classmethod
 
@@ -124,13 +124,13 @@ class TestMail(base.TestController):
 
        mailserver = 'smtp.mailserver.org'
 
        recipients = ['rcpt1', 'rcpt2']
 
        envelope_from = 'noreply@mailserver.org'
 
        subject = 'subject'
 
        body = 'body'
 
        html_body = 'html_body'
 
        author = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        author = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 

	
 
        config_mock = {
 
            'smtp_server': mailserver,
 
            'app_email_from': envelope_from,
 
        }
 
        with mock.patch('kallithea.lib.celerylib.tasks.config', config_mock):
 
@@ -148,13 +148,13 @@ class TestMail(base.TestController):
 
        recipients = ['ræcpt1', 'receptor2 <rcpt2@example.com>', 'tæst@example.com', 'Tæst <test@example.com>']
 
        envelope_addr = 'noreply@mailserver.org'
 
        envelope_from = 'Söme Næme <%s>' % envelope_addr
 
        subject = 'subject'
 
        body = 'body'
 
        html_body = 'html_body'
 
        author = User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 
        author = db.User.get_by_username(base.TEST_USER_REGULAR_LOGIN)
 

	
 
        config_mock = {
 
            'smtp_server': mailserver,
 
            'app_email_from': envelope_from,
 
        }
 
        with mock.patch('kallithea.lib.celerylib.tasks.config', config_mock):
 
@@ -171,13 +171,13 @@ class TestMail(base.TestController):
 
        mailserver = 'smtp.mailserver.org'
 
        recipients = ['rcpt1', 'rcpt2']
 
        envelope_from = 'noreply@mailserver.org'
 
        subject = 'subject'
 
        body = 'body'
 
        html_body = 'html_body'
 
        author = User(name='foo', lastname='(fubar) "baz"')
 
        author = db.User(name='foo', lastname='(fubar) "baz"')
 
        headers = {'extra': 'yes'}
 

	
 
        config_mock = {
 
            'smtp_server': mailserver,
 
            'app_email_from': envelope_from,
 
        }
kallithea/tests/other/test_vcs_operations.py
Show inline comments
 
@@ -35,14 +35,13 @@ from subprocess import PIPE, Popen
 
from tempfile import _RandomNameSequence
 

	
 
import pytest
 

	
 
import kallithea
 
from kallithea.lib.utils2 import ascii_bytes, safe_str
 
from kallithea.model import meta
 
from kallithea.model.db import Repository, Ui, User, UserIpMap, UserLog
 
from kallithea.model import db, meta
 
from kallithea.model.ssh_key import SshKeyModel
 
from kallithea.model.user import UserModel
 
from kallithea.tests import base
 
from kallithea.tests.fixture import Fixture
 

	
 

	
 
@@ -66,13 +65,13 @@ class SshVcsTest(object):
 
        base.TEST_USER_REGULAR_LOGIN: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC6Ycnc2oUZHQnQwuqgZqTTdMDZD7ataf3JM7oG2Fw8JR6cdmz4QZLe5mfDwaFwG2pWHLRpVqzfrD/Pn3rIO++bgCJH5ydczrl1WScfryV1hYMJ/4EzLGM657J1/q5EI+b9SntKjf4ax+KP322L0TNQGbZUHLbfG2MwHMrYBQpHUQ== kallithea@localhost',
 
        base.TEST_USER_ADMIN_LOGIN: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC6Ycnc2oUZHQnQwuqgZqTTdMDZD7ataf3JM7oG2Fw8JR6cdmz4QZLe5mfDwaFwG2pWHLRpVqzfrD/Pn3rIO++bgCJH5ydczrl1WScfryV1hYMJ/4EzLGM657J1/q5EI+b9SntKjf4ax+KP322L0TNQGbZUHLbfG2MwHMrYBQpHUq== kallithea@localhost',
 
    }
 

	
 
    @classmethod
 
    def repo_url_param(cls, webserver, repo_name, username=base.TEST_USER_ADMIN_LOGIN, password=base.TEST_USER_ADMIN_PASS, client_ip=base.IP_ADDR):
 
        user = User.get_by_username(username)
 
        user = db.User.get_by_username(username)
 
        if user.ssh_keys:
 
            ssh_key = user.ssh_keys[0]
 
        else:
 
            sshkeymodel = SshKeyModel()
 
            ssh_key = sshkeymodel.create(user, 'test key', cls.public_keys[user.username])
 
            meta.Session().commit()
 
@@ -218,16 +217,16 @@ def _check_outgoing(vcs, cwd, clone_url)
 
    elif vcs == 'git':
 
        Command(cwd).execute('git remote update')
 
        return Command(cwd).execute('git log origin/master..master')
 

	
 

	
 
def set_anonymous_access(enable=True):
 
    user = User.get_default_user()
 
    user = db.User.get_default_user()
 
    user.active = enable
 
    meta.Session().commit()
 
    if enable != User.get_default_user().active:
 
    if enable != db.User.get_default_user().active:
 
        raise Exception('Cannot set anonymous access')
 

	
 

	
 
#==============================================================================
 
# TESTS
 
#==============================================================================
 
@@ -250,13 +249,13 @@ class TestVCSOperations(base.TestControl
 

	
 
    @pytest.fixture()
 
    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)
 
            entry = db.Ui.get_by_key('hooks', '%s.testhook' % hook)
 
            if entry:
 
                meta.Session().delete(entry)
 
        meta.Session().commit()
 

	
 
    @pytest.fixture(scope="module")
 
    def testfork(self):
 
@@ -310,18 +309,18 @@ class TestVCSOperations(base.TestControl
 
        elif vt.repo_type == 'hg':
 
            assert 'HTTP Error 404: Not Found' in stderr or 'abort: no suitable response from remote hg' in stderr and 'remote: abort: Access to %r denied' % 'trololo' in stdout + stderr
 

	
 
    @parametrize_vcs_test
 
    def test_push_new_repo(self, webserver, vt):
 
        # Clear the log so we know what is added
 
        UserLog.query().delete()
 
        db.UserLog.query().delete()
 
        meta.Session().commit()
 

	
 
        # Create an empty server repo using the API
 
        repo_name = 'new_%s_%s' % (vt.repo_type, next(_RandomNameSequence()))
 
        usr = User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        usr = db.User.get_by_username(base.TEST_USER_ADMIN_LOGIN)
 
        params = {
 
            "id": 7,
 
            "api_key": usr.api_key,
 
            "method": 'create_repo',
 
            "args": dict(repo_name=repo_name,
 
                         owner=base.TEST_USER_ADMIN_LOGIN,
 
@@ -356,13 +355,13 @@ class TestVCSOperations(base.TestControl
 
        # Verify that we got the right events in UserLog. Expect something like:
 
        # <UserLog('id:new_git_XXX:started_following_repo')>
 
        # <UserLog('id:new_git_XXX:user_created_repo')>
 
        # <UserLog('id:new_git_XXX:pull')>
 
        # <UserLog('id:new_git_XXX:push:aed9d4c1732a1927da3be42c47eb9afdc200d427,d38b083a07af10a9f44193486959a96a23db78da,4841ff9a2b385bec995f4679ef649adb3f437622')>
 
        meta.Session.close()  # make sure SA fetches all new log entries (apparently only needed for MariaDB/MySQL ...)
 
        action_parts = [ul.action.split(':', 1) for ul in UserLog.query().order_by(UserLog.user_log_id)]
 
        action_parts = [ul.action.split(':', 1) for ul in db.UserLog.query().order_by(db.UserLog.user_log_id)]
 
        assert [(t[0], (t[1].count(',') + 1) if len(t) == 2 else 0) for t in action_parts] == ([
 
            ('started_following_repo', 0),
 
            ('user_created_repo', 0),
 
            ('pull', 0),
 
            ('push', 3)]
 
            if vt.repo_type == 'git' else [
 
@@ -370,13 +369,13 @@ class TestVCSOperations(base.TestControl
 
            ('user_created_repo', 0),
 
            # (u'pull', 0), # Mercurial outgoing hook is not called for empty clones
 
            ('push', 3)])
 

	
 
    @parametrize_vcs_test
 
    def test_push_new_file(self, webserver, testfork, vt):
 
        UserLog.query().delete()
 
        db.UserLog.query().delete()
 
        meta.Session().commit()
 

	
 
        dest_dir = _get_tmp_dir()
 
        clone_url = vt.repo_url_param(webserver, vt.repo_name)
 
        stdout, stderr = Command(base.TESTS_TMP_PATH).execute(vt.repo_type, 'clone', clone_url, dest_dir)
 

	
 
@@ -388,19 +387,19 @@ class TestVCSOperations(base.TestControl
 
        elif vt.repo_type == 'hg':
 
            assert 'pushing to' in stdout
 
            assert 'Repository size' in stdout
 
            assert 'Last revision is now' in stdout
 

	
 
        meta.Session.close()  # make sure SA fetches all new log entries (apparently only needed for MariaDB/MySQL ...)
 
        action_parts = [ul.action.split(':', 1) for ul in UserLog.query().order_by(UserLog.user_log_id)]
 
        action_parts = [ul.action.split(':', 1) for ul in db.UserLog.query().order_by(db.UserLog.user_log_id)]
 
        assert [(t[0], (t[1].count(',') + 1) if len(t) == 2 else 0) for t in action_parts] == \
 
            [('pull', 0), ('push', 3)]
 

	
 
    @parametrize_vcs_test
 
    def test_pull(self, webserver, testfork, vt):
 
        UserLog.query().delete()
 
        db.UserLog.query().delete()
 
        meta.Session().commit()
 

	
 
        dest_dir = _get_tmp_dir()
 
        stdout, stderr = Command(base.TESTS_TMP_PATH).execute(vt.repo_type, 'init', dest_dir)
 

	
 
        clone_url = vt.repo_url_param(webserver, vt.repo_name)
 
@@ -409,13 +408,13 @@ class TestVCSOperations(base.TestControl
 

	
 
        if vt.repo_type == 'git':
 
            assert 'FETCH_HEAD' in stderr
 
        elif vt.repo_type == 'hg':
 
            assert 'new changesets' in stdout
 

	
 
        action_parts = [ul.action for ul in UserLog.query().order_by(UserLog.user_log_id)]
 
        action_parts = [ul.action for ul in db.UserLog.query().order_by(db.UserLog.user_log_id)]
 
        assert action_parts == ['pull']
 

	
 
        # Test handling of URLs with extra '/' around repo_name
 
        stdout, stderr = Command(dest_dir).execute(vt.repo_type, 'pull', clone_url.replace('/' + vt.repo_name, '/./%s/' % vt.repo_name), ignoreReturnCode=True)
 
        if issubclass(vt, HttpVcsTest):
 
            if vt.repo_type == 'git':
 
@@ -440,25 +439,25 @@ class TestVCSOperations(base.TestControl
 
        assert "denied" not in stderr
 
        assert "denied" not in stdout
 
        assert "404" not in stdout
 

	
 
    @parametrize_vcs_test
 
    def test_push_invalidates_cache(self, webserver, testfork, vt):
 
        pre_cached_tip = [repo.get_api_data()['last_changeset']['short_id'] for repo in Repository.query().filter(Repository.repo_name == testfork[vt.repo_type])]
 
        pre_cached_tip = [repo.get_api_data()['last_changeset']['short_id'] for repo in db.Repository.query().filter(db.Repository.repo_name == testfork[vt.repo_type])]
 

	
 
        dest_dir = _get_tmp_dir()
 
        clone_url = vt.repo_url_param(webserver, testfork[vt.repo_type])
 
        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, files_no=1, clone_url=clone_url)
 

	
 
        if vt.repo_type == 'git':
 
            _check_proper_git_push(stdout, stderr)
 

	
 
        meta.Session.close()  # expire session to make sure SA fetches new Repository instances after last_changeset has been updated by server side hook in another process
 
        post_cached_tip = [repo.get_api_data()['last_changeset']['short_id'] for repo in Repository.query().filter(Repository.repo_name == testfork[vt.repo_type])]
 
        post_cached_tip = [repo.get_api_data()['last_changeset']['short_id'] for repo in db.Repository.query().filter(db.Repository.repo_name == testfork[vt.repo_type])]
 
        assert pre_cached_tip != post_cached_tip
 

	
 
    @parametrize_vcs_test_http
 
    def test_push_wrong_credentials(self, webserver, vt):
 
        dest_dir = _get_tmp_dir()
 
        clone_url = vt.repo_url_param(webserver, vt.repo_name)
 
@@ -472,13 +471,13 @@ class TestVCSOperations(base.TestControl
 
            assert 'fatal: Authentication failed' in stderr
 
        elif vt.repo_type == 'hg':
 
            assert 'abort: authorization failed' in stderr
 

	
 
    @parametrize_vcs_test
 
    def test_push_with_readonly_credentials(self, webserver, vt):
 
        UserLog.query().delete()
 
        db.UserLog.query().delete()
 
        meta.Session().commit()
 

	
 
        dest_dir = _get_tmp_dir()
 
        clone_url = vt.repo_url_param(webserver, vt.repo_name, username=base.TEST_USER_REGULAR_LOGIN, password=base.TEST_USER_REGULAR_PASS)
 
        stdout, stderr = Command(base.TESTS_TMP_PATH).execute(vt.repo_type, 'clone', clone_url, dest_dir)
 

	
 
@@ -487,13 +486,13 @@ class TestVCSOperations(base.TestControl
 
        if vt.repo_type == 'git':
 
            assert 'The requested URL returned error: 403' in stderr or 'abort: Push access to %r denied' % str(vt.repo_name) in stderr
 
        elif vt.repo_type == 'hg':
 
            assert 'abort: HTTP Error 403: Forbidden' in stderr or 'abort: push failed on remote' in stderr and 'remote: Push access to %r denied' % str(vt.repo_name) in stdout
 

	
 
        meta.Session.close()  # make sure SA fetches all new log entries (apparently only needed for MariaDB/MySQL ...)
 
        action_parts = [ul.action.split(':', 1) for ul in UserLog.query().order_by(UserLog.user_log_id)]
 
        action_parts = [ul.action.split(':', 1) for ul in db.UserLog.query().order_by(db.UserLog.user_log_id)]
 
        assert [(t[0], (t[1].count(',') + 1) if len(t) == 2 else 0) for t in action_parts] == \
 
            [('pull', 0)]
 

	
 
    @parametrize_vcs_test
 
    def test_push_back_to_wrong_url(self, webserver, vt):
 
        dest_dir = _get_tmp_dir()
 
@@ -525,14 +524,14 @@ class TestVCSOperations(base.TestControl
 
                # The message apparently changed in Git 1.8.3, so match it loosely.
 
                assert re.search(r'\b403\b', stderr) or 'abort: User test_admin from 127.0.0.127 cannot be authorized' in stderr
 
            elif vt.repo_type == 'hg':
 
                assert 'abort: HTTP Error 403: Forbidden' in stderr or 'remote: abort: User test_admin from 127.0.0.127 cannot be authorized' in stdout + stderr
 
        finally:
 
            # release IP restrictions
 
            for ip in UserIpMap.query():
 
                UserIpMap.delete(ip.ip_id)
 
            for ip in db.UserIpMap.query():
 
                db.UserIpMap.delete(ip.ip_id)
 
            meta.Session().commit()
 
            # IP permissions are cached, need to wait for the cache in the server process to expire
 
            time.sleep(1.5)
 

	
 
        clone_url = vt.repo_url_param(webserver, vt.repo_name)
 
        stdout, stderr = Command(base.TESTS_TMP_PATH).execute(vt.repo_type, 'clone', clone_url, _get_tmp_dir())
 
@@ -548,13 +547,13 @@ class TestVCSOperations(base.TestControl
 

	
 
            assert stderr == ''
 

	
 
    @parametrize_vcs_test_hg # git hooks doesn't work like hg hooks
 
    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')
 
        db.Ui.create_or_update_hook('preoutgoing.testhook', 'python:kallithea.tests.fixture.failing_test_hook')
 
        meta.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)
 
@@ -563,13 +562,13 @@ class TestVCSOperations(base.TestControl
 
        elif vt.repo_type == 'git':
 
            assert 'error: 406' in stderr
 

	
 
    @parametrize_vcs_test_hg # git hooks doesn't work like hg hooks
 
    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')
 
        db.Ui.create_or_update_hook('prechangegroup.testhook', 'python:kallithea.tests.fixture.failing_test_hook')
 
        meta.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)
 

	
 
@@ -580,13 +579,13 @@ class TestVCSOperations(base.TestControl
 
        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')
 
        db.Ui.create_or_update_hook('prechangegroup.testhook', 'python:kallithea.tests.fixture.exception_test_hook')
 
        meta.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
 
@@ -595,13 +594,13 @@ class TestVCSOperations(base.TestControl
 
        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')
 
        db.Ui.create_or_update_hook('prechangegroup.testhook', 'python:kallithea.tests.fixture.passing_test_hook')
 
        meta.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
kallithea/tests/performance/test_vcs.py
Show inline comments
 
@@ -11,23 +11,23 @@
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import pytest
 

	
 
from kallithea.model.db import Repository
 
from kallithea.model import db
 
from kallithea.tests import base
 

	
 

	
 
@pytest.mark.skipif("'TEST_PERFORMANCE' not in os.environ", reason="skipping performance tests, set TEST_PERFORMANCE in environment if desired")
 
class TestVCSPerformance(base.TestController):
 

	
 
    def graphmod(self, repo):
 
        """ Simple test for running the graph_data function for profiling/testing performance. """
 
        from kallithea.lib.graphmod import graph_data
 
        dbr = Repository.get_by_repo_name(repo)
 
        dbr = db.Repository.get_by_repo_name(repo)
 
        scm_inst = dbr.scm_instance
 
        collection = scm_inst.get_changesets(start=0, end=None, branch_name=None)
 
        revs = [x.revision for x in collection]
 
        jsdata = graph_data(scm_inst, revs)
 

	
 
    def test_graphmod_hg(self, benchmark):
kallithea/tests/scripts/manual_test_concurrency.py
Show inline comments
 
@@ -36,15 +36,14 @@ from subprocess import PIPE, Popen
 

	
 
from paste.deploy import appconfig
 
from sqlalchemy import engine_from_config
 

	
 
import kallithea.config.application
 
from kallithea.lib.auth import get_crypt_password
 
from kallithea.model import meta
 
from kallithea.model import db, meta
 
from kallithea.model.base import init_model
 
from kallithea.model.db import Repository, Ui, User
 
from kallithea.tests.base import HG_REPO, TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS
 

	
 

	
 
rel_path = dirname(dirname(dirname(dirname(os.path.abspath(__file__)))))
 
conf = appconfig('config:development.ini', relative_to=rel_path)
 
kallithea.config.application.make_app(conf.global_conf, **conf.local_conf)
 
@@ -85,24 +84,24 @@ def get_session():
 

	
 

	
 
def create_test_user(force=True):
 
    print('creating test user')
 
    sa = get_session()
 

	
 
    user = sa.query(User).filter(User.username == USER).scalar()
 
    user = sa.query(db.User).filter(db.User.username == USER).scalar()
 

	
 
    if force and user is not None:
 
        print('removing current user')
 
        for repo in sa.query(Repository).filter(Repository.user == user).all():
 
        for repo in sa.query(db.Repository).filter(db.Repository.user == user).all():
 
            sa.delete(repo)
 
        sa.delete(user)
 
        sa.commit()
 

	
 
    if user is None or force:
 
        print('creating new one')
 
        new_usr = User()
 
        new_usr = db.User()
 
        new_usr.username = USER
 
        new_usr.password = get_crypt_password(PASS)
 
        new_usr.email = 'mail@example.com'
 
        new_usr.name = 'test'
 
        new_usr.lastname = 'lasttestname'
 
        new_usr.active = True
 
@@ -115,17 +114,17 @@ def create_test_user(force=True):
 

	
 
def create_test_repo(force=True):
 
    print('creating test repo')
 
    from kallithea.model.repo import RepoModel
 
    sa = get_session()
 

	
 
    user = sa.query(User).filter(User.username == USER).scalar()
 
    user = sa.query(db.User).filter(db.User.username == USER).scalar()
 
    if user is None:
 
        raise Exception('user not found')
 

	
 
    repo = sa.query(Repository).filter(Repository.repo_name == HG_REPO).scalar()
 
    repo = sa.query(db.Repository).filter(db.Repository.repo_name == HG_REPO).scalar()
 

	
 
    if repo is None:
 
        print('repo not found creating')
 

	
 
        form_data = {'repo_name': HG_REPO,
 
                     'repo_type': 'hg',
 
@@ -137,29 +136,29 @@ def create_test_repo(force=True):
 

	
 
    print('done')
 

	
 

	
 
def set_anonymous_access(enable=True):
 
    sa = get_session()
 
    user = sa.query(User).filter(User.username == 'default').one()
 
    user = sa.query(db.User).filter(db.User.username == 'default').one()
 
    user.active = enable
 
    sa.add(user)
 
    sa.commit()
 

	
 

	
 
def get_anonymous_access():
 
    sa = get_session()
 
    return sa.query(User).filter(User.username == 'default').one().active
 
    return sa.query(db.User).filter(db.User.username == 'default').one().active
 

	
 

	
 
#==============================================================================
 
# TESTS
 
#==============================================================================
 
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)
 
    cwd = path = os.path.join(db.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:
0 comments (0 inline, 0 general)