Exemplo n.º 1
0
    def settings_issuetracker(self):
        """GET /admin/settings/issue-tracker: All items in the collection"""
        # url('admin_settings_issuetracker')
        c.active = 'issuetracker'
        defaults = SettingsModel().get_all_settings()

        entry_key = 'rhodecode_issuetracker_pat_'

        c.issuetracker_entries = {}
        for k, v in defaults.items():
            if k.startswith(entry_key):
                uid = k[len(entry_key):]
                c.issuetracker_entries[uid] = None

        for uid in c.issuetracker_entries:
            c.issuetracker_entries[uid] = AttributeDict({
                'pat':
                defaults.get('rhodecode_issuetracker_pat_' + uid),
                'url':
                defaults.get('rhodecode_issuetracker_url_' + uid),
                'pref':
                defaults.get('rhodecode_issuetracker_pref_' + uid),
                'desc':
                defaults.get('rhodecode_issuetracker_desc_' + uid),
            })

        return render('admin/settings/settings.html')
Exemplo n.º 2
0
    def password_reset(self):
        settings = SettingsModel().get_all_settings()
        captcha_private_key = settings.get('rhodecode_captcha_private_key')
        captcha_active = bool(captcha_private_key)
        captcha_public_key = settings.get('rhodecode_captcha_public_key')

        render_ctx = {
            'captcha_active': captcha_active,
            'captcha_public_key': captcha_public_key,
            'defaults': {},
            'errors': {},
        }

        if self.request.POST:
            password_reset_form = PasswordResetForm()()
            try:
                form_result = password_reset_form.to_python(
                    self.request.params)
                if captcha_active:
                    response = submit(
                        self.request.params.get('recaptcha_challenge_field'),
                        self.request.params.get('recaptcha_response_field'),
                        private_key=captcha_private_key,
                        remoteip=get_ip_addr(self.request.environ))
                    if captcha_active and not response.is_valid:
                        _value = form_result
                        _msg = _('bad captcha')
                        error_dict = {'recaptcha_field': _msg}
                        raise formencode.Invalid(_msg, _value, None,
                                                 error_dict=error_dict)

                # Generate reset URL and send mail.
                user_email = form_result['email']
                user = User.get_by_email(user_email)
                password_reset_url = self.request.route_url(
                    'reset_password_confirmation',
                    _query={'key': user.api_key})
                UserModel().reset_password_link(
                    form_result, password_reset_url)

                # Display success message and redirect.
                self.session.flash(
                    _('Your password reset link was sent'),
                    queue='success')
                return HTTPFound(self.request.route_path('login'))

            except formencode.Invalid as errors:
                render_ctx.update({
                    'defaults': errors.value,
                    'errors': errors.error_dict,
                })

        return render_ctx
Exemplo n.º 3
0
def error_handler(exception, request):
    # TODO: dan: replace the old pylons error controller with this
    from rhodecode.model.settings import SettingsModel
    from rhodecode.lib.utils2 import AttributeDict

    try:
        rc_config = SettingsModel().get_all_settings()
    except Exception:
        log.exception('failed to fetch settings')
        rc_config = {}

    base_response = HTTPInternalServerError()
    # prefer original exception for the response since it may have headers set
    if isinstance(exception, HTTPError):
        base_response = exception

    c = AttributeDict()
    c.error_message = base_response.status
    c.error_explanation = base_response.explanation or str(base_response)
    c.visual = AttributeDict()

    c.visual.rhodecode_support_url = (
        request.registry.settings.get('rhodecode_support_url')
        or request.route_url('rhodecode_support'))
    c.redirect_time = 0
    c.rhodecode_name = rc_config.get('rhodecode_title', '')
    if not c.rhodecode_name:
        c.rhodecode_name = 'Rhodecode'

    response = render_to_response('/errors/error_document.html', {'c': c},
                                  request=request,
                                  response=base_response)

    return response
Exemplo n.º 4
0
    def register(self, defaults=None, errors=None):
        defaults = defaults or {}
        errors = errors or {}

        settings = SettingsModel().get_all_settings()
        captcha_public_key = settings.get('rhodecode_captcha_public_key')
        captcha_private_key = settings.get('rhodecode_captcha_private_key')
        captcha_active = bool(captcha_private_key)
        register_message = settings.get('rhodecode_register_message') or ''
        auto_active = 'hg.register.auto_activate' in User.get_default_user()\
            .AuthUser.permissions['global']

        render_ctx = self._get_template_context()
        render_ctx.update({
            'defaults': defaults,
            'errors': errors,
            'auto_active': auto_active,
            'captcha_active': captcha_active,
            'captcha_public_key': captcha_public_key,
            'register_message': register_message,
        })
        return render_ctx
Exemplo n.º 5
0
    def permission_application(self):
        c.active = 'application'
        self.__load_data()

        c.user = User.get_default_user()

        # TODO: johbo: The default user might be based on outdated state which
        # has been loaded from the cache. A call to refresh() ensures that the
        # latest state from the database is used.
        Session().refresh(c.user)

        app_settings = SettingsModel().get_all_settings()
        defaults = {
            'anonymous':
            c.user.active,
            'default_register_message':
            app_settings.get('rhodecode_register_message')
        }
        defaults.update(c.user.get_default_perms())

        return htmlfill.render(render('admin/permissions/permissions.html'),
                               defaults=defaults,
                               encoding="UTF-8",
                               force_defaults=False)
Exemplo n.º 6
0
def attach_context_attributes(context):
    rc_config = SettingsModel().get_all_settings(cache=True)

    context.rhodecode_version = rhodecode.__version__
    context.rhodecode_edition = config.get('rhodecode.edition')
    # unique secret + version does not leak the version but keep consistency
    context.rhodecode_version_hash = md5(
        config.get('beaker.session.secret', '') +
        rhodecode.__version__)[:8]

    # Default language set for the incoming request
    context.language = translation.get_lang()[0]

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

    # DB store
    context.visual.show_public_icon = str2bool(
        rc_config.get('rhodecode_show_public_icon'))
    context.visual.show_private_icon = str2bool(
        rc_config.get('rhodecode_show_private_icon'))
    context.visual.stylify_metatags = str2bool(
        rc_config.get('rhodecode_stylify_metatags'))
    context.visual.dashboard_items = safe_int(
        rc_config.get('rhodecode_dashboard_items', 100))
    context.visual.admin_grid_items = safe_int(
        rc_config.get('rhodecode_admin_grid_items', 100))
    context.visual.repository_fields = str2bool(
        rc_config.get('rhodecode_repository_fields'))
    context.visual.show_version = str2bool(
        rc_config.get('rhodecode_show_version'))
    context.visual.use_gravatar = str2bool(
        rc_config.get('rhodecode_use_gravatar'))
    context.visual.gravatar_url = rc_config.get('rhodecode_gravatar_url')
    context.visual.default_renderer = rc_config.get(
        'rhodecode_markup_renderer', 'rst')
    context.visual.rhodecode_support_url = \
        rc_config.get('rhodecode_support_url') or url('rhodecode_support')

    context.pre_code = rc_config.get('rhodecode_pre_code')
    context.post_code = rc_config.get('rhodecode_post_code')
    context.rhodecode_name = rc_config.get('rhodecode_title')
    context.default_encodings = aslist(config.get('default_encoding'), sep=',')
    # if we have specified default_encoding in the request, it has more
    # priority
    if request.GET.get('default_encoding'):
        context.default_encodings.insert(0, request.GET.get('default_encoding'))
    context.clone_uri_tmpl = rc_config.get('rhodecode_clone_uri_tmpl')

    # INI stored
    context.labs_active = str2bool(
        config.get('labs_settings_active', 'false'))
    context.visual.allow_repo_location_change = str2bool(
        config.get('allow_repo_location_change', True))
    context.visual.allow_custom_hooks_settings = str2bool(
        config.get('allow_custom_hooks_settings', True))
    context.debug_style = str2bool(config.get('debug_style', False))

    context.rhodecode_instanceid = config.get('instance_id')

    # AppEnlight
    context.appenlight_enabled = str2bool(config.get('appenlight', 'false'))
    context.appenlight_api_public_key = config.get(
        'appenlight.api_public_key', '')
    context.appenlight_server_url = config.get('appenlight.server_url', '')

    # END CONFIG VARS

    # TODO: This dosn't work when called from pylons compatibility tween.
    # Fix this and remove it from base controller.
    # context.repo_name = get_repo_slug(request)  # can be empty

    context.csrf_token = auth.get_csrf_token()
    context.backends = rhodecode.BACKENDS.keys()
    context.backends.sort()
    context.unread_notifications = NotificationModel().get_unread_cnt_for_user(
        context.rhodecode_user.user_id)
Exemplo n.º 7
0
def create_repo(form_data, cur_user):
    from rhodecode.model.repo import RepoModel
    from rhodecode.model.user import UserModel
    from rhodecode.model.settings import SettingsModel

    log = get_logger(create_repo)
    DBS = get_session()

    cur_user = UserModel(DBS)._get_user(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']
    private = form_data['repo_private']
    clone_uri = form_data.get('clone_uri')
    repo_group = safe_int(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)

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

    try:
        RepoModel(DBS)._create_repo(
            repo_name=repo_name_full,
            repo_type=repo_type,
            description=description,
            owner=owner,
            private=private,
            clone_uri=clone_uri,
            repo_group=repo_group,
            landing_rev=landing_rev,
            fork_of=fork_of,
            copy_fork_permissions=copy_fork_permissions,
            copy_group_permissions=copy_group_permissions,
            enable_statistics=enable_statistics,
            enable_locking=enable_locking,
            enable_downloads=enable_downloads,
            state=state)

        action_logger(cur_user, 'user_created_repo', repo_name_full, '', DBS)
        DBS.commit()

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

        # update repo commit caches initially
        repo.update_commit_cache()

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

    # it's an odd fix to make celery fail task when exception occurs
    def on_failure(self, *args, **kwargs):
        pass

    return True
def comment_pull_request(request,
                         apiuser,
                         repoid,
                         pullrequestid,
                         message=Optional(None),
                         status=Optional(None),
                         userid=Optional(OAttr('apiuser'))):
    """
    Comment on the pull request specified with the `pullrequestid`,
    in the |repo| specified by the `repoid`, and optionally change the
    review status.

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param repoid: The repository name or repository ID.
    :type repoid: str or int
    :param pullrequestid: The pull request ID.
    :type pullrequestid: int
    :param message: The text content of the comment.
    :type message: str
    :param status: (**Optional**) Set the approval status of the pull
        request. Valid options are:
        * not_reviewed
        * approved
        * rejected
        * under_review
    :type status: str
    :param userid: Comment on the pull request as this user
    :type userid: Optional(str or int)

    Example output:

    .. code-block:: bash

      id : <id_given_in_input>
      result :
        {
            "pull_request_id":  "<Integer>",
            "comment_id":       "<Integer>"
        }
      error :  null
    """
    repo = get_repo_or_error(repoid)
    if not isinstance(userid, Optional):
        if (has_superadmin_permission(apiuser)
                or HasRepoPermissionAnyApi('repository.admin')(
                    user=apiuser, repo_name=repo.repo_name)):
            apiuser = get_user_or_error(userid)
        else:
            raise JSONRPCError('userid is not the same as your user')

    pull_request = get_pull_request_or_error(pullrequestid)
    if not PullRequestModel().check_user_read(pull_request, apiuser, api=True):
        raise JSONRPCError('repository `%s` does not exist' % (repoid, ))
    message = Optional.extract(message)
    status = Optional.extract(status)
    if not message and not status:
        raise JSONRPCError('message and status parameter missing')

    if (status not in (st[0] for st in ChangesetStatus.STATUSES)
            and status is not None):
        raise JSONRPCError('unknown comment status`%s`' % status)

    allowed_to_change_status = PullRequestModel().check_user_change_status(
        pull_request, apiuser)
    text = message
    if status and allowed_to_change_status:
        st_message = (('Status change %(transition_icon)s %(status)s') % {
            'transition_icon': '>',
            'status': ChangesetStatus.get_status_lbl(status)
        })
        text = message or st_message

    rc_config = SettingsModel().get_all_settings()
    renderer = rc_config.get('rhodecode_markup_renderer', 'rst')
    comment = ChangesetCommentsModel().create(
        text=text,
        repo=pull_request.target_repo.repo_id,
        user=apiuser.user_id,
        pull_request=pull_request.pull_request_id,
        f_path=None,
        line_no=None,
        status_change=(ChangesetStatus.get_status_lbl(status)
                       if status and allowed_to_change_status else None),
        closing_pr=False,
        renderer=renderer)

    if allowed_to_change_status and status:
        ChangesetStatusModel().set_status(
            pull_request.target_repo.repo_id,
            status,
            apiuser.user_id,
            comment,
            pull_request=pull_request.pull_request_id)
        Session().flush()

    Session().commit()
    data = {
        'pull_request_id': pull_request.pull_request_id,
        'comment_id': comment.comment_id,
        'status': status
    }
    return data
Exemplo n.º 9
0
def repo2db_mapper(initial_repo_list, remove_obsolete=False):
    """
    maps all repos given in initial_repo_list, non existing repositories
    are created, if remove_obsolete is True it also checks for db entries
    that are not in initial_repo_list and removes them.

    :param initial_repo_list: list of repositories found by scanning methods
    :param remove_obsolete: check for obsolete entries in database
    """
    from rhodecode.model.repo import RepoModel
    from rhodecode.model.scm import ScmModel
    from rhodecode.model.repo_group import RepoGroupModel
    from rhodecode.model.settings import SettingsModel

    sa = meta.Session()
    repo_model = RepoModel()
    user = User.get_first_super_admin()
    added = []

    # creation defaults
    defs = SettingsModel().get_default_repo_settings(strip_prefix=True)
    enable_statistics = defs.get('repo_enable_statistics')
    enable_locking = defs.get('repo_enable_locking')
    enable_downloads = defs.get('repo_enable_downloads')
    private = defs.get('repo_private')

    for name, repo in initial_repo_list.items():
        group = map_groups(name)
        unicode_name = safe_unicode(name)
        db_repo = repo_model.get_by_repo_name(unicode_name)
        # found repo that is on filesystem not in RhodeCode database
        if not db_repo:
            log.info('repository %s not found, creating now', name)
            added.append(name)
            desc = (repo.description if repo.description != 'unknown' else
                    '%s repository' % name)

            db_repo = repo_model._create_repo(
                repo_name=name,
                repo_type=repo.alias,
                description=desc,
                repo_group=getattr(group, 'group_id', None),
                owner=user,
                enable_locking=enable_locking,
                enable_downloads=enable_downloads,
                enable_statistics=enable_statistics,
                private=private,
                state=Repository.STATE_CREATED)
            sa.commit()
            # we added that repo just now, and make sure we updated server info
            if db_repo.repo_type == 'git':
                git_repo = db_repo.scm_instance()
                # update repository server-info
                log.debug('Running update server info')
                git_repo._update_server_info()

            db_repo.update_commit_cache()

        config = db_repo._config
        config.set('extensions', 'largefiles', '')
        ScmModel().install_hooks(db_repo.scm_instance(config=config),
                                 repo_type=db_repo.repo_type)

    removed = []
    if remove_obsolete:
        # remove from database those repositories that are not in the filesystem
        for repo in sa.query(Repository).all():
            if repo.repo_name not in initial_repo_list.keys():
                log.debug("Removing non-existing repository found in db `%s`",
                          repo.repo_name)
                try:
                    RepoModel(sa).delete(repo, forks='detach', fs_remove=False)
                    sa.commit()
                    removed.append(repo.repo_name)
                except Exception:
                    # don't hold further removals on error
                    log.error(traceback.format_exc())
                    sa.rollback()

        def splitter(full_repo_name):
            _parts = full_repo_name.rsplit(RepoGroup.url_sep(), 1)
            gr_name = None
            if len(_parts) == 2:
                gr_name = _parts[0]
            return gr_name

        initial_repo_group_list = [
            splitter(x) for x in initial_repo_list.keys() if splitter(x)
        ]

        # remove from database those repository groups that are not in the
        # filesystem due to parent child relationships we need to delete them
        # in a specific order of most nested first
        all_groups = [x.group_name for x in sa.query(RepoGroup).all()]
        nested_sort = lambda gr: len(gr.split('/'))
        for group_name in sorted(all_groups, key=nested_sort, reverse=True):
            if group_name not in initial_repo_group_list:
                repo_group = RepoGroup.get_by_group_name(group_name)
                if (repo_group.children.all()
                        or not RepoGroupModel().check_exist_filesystem(
                            group_name=group_name, exc_on_failure=False)):
                    continue

                log.info(
                    'Removing non-existing repository group found in db `%s`',
                    group_name)
                try:
                    RepoGroupModel(sa).delete(group_name, fs_remove=False)
                    sa.commit()
                    removed.append(group_name)
                except Exception:
                    # don't hold further removals on error
                    log.exception('Unable to remove repository group `%s`',
                                  group_name)
                    sa.rollback()
                    raise

    return added, removed