Esempio n. 1
0
    def invalidate_cache(self, apiuser, repoid):
        """
        Dispatch cache invalidation action on given repo

        :param apiuser:
        :param repoid:
        """
        repo = get_repo_or_error(repoid)
        if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
            # check if we have admin permission for this repo !
            if HasRepoPermissionAnyApi('repository.admin',
                                       'repository.write')(user=apiuser,
                                            repo_name=repo.repo_name) is False:
                raise JSONRPCError('repository `%s` does not exist' % (repoid))

        try:
            invalidated_keys = ScmModel().mark_for_invalidation(repo.repo_name)
            Session().commit()
            return ('Cache for repository `%s` was invalidated: '
                    'invalidated cache keys: %s' % (repoid, invalidated_keys))
        except Exception:
            log.error(traceback.format_exc())
            raise JSONRPCError(
                'Error occurred during cache invalidation action'
            )
Esempio n. 2
0
    def get_locks(self, apiuser, userid=Optional(OAttr('apiuser'))):
        """
        Get all locks for given userid, if
        this command is runned by non-admin account userid is set to user
        who is calling this method, thus returning locks for himself

        :param apiuser:
        :param userid:
        """

        if not HasPermissionAnyApi('hg.admin')(user=apiuser):
            #make sure normal user does not pass someone else userid,
            #he is not allowed to do that
            if not isinstance(userid, Optional) and userid != apiuser.user_id:
                raise JSONRPCError('userid is not the same as your user')
        ret = []
        if isinstance(userid, Optional):
            user = None
        else:
            user = get_user_or_error(userid)

        #show all locks
        for r in Repository.getAll():
            userid, time_ = r.locked
            if time_:
                _api_data = r.get_api_data()
                # if we use userfilter just show the locks for this user
                if user:
                    if safe_int(userid) == user.user_id:
                        ret.append(_api_data)
                else:
                    ret.append(_api_data)

        return ret
Esempio n. 3
0
    def fork_repo(self, apiuser, repoid, fork_name, owner=Optional(OAttr('apiuser')),
                  description=Optional(''), copy_permissions=Optional(False),
                  private=Optional(False), landing_rev=Optional('tip')):
        repo = get_repo_or_error(repoid)
        repo_name = repo.repo_name

        _repo = RepoModel().get_by_repo_name(fork_name)
        if _repo:
            type_ = 'fork' if _repo.fork else 'repo'
            raise JSONRPCError("%s `%s` already exist" % (type_, fork_name))

        if HasPermissionAnyApi('hg.admin')(user=apiuser):
            pass
        elif HasRepoPermissionAnyApi('repository.admin',
                                     'repository.write',
                                     'repository.read')(user=apiuser,
                                                        repo_name=repo.repo_name):
            if not isinstance(owner, Optional):
                #forbid setting owner for non-admins
                raise JSONRPCError(
                    'Only RhodeCode admin can specify `owner` param'
                )
        else:
            raise JSONRPCError('repository `%s` does not exist' % (repoid))

        if isinstance(owner, Optional):
            owner = apiuser.user_id

        owner = get_user_or_error(owner)

        try:
            # create structure of groups and return the last group
            group = map_groups(fork_name)

            form_data = dict(
                repo_name=fork_name,
                repo_name_full=fork_name,
                repo_group=group,
                repo_type=repo.repo_type,
                description=Optional.extract(description),
                private=Optional.extract(private),
                copy_permissions=Optional.extract(copy_permissions),
                landing_rev=Optional.extract(landing_rev),
                update_after_clone=False,
                fork_parent_id=repo.repo_id,
            )
            RepoModel().create_fork(form_data, cur_user=owner)
            return dict(
                msg='Created fork of `%s` as `%s`' % (repo.repo_name,
                                                      fork_name),
                success=True  # cannot return the repo data here since fork
                              # cann be done async
            )
        except Exception:
            log.error(traceback.format_exc())
            raise JSONRPCError(
                'failed to fork repository `%s` as `%s`' % (repo_name,
                                                            fork_name)
            )
Esempio n. 4
0
def has_superadmin_permission(apiuser):
    """
    Return True if apiuser is admin or return False

    :param apiuser:
    """
    if HasPermissionAnyApi('hg.admin')(user=apiuser):
        return True
    return False
Esempio n. 5
0
    def get_repos(self, apiuser):
        """"
        Get all repositories

        :param apiuser:
        """
        result = []
        if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
            repos = RepoModel().get_all_user_repos(user=apiuser)
        else:
            repos = RepoModel().get_all()

        for repo in repos:
            result.append(repo.get_api_data())
        return result
Esempio n. 6
0
    def get_user(self, apiuser, userid=Optional(OAttr('apiuser'))):
        """"
        Get a user by username, or userid, if userid is given

        :param apiuser:
        :param userid:
        """
        if not HasPermissionAnyApi('hg.admin')(user=apiuser):
            #make sure normal user does not pass someone else userid,
            #he is not allowed to do that
            if not isinstance(userid, Optional) and userid != apiuser.user_id:
                raise JSONRPCError('userid is not the same as your user')

        if isinstance(userid, Optional):
            userid = apiuser.user_id

        user = get_user_or_error(userid)
        data = user.get_api_data()
        data['permissions'] = AuthUser(user_id=user.user_id).permissions
        return data
Esempio n. 7
0
    def delete_repo(self, apiuser, repoid, forks=Optional(None)):
        """
        Deletes a given repository

        :param apiuser:
        :param repoid:
        :param forks: detach or delete, what do do with attached forks for repo
        """
        repo = get_repo_or_error(repoid)

        if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
            # check if we have admin permission for this repo !
            if HasRepoPermissionAnyApi('repository.admin')(user=apiuser,
                                            repo_name=repo.repo_name) is False:
                raise JSONRPCError('repository `%s` does not exist' % (repoid))

        try:
            handle_forks = Optional.extract(forks)
            _forks_msg = ''
            _forks = [f for f in repo.forks]
            if handle_forks == 'detach':
                _forks_msg = ' ' + _('Detached %s forks') % len(_forks)
            elif handle_forks == 'delete':
                _forks_msg = ' ' + _('Deleted %s forks') % len(_forks)
            elif _forks:
                raise JSONRPCError(
                    'Cannot delete `%s` it still contains attached forks'
                    % repo.repo_name
                )

            RepoModel().delete(repo, forks=forks)
            Session().commit()
            return dict(
                msg='Deleted repository `%s`%s' % (repo.repo_name, _forks_msg),
                success=True
            )
        except Exception:
            log.error(traceback.format_exc())
            raise JSONRPCError(
                'failed to delete repository `%s`' % repo.repo_name
            )
Esempio n. 8
0
    def get_repo(self, apiuser, repoid):
        """"
        Get repository by name

        :param apiuser:
        :param repoid:
        """
        repo = get_repo_or_error(repoid)

        if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
            # check if we have admin permission for this repo !
            if HasRepoPermissionAnyApi('repository.admin')(user=apiuser,
                                            repo_name=repo.repo_name) is False:
                raise JSONRPCError('repository `%s` does not exist' % (repoid))

        members = []
        followers = []
        for user in repo.repo_to_perm:
            perm = user.permission.permission_name
            user = user.user
            user_data = user.get_api_data()
            user_data['type'] = "user"
            user_data['permission'] = perm
            members.append(user_data)

        for users_group in repo.users_group_to_perm:
            perm = users_group.permission.permission_name
            users_group = users_group.users_group
            users_group_data = users_group.get_api_data()
            users_group_data['type'] = "users_group"
            users_group_data['permission'] = perm
            members.append(users_group_data)

        for user in repo.followers:
            followers.append(user.user.get_api_data())

        data = repo.get_api_data()
        data['members'] = members
        data['followers'] = followers
        return data
def create_user_group(
        request, apiuser, group_name, description=Optional(''),
        owner=Optional(OAttr('apiuser')), active=Optional(True)):
    """
    Creates a new user group.

    This command can only be run using an |authtoken| with admin rights to
    the specified repository.

    This command takes the following options:

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param group_name: Set the name of the new user group.
    :type group_name: str
    :param description: Give a description of the new user group.
    :type description: str
    :param owner: Set the owner of the new user group.
        If not set, the owner is the |authtoken| user.
    :type owner: Optional(str or int)
    :param active: Set this group as active.
    :type active: Optional(``True`` | ``False``)

    Example output:

    .. code-block:: bash

        id : <id_given_in_input>
        result: {
                  "msg": "created new user group `<groupname>`",
                  "user_group": <user_group_object>
                }
        error:  null

    Example error output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : null
      error :  {
        "user group `<group name>` already exist"
        or
        "failed to create group `<group name>`"
      }

    """

    if not has_superadmin_permission(apiuser):
        if not HasPermissionAnyApi('hg.usergroup.create.true')(user=apiuser):
            raise JSONRPCForbidden()

    if UserGroupModel().get_by_name(group_name):
        raise JSONRPCError("user group `%s` already exist" % (group_name,))

    try:
        if isinstance(owner, Optional):
            owner = apiuser.user_id

        owner = get_user_or_error(owner)
        active = Optional.extract(active)
        description = Optional.extract(description)
        ug = UserGroupModel().create(
            name=group_name, description=description, owner=owner,
            active=active)
        Session().commit()
        return {
            'msg': 'created new user group `%s`' % group_name,
            'user_group': ug.get_api_data()
        }
    except Exception:
        log.exception("Error occurred during creation of user group")
        raise JSONRPCError('failed to create group `%s`' % (group_name,))
Esempio n. 10
0
def create_repo_group(request, apiuser, group_name, description=Optional(''),
                      owner=Optional(OAttr('apiuser')),
                      copy_permissions=Optional(False)):
    """
    Creates a repository group.

    * If the repository group name contains "/", all the required repository
      groups will be created.

      For example "foo/bar/baz" will create |repo| groups "foo" and "bar"
      (with "foo" as parent). It will also create the "baz" repository
      with "bar" as |repo| group.

    This command can only be run using an |authtoken| with admin
    permissions.

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param group_name: Set the repository group name.
    :type group_name: str
    :param description: Set the |repo| group description.
    :type description: str
    :param owner: Set the |repo| group owner.
    :type owner: str
    :param copy_permissions:
    :type copy_permissions:

    Example output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : {
          "msg": "Created new repo group `<repo_group_name>`"
          "repo_group": <repogroup_object>
      }
      error :  null


    Example error output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : null
      error :  {
        failed to create repo group `<repogroupid>`
      }

    """

    schema = RepoGroupSchema()
    try:
        data = schema.deserialize({
            'group_name': group_name
        })
    except colander.Invalid as e:
        raise JSONRPCError("Validation failed: %s" % (e.asdict(),))
    group_name = data['group_name']

    if isinstance(owner, Optional):
        owner = apiuser.user_id

    group_description = Optional.extract(description)
    copy_permissions = Optional.extract(copy_permissions)

    # get by full name with parents, check if it already exist
    if RepoGroup.get_by_group_name(group_name):
        raise JSONRPCError("repo group `%s` already exist" % (group_name,))

    (group_name_cleaned,
     parent_group_name) = RepoGroupModel()._get_group_name_and_parent(
        group_name)

    parent_group = None
    if parent_group_name:
        parent_group = get_repo_group_or_error(parent_group_name)

    if not HasPermissionAnyApi(
            'hg.admin', 'hg.repogroup.create.true')(user=apiuser):
        # check if we have admin permission for this parent repo group !
        # users without admin or hg.repogroup.create can only create other
        # groups in groups they own so this is a required, but can be empty
        parent_group = getattr(parent_group, 'group_name', '')
        _perms = ('group.admin',)
        if not HasRepoGroupPermissionAnyApi(*_perms)(
                user=apiuser, group_name=parent_group):
            raise JSONRPCForbidden()

    try:
        repo_group = RepoGroupModel().create(
            group_name=group_name,
            group_description=group_description,
            owner=owner,
            copy_permissions=copy_permissions)
        Session().commit()
        return {
            'msg': 'Created new repo group `%s`' % group_name,
            'repo_group': repo_group.get_api_data()
        }
    except Exception:
        log.exception("Exception occurred while trying create repo group")
        raise JSONRPCError(
            'failed to create repo group `%s`' % (group_name,))
Esempio n. 11
0
    def create_repo(self, apiuser, repo_name, owner=Optional(OAttr('apiuser')),
                    repo_type=Optional('hg'),
                    description=Optional(''), private=Optional(False),
                    clone_uri=Optional(None), landing_rev=Optional('tip'),
                    enable_statistics=Optional(False),
                    enable_locking=Optional(False),
                    enable_downloads=Optional(False)):
        """
        Create repository, if clone_url is given it makes a remote clone
        if repo_name is within a group name the groups will be created
        automatically if they aren't present

        :param apiuser:
        :param repo_name:
        :param onwer:
        :param repo_type:
        :param description:
        :param private:
        :param clone_uri:
        :param landing_rev:
        """
        if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
            if not isinstance(owner, Optional):
                #forbid setting owner for non-admins
                raise JSONRPCError(
                    'Only RhodeCode admin can specify `owner` param'
                )
        if isinstance(owner, Optional):
            owner = apiuser.user_id

        owner = get_user_or_error(owner)

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

        defs = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True)
        if isinstance(private, Optional):
            private = defs.get('repo_private') or Optional.extract(private)
        if isinstance(repo_type, Optional):
            repo_type = defs.get('repo_type')
        if isinstance(enable_statistics, Optional):
            enable_statistics = defs.get('repo_enable_statistics')
        if isinstance(enable_locking, Optional):
            enable_locking = defs.get('repo_enable_locking')
        if isinstance(enable_downloads, Optional):
            enable_downloads = defs.get('repo_enable_downloads')

        clone_uri = Optional.extract(clone_uri)
        description = Optional.extract(description)
        landing_rev = Optional.extract(landing_rev)

        try:
            # create structure of groups and return the last group
            group = map_groups(repo_name)

            repo = RepoModel().create_repo(
                repo_name=repo_name,
                repo_type=repo_type,
                description=description,
                owner=owner,
                private=private,
                clone_uri=clone_uri,
                repos_group=group,
                landing_rev=landing_rev,
                enable_statistics=enable_statistics,
                enable_downloads=enable_downloads,
                enable_locking=enable_locking
            )

            Session().commit()
            return dict(
                msg="Created new repository `%s`" % (repo.repo_name),
                repo=repo.get_api_data()
            )
        except Exception:
            log.error(traceback.format_exc())
            raise JSONRPCError('failed to create repository `%s`' % repo_name)
Esempio n. 12
0
    def lock(self, apiuser, repoid, locked=Optional(None),
             userid=Optional(OAttr('apiuser'))):
        """
        Set locking state on particular repository by given user, if
        this command is runned by non-admin account userid is set to user
        who is calling this method

        :param apiuser:
        :param repoid:
        :param userid:
        :param locked:
        """
        repo = get_repo_or_error(repoid)
        if HasPermissionAnyApi('hg.admin')(user=apiuser):
            pass
        elif HasRepoPermissionAnyApi('repository.admin',
                                     'repository.write')(user=apiuser,
                                                         repo_name=repo.repo_name):
            #make sure normal user does not pass someone else userid,
            #he is not allowed to do that
            if not isinstance(userid, Optional) and userid != apiuser.user_id:
                raise JSONRPCError(
                    'userid is not the same as your user'
                )
        else:
            raise JSONRPCError('repository `%s` does not exist' % (repoid))

        if isinstance(userid, Optional):
            userid = apiuser.user_id

        user = get_user_or_error(userid)

        if isinstance(locked, Optional):
            lockobj = Repository.getlock(repo)

            if lockobj[0] is None:
                return ('Repo `%s` not locked. Locked=`False`.'
                        % (repo.repo_name))
            else:
                userid, time_ = lockobj
                user = get_user_or_error(userid)

                return ('Repo `%s` locked by `%s`. Locked=`True`. '
                        'Locked since: `%s`'
                    % (repo.repo_name, user.username,
                       json.dumps(time_to_datetime(time_))))

        else:
            locked = str2bool(locked)
            try:
                if locked:
                    Repository.lock(repo, user.user_id)
                else:
                    Repository.unlock(repo)

                return ('User `%s` set lock state for repo `%s` to `%s`'
                        % (user.username, repo.repo_name, locked))
            except Exception:
                log.error(traceback.format_exc())
                raise JSONRPCError(
                    'Error occurred locking repository `%s`' % repo.repo_name
                )
Esempio n. 13
0
    def update_repo(self,
                    apiuser,
                    repoid,
                    name=Optional(None),
                    owner=Optional(OAttr('apiuser')),
                    group=Optional(None),
                    description=Optional(''),
                    private=Optional(False),
                    clone_uri=Optional(None),
                    landing_rev=Optional('tip'),
                    enable_statistics=Optional(False),
                    enable_locking=Optional(False),
                    enable_downloads=Optional(False)):
        """
        Updates repo

        :param apiuser: filled automatically from apikey
        :type apiuser: AuthUser
        :param repoid: repository name or repository id
        :type repoid: str or int
        :param name:
        :param owner:
        :param group:
        :param description:
        :param private:
        :param clone_uri:
        :param landing_rev:
        :param enable_statistics:
        :param enable_locking:
        :param enable_downloads:
        """
        repo = get_repo_or_error(repoid)
        if not HasPermissionAnyApi('hg.admin')(user=apiuser):
            # check if we have admin permission for this repo !
            if not HasRepoPermissionAnyApi('repository.admin')(
                    user=apiuser, repo_name=repo.repo_name):
                raise JSONRPCError('repository `%s` does not exist' %
                                   (repoid, ))

        updates = {
            # update function requires this.
            'repo_name': repo.repo_name
        }
        repo_group = group
        if not isinstance(repo_group, Optional):
            repo_group = get_repo_group_or_error(repo_group)
            repo_group = repo_group.group_id
        try:
            store_update(updates, name, 'repo_name')
            store_update(updates, repo_group, 'repo_group')
            store_update(updates, owner, 'user')
            store_update(updates, description, 'repo_description')
            store_update(updates, private, 'repo_private')
            store_update(updates, clone_uri, 'clone_uri')
            store_update(updates, landing_rev, 'repo_landing_rev')
            store_update(updates, enable_statistics, 'repo_enable_statistics')
            store_update(updates, enable_locking, 'repo_enable_locking')
            store_update(updates, enable_downloads, 'repo_enable_downloads')

            RepoModel().update(repo, **updates)
            Session().commit()
            return dict(msg='updated repo ID:%s %s' %
                        (repo.repo_id, repo.repo_name),
                        repository=repo.get_api_data())
        except Exception:
            log.error(traceback.format_exc())
            raise JSONRPCError('failed to update repo `%s`' % repoid)