def grant_user_permission_to_user_group(
        request, apiuser, usergroupid, userid, perm):
    """
    Set permissions for a user in a user group.

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param usergroupid: Set the user group to edit permissions on.
    :type usergroupid: str or int
    :param userid: Set the user from whom you wish to set permissions.
    :type userid: str
    :param perm: (usergroup.(none|read|write|admin))
    :type perm: str

    Example output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : {
        "msg": "Granted perm: `<perm_name>` for user: `<username>` in user group: `<user_group_name>`",
        "success": true
      }
      error :  null
    """

    user_group = get_user_group_or_error(usergroupid)

    if not has_superadmin_permission(apiuser):
        # check if we have admin permission for this user group !
        _perms = ('usergroup.admin',)
        if not HasUserGroupPermissionAnyApi(*_perms)(
                user=apiuser, user_group_name=user_group.users_group_name):
            raise JSONRPCError(
                'user group `%s` does not exist' % (usergroupid,))

    user = get_user_or_error(userid)
    perm = get_perm_or_error(perm, prefix='usergroup.')

    try:
        UserGroupModel().grant_user_permission(
            user_group=user_group, user=user, perm=perm)
        Session().commit()
        return {
            'msg':
                'Granted perm: `%s` for user: `%s` in user group: `%s`' % (
                    perm.permission_name, user.username,
                    user_group.users_group_name
                ),
            'success': True
        }
    except Exception:
        log.exception("Error occurred during editing permissions "
                      "for user in user group")
        raise JSONRPCError(
            'failed to edit permission for user: '******'`%s` in user group: `%s`' % (
                userid, user_group.users_group_name))
def close_pull_request(request,
                       apiuser,
                       repoid,
                       pullrequestid,
                       userid=Optional(OAttr('apiuser'))):
    """
    Close the pull request specified by `pullrequestid`.

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param repoid: Repository name or repository ID to which the pull
        request belongs.
    :type repoid: str or int
    :param pullrequestid: ID of the pull request to be closed.
    :type pullrequestid: int
    :param userid: Close 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":  "<int>",
            "closed":           "<bool>"
        },
      "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_update(
            pull_request, apiuser, api=True):
        raise JSONRPCError(
            'pull request `%s` close failed, no permission to close.' %
            (pullrequestid, ))
    if pull_request.is_closed():
        raise JSONRPCError('pull request `%s` is already closed' %
                           (pullrequestid, ))

    PullRequestModel().close_pull_request(pull_request.pull_request_id,
                                          apiuser)
    Session.commit()
    data = {
        'pull_request_id': pull_request.pull_request_id,
        'closed': True,
    }
    return data
def remove_user_from_user_group(request, apiuser, usergroupid, userid):
    """
    Removes a user from a user group.

    * If the specified user is not in the group, this command will return
      `false`.

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

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param usergroupid: Sets the user group name.
    :type usergroupid: str or int
    :param userid: The user you wish to remove from |RCE|.
    :type userid: str or int

    Example output:

    .. code-block:: bash

        id : <id_given_in_input>
        result: {
                  "success":  True|False,  # depends on if member is in group
                  "msg": "removed member <username> from user group <groupname> |
                          User wasn't in group"
                }
        error:  null

    """

    user = get_user_or_error(userid)
    user_group = get_user_group_or_error(usergroupid)
    if not has_superadmin_permission(apiuser):
        # check if we have admin permission for this user group !
        _perms = ('usergroup.admin',)
        if not HasUserGroupPermissionAnyApi(*_perms)(
                user=apiuser, user_group_name=user_group.users_group_name):
            raise JSONRPCError(
                'user group `%s` does not exist' % (usergroupid,))

    try:
        success = UserGroupModel().remove_user_from_group(user_group, user)
        msg = 'removed member `%s` from user group `%s`' % (
            user.username, user_group.users_group_name
        )
        msg = msg if success else "User wasn't in group"
        Session().commit()
        return {'success': success, 'msg': msg}
    except Exception:
        log.exception("Error occurred during removing an member from user group")
        raise JSONRPCError(
            'failed to remove member from user group `%s`' % (
                user_group.users_group_name,
            )
        )
def revoke_user_permission_from_user_group(
        request, apiuser, usergroupid, userid):
    """
    Revoke a users permissions in a user group.

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param usergroupid: Set the user group from which to revoke the user
        permissions.
    :type: usergroupid: str or int
    :param userid: Set the userid of the user whose permissions will be
        revoked.
    :type userid: str

    Example output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : {
        "msg": "Revoked perm for user: `<username>` in user group: `<user_group_name>`",
        "success": true
      }
      error :  null
    """

    user_group = get_user_group_or_error(usergroupid)

    if not has_superadmin_permission(apiuser):
        # check if we have admin permission for this user group !
        _perms = ('usergroup.admin',)
        if not HasUserGroupPermissionAnyApi(*_perms)(
                user=apiuser, user_group_name=user_group.users_group_name):
            raise JSONRPCError(
                'user group `%s` does not exist' % (usergroupid,))

    user = get_user_or_error(userid)

    try:
        UserGroupModel().revoke_user_permission(
            user_group=user_group, user=user)
        Session().commit()
        return {
            'msg': 'Revoked perm for user: `%s` in user group: `%s`' % (
                user.username, user_group.users_group_name
            ),
            'success': True
        }
    except Exception:
        log.exception("Error occurred during editing permissions "
                      "for user in user group")
        raise JSONRPCError(
            'failed to edit permission for user: `%s` in user group: `%s`'
            % (userid, user_group.users_group_name))
예제 #5
0
def delete_repo_group(request, apiuser, repogroupid):
    """
    Deletes a |repo| group.

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param repogroupid: Set the name or ID of repository group to be
        deleted.
    :type repogroupid: str or int

    Example output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : {
        'msg': 'deleted repo group ID:<repogroupid> <repogroupname>
        'repo_group': null
      }
      error :  null

    Example error output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : null
      error :  {
        "failed to delete repo group ID:<repogroupid> <repogroupname>"
      }

    """

    repo_group = get_repo_group_or_error(repogroupid)
    if not has_superadmin_permission(apiuser):
        # check if we have admin permission for this repo group !
        _perms = ('group.admin',)
        if not HasRepoGroupPermissionAnyApi(*_perms)(
                user=apiuser, group_name=repo_group.group_name):
            raise JSONRPCError(
                'repository group `%s` does not exist' % (repogroupid,))
    try:
        RepoGroupModel().delete(repo_group)
        Session().commit()
        return {
            'msg': 'deleted repo group ID:%s %s' %
                   (repo_group.group_id, repo_group.group_name),
            'repo_group': None
        }
    except Exception:
        log.exception("Exception occurred while trying to delete repo group")
        raise JSONRPCError('failed to delete repo group ID:%s %s' %
                           (repo_group.group_id, repo_group.group_name))
예제 #6
0
def update_repo_group(
        request, apiuser, repogroupid, group_name=Optional(''),
        description=Optional(''), owner=Optional(OAttr('apiuser')),
        parent=Optional(None), enable_locking=Optional(False)):
    """
    Updates repository group with the details given.

    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 repogroupid: Set the ID of repository group.
    :type repogroupid: str or int
    :param group_name: Set the name of the |repo| group.
    :type group_name: str
    :param description: Set a description for the group.
    :type description: str
    :param owner: Set the |repo| group owner.
    :type owner: str
    :param parent: Set the |repo| group parent.
    :type parent: str or int
    :param enable_locking: Enable |repo| locking. The default is false.
    :type enable_locking: bool
    """

    repo_group = get_repo_group_or_error(repogroupid)
    if not has_superadmin_permission(apiuser):
        # check if we have admin permission for this repo group !
        _perms = ('group.admin',)
        if not HasRepoGroupPermissionAnyApi(*_perms)(
                user=apiuser, group_name=repo_group.group_name):
            raise JSONRPCError(
                'repository group `%s` does not exist' % (repogroupid,))

    updates = {}
    try:
        store_update(updates, group_name, 'group_name')
        store_update(updates, description, 'group_description')
        store_update(updates, owner, 'user')
        store_update(updates, parent, 'group_parent_id')
        store_update(updates, enable_locking, 'enable_locking')
        repo_group = RepoGroupModel().update(repo_group, updates)
        Session().commit()
        return {
            'msg': 'updated repository group ID:%s %s' % (
                repo_group.group_id, repo_group.group_name),
            'repo_group': repo_group.get_api_data()
        }
    except Exception:
        log.exception("Exception occurred while trying update repo group")
        raise JSONRPCError('failed to update repository group `%s`'
                           % (repogroupid,))
예제 #7
0
def delete_gist(request, apiuser, gistid):
    """
    Deletes existing gist

    :param apiuser: filled automatically from apikey
    :type apiuser: AuthUser
    :param gistid: id of gist to delete
    :type gistid: str

    Example output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : {
        "deleted gist ID: <gist_id>",
        "gist": null
      }
      error :  null

    Example error output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : null
      error :  {
        "failed to delete gist ID:<gist_id>"
      }

    """

    gist = get_gist_or_error(gistid)
    if not has_superadmin_permission(apiuser):
        if gist.gist_owner != apiuser.user_id:
            raise JSONRPCError('gist `%s` does not exist' % (gistid,))

    try:
        GistModel().delete(gist)
        Session().commit()
        return {
            'msg': 'deleted gist ID:%s' % (gist.gist_access_id,),
            'gist': None
        }
    except Exception:
        log.exception('Error occured during gist deletion')
        raise JSONRPCError('failed to delete gist ID:%s'
                           % (gist.gist_access_id,))
예제 #8
0
def get_gists(request, apiuser, userid=Optional(OAttr('apiuser'))):
    """
    Get all gists for given user. If userid is empty returned gists
    are for user who called the api

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param userid: user to get gists for
    :type userid: Optional(str or int)
    """

    if not has_superadmin_permission(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):
        user_id = apiuser.user_id
    else:
        user_id = get_user_or_error(userid).user_id

    gists = []
    _gists = Gist().query() \
        .filter(or_(
        Gist.gist_expires == -1, Gist.gist_expires >= time.time())) \
        .filter(Gist.gist_owner == user_id) \
        .order_by(Gist.created_on.desc())
    for gist in _gists:
        gists.append(gist.get_api_data())
    return gists
예제 #9
0
def delete_user(request, apiuser, userid):
    """
    Deletes the specified user from the |RCE| user database.

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

    .. important::

       Ensure all open pull requests and open code review
       requests to this user are close.

       Also ensure all repositories, or repository groups owned by this
       user are reassigned before deletion.

    This command takes the following options:

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param userid: Set the user to delete.
    :type userid: str or int

    Example output:

    .. code-block:: bash

        id : <id_given_in_input>
        result: {
                  "msg" : "deleted user ID:<userid> <username>",
                  "user": null
                }
        error:  null

    Example error output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : null
      error :  {
        "failed to delete user ID:<userid> <username>"
      }

    """
    if not has_superadmin_permission(apiuser):
        raise JSONRPCForbidden()

    user = get_user_or_error(userid)

    try:
        UserModel().delete(userid)
        Session().commit()
        return {
            'msg': 'deleted user ID:%s %s' % (user.user_id, user.username),
            'user': None
        }
    except Exception:
        log.exception("Error occurred during deleting of user")
        raise JSONRPCError('failed to delete user ID:%s %s' %
                           (user.user_id, user.username))
예제 #10
0
def rescan_repos(request, apiuser, remove_obsolete=Optional(False)):
    """
    Triggers a rescan of the specified repositories.

    * If the ``remove_obsolete`` option is set, it also deletes repositories
      that are found in the database but not on the file system, so called
      "clean zombies".

    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 remove_obsolete: Deletes repositories from the database that
        are not found on the filesystem.
    :type remove_obsolete: Optional(``True`` | ``False``)

    Example output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : {
        'added': [<added repository name>,...]
        'removed': [<removed repository name>,...]
      }
      error :  null

    Example error output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : null
      error :  {
        'Error occurred during rescan repositories action'
      }

    """
    if not has_superadmin_permission(apiuser):
        raise JSONRPCForbidden()

    try:
        rm_obsolete = Optional.extract(remove_obsolete)
        added, removed = repo2db_mapper(ScmModel().repo_scan(),
                                        remove_obsolete=rm_obsolete)
        return {'added': added, 'removed': removed}
    except Exception:
        log.exception('Failed to run repo rescann')
        raise JSONRPCError(
            'Error occurred during rescan repositories action'
        )
예제 #11
0
def get_user_locks(request, apiuser, userid=Optional(OAttr('apiuser'))):
    """
    Displays all repositories locked by the specified user.

    * If this command is run by a non-admin user, it returns
      a list of |repos| locked by that user.

    This command takes the following options:

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param userid: Sets the userid whose list of locked |repos| will be
        displayed.
    :type userid: Optional(str or int)

    Example output:

    .. code-block:: bash

        id : <id_given_in_input>
        result : {
            [repo_object, repo_object,...]
        }
        error :  null
    """

    include_secrets = False
    if not has_superadmin_permission(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')
    else:
        include_secrets = True

    userid = Optional.extract(userid, evaluate_locals=locals())
    userid = getattr(userid, 'user_id', userid)
    user = get_user_or_error(userid)

    ret = []

    # show all locks
    for r in Repository.getAll():
        _user_id, _time, _reason = r.locked
        if _user_id and _time:
            _api_data = r.get_api_data(include_secrets=include_secrets)
            # if we use user filter just show the locks for this user
            if safe_int(_user_id) == user.user_id:
                ret.append(_api_data)

    return ret
예제 #12
0
def get_gist(request, apiuser, gistid, content=Optional(False)):
    """
    Get the specified gist, based on the gist ID.

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param gistid: Set the id of the private or public gist
    :type gistid: str
    :param content: Return the gist content. Default is false.
    :type content: Optional(bool)
    """

    gist = get_gist_or_error(gistid)
    content = Optional.extract(content)
    if not has_superadmin_permission(apiuser):
        if gist.gist_owner != apiuser.user_id:
            raise JSONRPCError('gist `%s` does not exist' % (gistid,))
    data = gist.get_api_data()
    if content:
        from rhodecode.model.gist import GistModel
        rev, gist_files = GistModel().get_gist_files(gistid)
        data['content'] = dict([(x.path, x.content) for x in gist_files])
    return data
def delete_user_group(request, apiuser, usergroupid):
    """
    Deletes the specified `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: filled automatically from apikey
    :type apiuser: AuthUser
    :param usergroupid:
    :type usergroupid: int

    Example output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : {
        "msg": "deleted user group ID:<user_group_id> <user_group_name>"
      }
      error :  null

    Example error output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : null
      error :  {
        "failed to delete user group ID:<user_group_id> <user_group_name>"
        or
        "RepoGroup assigned to <repo_groups_list>"
      }

    """

    user_group = get_user_group_or_error(usergroupid)
    if not has_superadmin_permission(apiuser):
        # check if we have admin permission for this user group !
        _perms = ('usergroup.admin',)
        if not HasUserGroupPermissionAnyApi(*_perms)(
                user=apiuser, user_group_name=user_group.users_group_name):
            raise JSONRPCError(
                'user group `%s` does not exist' % (usergroupid,))

    try:
        UserGroupModel().delete(user_group)
        Session().commit()
        return {
            'msg': 'deleted user group ID:%s %s' % (
                user_group.users_group_id, user_group.users_group_name),
            'user_group': None
        }
    except UserGroupAssignedException as e:
        log.exception("UserGroupAssigned error")
        raise JSONRPCError(str(e))
    except Exception:
        log.exception("Error occurred during deletion of user group")
        raise JSONRPCError(
            'failed to delete user group ID:%s %s' %(
                user_group.users_group_id, user_group.users_group_name))
def update_user_group(request, apiuser, usergroupid, group_name=Optional(''),
                      description=Optional(''), owner=Optional(None),
                      active=Optional(True)):
    """
    Updates the specified `user group` with the details provided.

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

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param usergroupid: Set the id of the `user group` to update.
    :type usergroupid: str or int
    :param group_name: Set the new name the `user group`
    :type group_name: str
    :param description: Give a description for the `user group`
    :type description: str
    :param owner: Set the owner of the `user group`.
    :type owner: Optional(str or int)
    :param active: Set the group as active.
    :type active: Optional(``True`` | ``False``)

    Example output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : {
        "msg": 'updated user group ID:<user group id> <user group name>',
        "user_group": <user_group_object>
      }
      error :  null

    Example error output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : null
      error :  {
        "failed to update user group `<user group name>`"
      }

    """

    user_group = get_user_group_or_error(usergroupid)
    include_secrets = False
    if not has_superadmin_permission(apiuser):
        # check if we have admin permission for this user group !
        _perms = ('usergroup.admin',)
        if not HasUserGroupPermissionAnyApi(*_perms)(
                user=apiuser, user_group_name=user_group.users_group_name):
            raise JSONRPCError(
                'user group `%s` does not exist' % (usergroupid,))
    else:
        include_secrets = True

    if not isinstance(owner, Optional):
        owner = get_user_or_error(owner)

    updates = {}
    store_update(updates, group_name, 'users_group_name')
    store_update(updates, description, 'user_group_description')
    store_update(updates, owner, 'user')
    store_update(updates, active, 'users_group_active')
    try:
        UserGroupModel().update(user_group, updates)
        Session().commit()
        return {
            'msg': 'updated user group ID:%s %s' % (
                user_group.users_group_id, user_group.users_group_name),
            'user_group': user_group.get_api_data(
                include_secrets=include_secrets)
        }
    except Exception:
        log.exception("Error occurred during update of user group")
        raise JSONRPCError(
            'failed to update user group `%s`' % (usergroupid,))
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,))
예제 #16
0
def get_user(request, apiuser, userid=Optional(OAttr('apiuser'))):
    """
    Returns the information associated with a username or userid.

    * If the ``userid`` is not set, this command returns the information
      for the ``userid`` calling the method.

    .. note::

       Normal users may only run this command against their ``userid``. For
       full privileges you must run this command using an |authtoken| with
       admin rights.

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param userid: Sets the userid for which data will be returned.
    :type userid: Optional(str or int)

    Example output:

    .. code-block:: bash

        {
          "error": null,
          "id": <id>,
          "result": {
            "active": true,
            "admin": false,
            "api_key": "api-key",
            "api_keys": [ list of keys ],
            "email": "*****@*****.**",
            "emails": [
              "*****@*****.**"
            ],
            "extern_name": "rhodecode",
            "extern_type": "rhodecode",
            "firstname": "username",
            "ip_addresses": [],
            "language": null,
            "last_login": "******",
            "lastname": "surnae",
            "permissions": {
              "global": [
                "hg.inherit_default_perms.true",
                "usergroup.read",
                "hg.repogroup.create.false",
                "hg.create.none",
                "hg.extern_activate.manual",
                "hg.create.write_on_repogroup.false",
                "hg.usergroup.create.false",
                "group.none",
                "repository.none",
                "hg.register.none",
                "hg.fork.repository"
              ],
              "repositories": { "username/example": "repository.write"},
              "repositories_groups": { "user-group/repo": "group.none" },
              "user_groups": { "user_group_name": "usergroup.read" }
            },
            "user_id": 32,
            "username": "******"
          }
        }
    """

    if not has_superadmin_permission(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')

    userid = Optional.extract(userid, evaluate_locals=locals())
    userid = getattr(userid, 'user_id', userid)

    user = get_user_or_error(userid)
    data = user.get_api_data(include_secrets=True)
    data['permissions'] = AuthUser(user_id=user.user_id).permissions
    return data
def create_pull_request(request,
                        apiuser,
                        source_repo,
                        target_repo,
                        source_ref,
                        target_ref,
                        title,
                        description=Optional(''),
                        reviewers=Optional(None)):
    """
    Creates a new pull request.

    Accepts refs in the following formats:

        * branch:<branch_name>:<sha>
        * branch:<branch_name>
        * bookmark:<bookmark_name>:<sha> (Mercurial only)
        * bookmark:<bookmark_name> (Mercurial only)

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param source_repo: Set the source repository name.
    :type source_repo: str
    :param target_repo: Set the target repository name.
    :type target_repo: str
    :param source_ref: Set the source ref name.
    :type source_ref: str
    :param target_ref: Set the target ref name.
    :type target_ref: str
    :param title: Set the pull request title.
    :type title: str
    :param description: Set the pull request description.
    :type description: Optional(str)
    :param reviewers: Set the new pull request reviewers list.
    :type reviewers: Optional(list)
    """
    source = get_repo_or_error(source_repo)
    target = get_repo_or_error(target_repo)
    if not has_superadmin_permission(apiuser):
        _perms = (
            'repository.admin',
            'repository.write',
            'repository.read',
        )
        has_repo_permissions(apiuser, source_repo, source, _perms)

    full_source_ref = resolve_ref_or_error(source_ref, source)
    full_target_ref = resolve_ref_or_error(target_ref, target)
    source_commit = get_commit_or_error(full_source_ref, source)
    target_commit = get_commit_or_error(full_target_ref, target)
    source_scm = source.scm_instance()
    target_scm = target.scm_instance()

    commit_ranges = target_scm.compare(target_commit.raw_id,
                                       source_commit.raw_id,
                                       source_scm,
                                       merge=True,
                                       pre_load=[])

    ancestor = target_scm.get_common_ancestor(target_commit.raw_id,
                                              source_commit.raw_id, source_scm)

    if not commit_ranges:
        raise JSONRPCError('no commits found')

    if not ancestor:
        raise JSONRPCError('no common ancestor found')

    reviewer_names = Optional.extract(reviewers) or []
    if not isinstance(reviewer_names, list):
        raise JSONRPCError('reviewers should be specified as a list')

    reviewer_users = [get_user_or_error(n) for n in reviewer_names]
    reviewer_ids = [u.user_id for u in reviewer_users]

    pull_request_model = PullRequestModel()
    pull_request = pull_request_model.create(
        created_by=apiuser.user_id,
        source_repo=source_repo,
        source_ref=full_source_ref,
        target_repo=target_repo,
        target_ref=full_target_ref,
        revisions=reversed(
            [commit.raw_id for commit in reversed(commit_ranges)]),
        reviewers=reviewer_ids,
        title=title,
        description=Optional.extract(description))

    Session().commit()
    data = {
        'msg': 'Created new pull request `{}`'.format(title),
        'pull_request_id': pull_request.pull_request_id,
    }
    return data
예제 #18
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,))
예제 #19
0
def get_repo_group(request, apiuser, repogroupid):
    """
    Return the specified |repo| group, along with permissions,
    and repositories inside the group

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param repogroupid: Specify the name of ID of the repository group.
    :type repogroupid: str or int


    Example output:

    .. code-block:: bash

        {
          "error": null,
          "id": repo-group-id,
          "result": {
            "group_description": "repo group description",
            "group_id": 14,
            "group_name": "group name",
            "members": [
              {
                "name": "super-admin-username",
                "origin": "super-admin",
                "permission": "group.admin",
                "type": "user"
              },
              {
                "name": "owner-name",
                "origin": "owner",
                "permission": "group.admin",
                "type": "user"
              },
              {
                "name": "user-group-name",
                "origin": "permission",
                "permission": "group.write",
                "type": "user_group"
              }
            ],
            "owner": "owner-name",
            "parent_group": null,
            "repositories": [ repo-list ]
          }
        }
    """

    repo_group = get_repo_group_or_error(repogroupid)
    if not has_superadmin_permission(apiuser):
        # check if we have at least read permission for this repo group !
        _perms = ('group.admin', 'group.write', 'group.read',)
        if not HasRepoGroupPermissionAnyApi(*_perms)(
                user=apiuser, group_name=repo_group.group_name):
            raise JSONRPCError(
                'repository group `%s` does not exist' % (repogroupid,))

    permissions = []
    for _user in repo_group.permissions():
        user_data = {
            'name': _user.username,
            'permission': _user.permission,
            'origin': get_origin(_user),
            'type': "user",
        }
        permissions.append(user_data)

    for _user_group in repo_group.permission_user_groups():
        user_group_data = {
            'name': _user_group.users_group_name,
            'permission': _user_group.permission,
            'origin': get_origin(_user_group),
            'type': "user_group",
        }
        permissions.append(user_group_data)

    data = repo_group.get_api_data()
    data["members"] = permissions  # TODO: this should be named permissions
    return data
def get_user_group(request, apiuser, usergroupid):
    """
    Returns the data of an existing user group.

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

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param usergroupid: Set the user group from which to return data.
    :type usergroupid: str or int

    Example error output:

    .. code-block:: bash

        {
          "error": null,
          "id": <id>,
          "result": {
            "active": true,
            "group_description": "group description",
            "group_name": "group name",
            "members": [
              {
                "name": "owner-name",
                "origin": "owner",
                "permission": "usergroup.admin",
                "type": "user"
              },
              {
              {
                "name": "user name",
                "origin": "permission",
                "permission": "usergroup.admin",
                "type": "user"
              },
              {
                "name": "user group name",
                "origin": "permission",
                "permission": "usergroup.write",
                "type": "user_group"
              }
            ],
            "owner": "owner name",
            "users": [],
            "users_group_id": 2
          }
        }

    """

    user_group = get_user_group_or_error(usergroupid)
    if not has_superadmin_permission(apiuser):
        # check if we have at least read permission for this user group !
        _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',)
        if not HasUserGroupPermissionAnyApi(*_perms)(
                user=apiuser, user_group_name=user_group.users_group_name):
            raise JSONRPCError('user group `%s` does not exist' % (
                usergroupid,))

    permissions = []
    for _user in user_group.permissions():
        user_data = {
            'name': _user.username,
            'permission': _user.permission,
            'origin': get_origin(_user),
            'type': "user",
        }
        permissions.append(user_data)

    for _user_group in user_group.permission_user_groups():
        user_group_data = {
            'name': _user_group.users_group_name,
            'permission': _user_group.permission,
            'origin': get_origin(_user_group),
            'type': "user_group",
        }
        permissions.append(user_group_data)

    data = user_group.get_api_data()
    data['members'] = permissions

    return data
예제 #21
0
def grant_user_group_permission_to_repo_group(
        request, apiuser, repogroupid, usergroupid, perm,
        apply_to_children=Optional('none'), ):
    """
    Grant permission for a user group on given repository group, or update
    existing permissions if found.

    This command can only be run using an |authtoken| with admin
    permissions on the |repo| group.

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param repogroupid: Set the name or id of repository group
    :type repogroupid: str or int
    :param usergroupid: id of usergroup
    :type usergroupid: str or int
    :param perm: (group.(none|read|write|admin))
    :type perm: str
    :param apply_to_children: 'none', 'repos', 'groups', 'all'
    :type apply_to_children: str

    Example output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : {
        "msg" : "Granted perm: `<perm>` (recursive:<apply_to_children>) for user group: `<usersgroupname>` in repo group: `<repo_group_name>`",
        "success": true

      }
      error :  null

    Example error output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : null
      error :  {
        "failed to edit permission for user group: `<usergroup>` in repo group: `<repo_group_name>`"
      }

    """

    repo_group = get_repo_group_or_error(repogroupid)
    perm = get_perm_or_error(perm, prefix='group.')
    user_group = get_user_group_or_error(usergroupid)
    if not has_superadmin_permission(apiuser):
        # check if we have admin permission for this repo group !
        _perms = ('group.admin',)
        if not HasRepoGroupPermissionAnyApi(*_perms)(
                user=apiuser, group_name=repo_group.group_name):
            raise JSONRPCError(
                'repository group `%s` does not exist' % (repogroupid,))

        # check if we have at least read permission for this user group !
        _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',)
        if not HasUserGroupPermissionAnyApi(*_perms)(
                user=apiuser, user_group_name=user_group.users_group_name):
            raise JSONRPCError(
                'user group `%s` does not exist' % (usergroupid,))

    apply_to_children = Optional.extract(apply_to_children)

    perm_additions = [[user_group.users_group_id, perm, "user_group"]]
    try:
        RepoGroupModel().update_permissions(repo_group=repo_group,
                                            perm_additions=perm_additions,
                                            recursive=apply_to_children,
                                            cur_user=apiuser)
        Session().commit()
        return {
            'msg': 'Granted perm: `%s` (recursive:%s) '
                   'for user group: `%s` in repo group: `%s`' % (
                       perm.permission_name, apply_to_children,
                       user_group.users_group_name, repo_group.name
                   ),
            'success': True
        }
    except Exception:
        log.exception("Exception occurred while trying to grant user "
                      "group permissions to repo group")
        raise JSONRPCError(
            'failed to edit permission for user group: `%s` in '
            'repo group: `%s`' % (
                usergroupid, repo_group.name
            )
        )
예제 #22
0
def revoke_user_group_permission_from_repo_group(
        request, apiuser, repogroupid, usergroupid,
        apply_to_children=Optional('none')):
    """
    Revoke permission for user group on given repository.

    This command can only be run using an |authtoken| with admin
    permissions on the |repo| group.

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param repogroupid: name or id of repository group
    :type repogroupid: str or int
    :param usergroupid:
    :param apply_to_children: 'none', 'repos', 'groups', 'all'
    :type apply_to_children: str

    Example output:

    .. code-block:: bash

        id : <id_given_in_input>
        result: {
                  "msg" : "Revoked perm (recursive:<apply_to_children>) for user group: `<usersgroupname>` in repo group: `<repo_group_name>`",
                  "success": true
                }
        error:  null

    Example error output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : null
      error :  {
        "failed to edit permission for user group: `<usergroup>` in repo group: `<repo_group_name>`"
      }


    """

    repo_group = get_repo_group_or_error(repogroupid)
    user_group = get_user_group_or_error(usergroupid)
    if not has_superadmin_permission(apiuser):
        # check if we have admin permission for this repo group !
        _perms = ('group.admin',)
        if not HasRepoGroupPermissionAnyApi(*_perms)(
                user=apiuser, group_name=repo_group.group_name):
            raise JSONRPCError(
                'repository group `%s` does not exist' % (repogroupid,))

        # check if we have at least read permission for this user group !
        _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',)
        if not HasUserGroupPermissionAnyApi(*_perms)(
                user=apiuser, user_group_name=user_group.users_group_name):
            raise JSONRPCError(
                'user group `%s` does not exist' % (usergroupid,))

    apply_to_children = Optional.extract(apply_to_children)

    perm_deletions = [[user_group.users_group_id, None, "user_group"]]
    try:
        RepoGroupModel().update_permissions(repo_group=repo_group,
                                            perm_deletions=perm_deletions,
                                            recursive=apply_to_children,
                                            cur_user=apiuser)
        Session().commit()
        return {
            'msg': 'Revoked perm (recursive:%s) for user group: '
                   '`%s` in repo group: `%s`' % (
                       apply_to_children, user_group.users_group_name,
                       repo_group.name
                   ),
            'success': True
        }
    except Exception:
        log.exception("Exception occurred while trying revoke user group "
                      "permissions from repo group")
        raise JSONRPCError(
            'failed to edit permission for user group: '
            '`%s` in repo group: `%s`' % (
                user_group.users_group_name, repo_group.name
            )
        )
def add_user_to_user_group(request, apiuser, usergroupid, userid):
    """
    Adds a user to a `user group`. If the user already exists in the group
    this command will return false.

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

    This command takes the following options:

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param usergroupid: Set the name of the `user group` to which a
        user will be added.
    :type usergroupid: int
    :param userid: Set the `user_id` of the user to add to the group.
    :type userid: int

    Example output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : {
          "success": True|False # depends on if member is in group
          "msg": "added member `<username>` to user group `<groupname>` |
                  User is already in that group"

      }
      error :  null

    Example error output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : null
      error :  {
        "failed to add member to user group `<user_group_name>`"
      }

    """

    user = get_user_or_error(userid)
    user_group = get_user_group_or_error(usergroupid)
    if not has_superadmin_permission(apiuser):
        # check if we have admin permission for this user group !
        _perms = ('usergroup.admin',)
        if not HasUserGroupPermissionAnyApi(*_perms)(
                user=apiuser, user_group_name=user_group.users_group_name):
            raise JSONRPCError('user group `%s` does not exist' % (
                usergroupid,))

    try:
        ugm = UserGroupModel().add_user_to_group(user_group, user)
        success = True if ugm is not True else False
        msg = 'added member `%s` to user group `%s`' % (
            user.username, user_group.users_group_name
        )
        msg = msg if success else 'User is already in that group'
        Session().commit()

        return {
            'success': success,
            'msg': msg
        }
    except Exception:
        log.exception("Error occurred during adding a member to user group")
        raise JSONRPCError(
            'failed to add member to user group `%s`' % (
                user_group.users_group_name,
            )
        )
def revoke_user_group_permission_from_user_group(
        request, apiuser, usergroupid, sourceusergroupid):
    """
    Revoke the permissions that one user group has to another.

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param usergroupid: Set the user group on which to edit permissions.
    :type usergroupid: str or int
    :param sourceusergroupid: Set the user group from which permissions
        are revoked.
    :type sourceusergroupid: str or int

    Example output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : {
        "msg": "Revoked perm for user group: `<user_group_name>` in user group: `<target_user_group_name>`",
        "success": true
      }
      error :  null
    """

    user_group = get_user_group_or_error(sourceusergroupid)
    target_user_group = get_user_group_or_error(usergroupid)

    if not has_superadmin_permission(apiuser):
        # check if we have admin permission for this user group !
        _perms = ('usergroup.admin',)
        if not HasUserGroupPermissionAnyApi(*_perms)(
                user=apiuser,
                user_group_name=target_user_group.users_group_name):
            raise JSONRPCError(
                'to user group `%s` does not exist' % (usergroupid,))

        # check if we have at least read permission
        # for the source user group !
        _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',)
        if not HasUserGroupPermissionAnyApi(*_perms)(
                user=apiuser, user_group_name=user_group.users_group_name):
            raise JSONRPCError(
                'user group `%s` does not exist' % (sourceusergroupid,))

    try:
        UserGroupModel().revoke_user_group_permission(
            target_user_group=target_user_group, user_group=user_group)
        Session().commit()

        return {
            'msg': 'Revoked perm for user group: '
                   '`%s` in user group: `%s`' % (
                       user_group.users_group_name,
                       target_user_group.users_group_name
                   ),
            'success': True
        }
    except Exception:
        log.exception("Error occurred during editing permissions "
                      "for user group in user group")
        raise JSONRPCError(
            'failed to edit permission for user group: '
            '`%s` in user group: `%s`' % (
                sourceusergroupid, target_user_group.users_group_name
            )
        )
예제 #25
0
def create_gist(
        request, apiuser, files, owner=Optional(OAttr('apiuser')),
        gist_type=Optional(Gist.GIST_PUBLIC), lifetime=Optional(-1),
        acl_level=Optional(Gist.ACL_LEVEL_PUBLIC),
        description=Optional('')):
    """
    Creates a new Gist.

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param files: files to be added to the gist. The data structure has
        to match the following example::

          {'filename': {'content':'...', 'lexer': null},
           'filename2': {'content':'...', 'lexer': null}}

    :type files: dict
    :param owner: Set the gist owner, defaults to api method caller
    :type owner: Optional(str or int)
    :param gist_type: type of gist ``public`` or ``private``
    :type gist_type: Optional(str)
    :param lifetime: time in minutes of gist lifetime
    :type lifetime: Optional(int)
    :param acl_level: acl level for this gist, can be
        ``acl_public`` or ``acl_private`` If the value is set to
        ``acl_private`` only logged in users are able to access this gist.
        If not set it defaults to ``acl_public``.
    :type acl_level: Optional(str)
    :param description: gist description
    :type description: Optional(str)

    Example  output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : {
        "msg": "created new gist",
        "gist": {}
      }
      error :  null

    Example error output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : null
      error :  {
        "failed to create gist"
      }

    """

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

        owner = get_user_or_error(owner)
        description = Optional.extract(description)
        gist_type = Optional.extract(gist_type)
        lifetime = Optional.extract(lifetime)
        acl_level = Optional.extract(acl_level)

        gist = GistModel().create(description=description,
                                  owner=owner,
                                  gist_mapping=files,
                                  gist_type=gist_type,
                                  lifetime=lifetime,
                                  gist_acl_level=acl_level)
        Session().commit()
        return {
            'msg': 'created new gist',
            'gist': gist.get_api_data()
        }
    except Exception:
        log.exception('Error occurred during creation of gist')
        raise JSONRPCError('failed to create gist')
def update_pull_request(request,
                        apiuser,
                        repoid,
                        pullrequestid,
                        title=Optional(''),
                        description=Optional(''),
                        reviewers=Optional(None),
                        update_commits=Optional(None),
                        close_pull_request=Optional(None)):
    """
    Updates a pull request.

    :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 title: Set the pull request title.
    :type title: str
    :param description: Update pull request description.
    :type description: Optional(str)
    :param reviewers: Update pull request reviewers list with new value.
    :type reviewers: Optional(list)
    :param update_commits: Trigger update of commits for this pull request
    :type: update_commits: Optional(bool)
    :param close_pull_request: Close this pull request with rejected state
    :type: close_pull_request: Optional(bool)

    Example output:

    .. code-block:: bash

      id : <id_given_in_input>
      result :
        {
            "msg": "Updated pull request `63`",
            "pull_request": <pull_request_object>,
            "updated_reviewers": {
              "added": [
                "username"
              ],
              "removed": []
            },
            "updated_commits": {
              "added": [
                "<sha1_hash>"
              ],
              "common": [
                "<sha1_hash>",
                "<sha1_hash>",
              ],
              "removed": []
            }
        }
      error :  null
    """

    repo = get_repo_or_error(repoid)
    pull_request = get_pull_request_or_error(pullrequestid)
    if not PullRequestModel().check_user_update(
            pull_request, apiuser, api=True):
        raise JSONRPCError(
            'pull request `%s` update failed, no permission to update.' %
            (pullrequestid, ))
    if pull_request.is_closed():
        raise JSONRPCError(
            'pull request `%s` update failed, pull request is closed' %
            (pullrequestid, ))

    reviewer_names = Optional.extract(reviewers) or []
    if not isinstance(reviewer_names, list):
        raise JSONRPCError('reviewers should be specified as a list')

    reviewer_users = [get_user_or_error(n) for n in reviewer_names]
    reviewer_ids = [u.user_id for u in reviewer_users]

    title = Optional.extract(title)
    description = Optional.extract(description)
    if title or description:
        PullRequestModel().edit(pull_request, title or pull_request.title,
                                description or pull_request.description)
        Session().commit()

    commit_changes = {"added": [], "common": [], "removed": []}
    if str2bool(Optional.extract(update_commits)):
        if PullRequestModel().has_valid_update_type(pull_request):
            _version, _commit_changes = PullRequestModel().update_commits(
                pull_request)
            commit_changes = _commit_changes or commit_changes
        Session().commit()

    reviewers_changes = {"added": [], "removed": []}
    if reviewer_ids:
        added_reviewers, removed_reviewers = \
            PullRequestModel().update_reviewers(pull_request, reviewer_ids)

        reviewers_changes['added'] = sorted(
            [get_user_or_error(n).username for n in added_reviewers])
        reviewers_changes['removed'] = sorted(
            [get_user_or_error(n).username for n in removed_reviewers])
        Session().commit()

    if str2bool(Optional.extract(close_pull_request)):
        PullRequestModel().close_pull_request_with_comment(
            pull_request, apiuser, repo)
        Session().commit()

    data = {
        'msg':
        'Updated pull request `{}`'.format(pull_request.pull_request_id),
        'pull_request': pull_request.get_api_data(),
        'updated_commits': commit_changes,
        'updated_reviewers': reviewers_changes
    }
    return data
def grant_user_group_permission_to_user_group(
        request, apiuser, usergroupid, sourceusergroupid, perm):
    """
    Give one user group permissions to another user group.

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser
    :param usergroupid: Set the user group on which to edit permissions.
    :type usergroupid: str or int
    :param sourceusergroupid: Set the source user group to which
        access/permissions will be granted.
    :type sourceusergroupid: str or int
    :param perm: (usergroup.(none|read|write|admin))
    :type perm: str

    Example output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : {
        "msg": "Granted perm: `<perm_name>` for user group: `<source_user_group_name>` in user group: `<user_group_name>`",
        "success": true
      }
      error :  null
    """

    user_group = get_user_group_or_error(sourceusergroupid)
    target_user_group = get_user_group_or_error(usergroupid)
    perm = get_perm_or_error(perm, prefix='usergroup.')

    if not has_superadmin_permission(apiuser):
        # check if we have admin permission for this user group !
        _perms = ('usergroup.admin',)
        if not HasUserGroupPermissionAnyApi(*_perms)(
                user=apiuser,
                user_group_name=target_user_group.users_group_name):
            raise JSONRPCError(
                'to user group `%s` does not exist' % (usergroupid,))

        # check if we have at least read permission for source user group !
        _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',)
        if not HasUserGroupPermissionAnyApi(*_perms)(
                user=apiuser, user_group_name=user_group.users_group_name):
            raise JSONRPCError(
                'user group `%s` does not exist' % (sourceusergroupid,))

    try:
        UserGroupModel().grant_user_group_permission(
            target_user_group=target_user_group,
            user_group=user_group, perm=perm)
        Session().commit()

        return {
            'msg': 'Granted perm: `%s` for user group: `%s` '
                   'in user group: `%s`' % (
                       perm.permission_name, user_group.users_group_name,
                       target_user_group.users_group_name
                   ),
            'success': True
        }
    except Exception:
        log.exception("Error occurred during editing permissions "
                      "for user group in user group")
        raise JSONRPCError(
            'failed to edit permission for user group: `%s` in '
            'user group: `%s`' % (
                sourceusergroupid, target_user_group.users_group_name
            )
        )
예제 #28
0
def create_user(request,
                apiuser,
                username,
                email,
                password=Optional(''),
                firstname=Optional(''),
                lastname=Optional(''),
                active=Optional(True),
                admin=Optional(False),
                extern_name=Optional('rhodecode'),
                extern_type=Optional('rhodecode'),
                force_password_change=Optional(False)):
    """
    Creates a new user and returns the new user object.

    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 username: Set the new username.
    :type username: str or int
    :param email: Set the user email address.
    :type email: str
    :param password: Set the new user password.
    :type password: Optional(str)
    :param firstname: Set the new user firstname.
    :type firstname: Optional(str)
    :param lastname: Set the new user surname.
    :type lastname: Optional(str)
    :param active: Set the user as active.
    :type active: Optional(``True`` | ``False``)
    :param admin: Give the new user admin rights.
    :type admin: Optional(``True`` | ``False``)
    :param extern_name: Set the authentication plugin name.
        Using LDAP this is filled with LDAP UID.
    :type extern_name: Optional(str)
    :param extern_type: Set the new user authentication plugin.
    :type extern_type: Optional(str)
    :param force_password_change: Force the new user to change password
        on next login.
    :type force_password_change: Optional(``True`` | ``False``)

    Example output:

    .. code-block:: bash

        id : <id_given_in_input>
        result: {
                  "msg" : "created new user `<username>`",
                  "user": <user_obj>
                }
        error:  null

    Example error output:

    .. code-block:: bash

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

    """
    if not has_superadmin_permission(apiuser):
        raise JSONRPCForbidden()

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

    if UserModel().get_by_email(email, case_insensitive=True):
        raise JSONRPCError("email `%s` already exist" % (email, ))

    # generate random password if we actually given the
    # extern_name and it's not rhodecode
    if (not isinstance(extern_name, Optional)
            and Optional.extract(extern_name) != 'rhodecode'):
        # generate temporary password if user is external
        password = PasswordGenerator().gen_password(length=16)

    try:
        user = UserModel().create_or_update(
            username=Optional.extract(username),
            password=Optional.extract(password),
            email=Optional.extract(email),
            firstname=Optional.extract(firstname),
            lastname=Optional.extract(lastname),
            active=Optional.extract(active),
            admin=Optional.extract(admin),
            extern_type=Optional.extract(extern_type),
            extern_name=Optional.extract(extern_name),
            force_password_change=Optional.extract(force_password_change),
        )
        Session().commit()
        return {
            'msg': 'created new user `%s`' % username,
            'user': user.get_api_data(include_secrets=True)
        }
    except Exception:
        log.exception('Error occurred during creation of user')
        raise JSONRPCError('failed to create user `%s`' % (username, ))
예제 #29
0
def test_error(request, apiuser):
    raise JSONRPCError('error happened')
예제 #30
0
def update_user(
        request,
        apiuser,
        userid,
        username=Optional(None),
        email=Optional(None),
        password=Optional(None),
        firstname=Optional(None),
        lastname=Optional(None),
        active=Optional(None),
        admin=Optional(None),
        extern_type=Optional(None),
        extern_name=Optional(None),
):
    """
    Updates the details for the specified user, if that user exists.

    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 |authtoken|.
    :type apiuser: AuthUser
    :param userid: Set the ``userid`` to update.
    :type userid: str or int
    :param username: Set the new username.
    :type username: str or int
    :param email: Set the new email.
    :type email: str
    :param password: Set the new password.
    :type password: Optional(str)
    :param firstname: Set the new first name.
    :type firstname: Optional(str)
    :param lastname: Set the new surname.
    :type lastname: Optional(str)
    :param active: Set the new user as active.
    :type active: Optional(``True`` | ``False``)
    :param admin: Give the user admin rights.
    :type admin: Optional(``True`` | ``False``)
    :param extern_name: Set the authentication plugin user name.
        Using LDAP this is filled with LDAP UID.
    :type extern_name: Optional(str)
    :param extern_type: Set the authentication plugin type.
    :type extern_type: Optional(str)


    Example output:

    .. code-block:: bash

        id : <id_given_in_input>
        result: {
                  "msg" : "updated user ID:<userid> <username>",
                  "user": <user_object>,
                }
        error:  null

    Example error output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : null
      error :  {
        "failed to update user `<username>`"
      }

    """
    if not has_superadmin_permission(apiuser):
        raise JSONRPCForbidden()

    user = get_user_or_error(userid)

    # only non optional arguments will be stored in updates
    updates = {}

    try:

        store_update(updates, username, 'username')
        store_update(updates, password, 'password')
        store_update(updates, email, 'email')
        store_update(updates, firstname, 'name')
        store_update(updates, lastname, 'lastname')
        store_update(updates, active, 'active')
        store_update(updates, admin, 'admin')
        store_update(updates, extern_name, 'extern_name')
        store_update(updates, extern_type, 'extern_type')

        user = UserModel().update_user(user, **updates)
        Session().commit()
        return {
            'msg': 'updated user ID:%s %s' % (user.user_id, user.username),
            'user': user.get_api_data(include_secrets=True)
        }
    except DefaultUserException:
        log.exception("Default user edit exception")
        raise JSONRPCError('editing default user is forbidden')
    except Exception:
        log.exception("Error occurred during update of user")
        raise JSONRPCError('failed to update user `%s`' % (userid, ))