Пример #1
0
def get_users(request, apiuser):
    """
    Lists all users in the |RCE| user database.

    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

    Example output:

    .. code-block:: bash

        id : <id_given_in_input>
            result: [<user_object>, ...]
        error:  null
    """

    if not has_superadmin_permission(apiuser):
        raise JSONRPCForbidden()

    result = []
    users_list = User.query().order_by(User.username) \
        .filter(User.username != User.DEFAULT_USER) \
        .all()
    for user in users_list:
        result.append(user.get_api_data(include_secrets=True))
    return result
Пример #2
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))
Пример #3
0
def get_server_info(request, apiuser):
    """
    Returns the |RCE| server information.

    This includes the running version of |RCE| and all installed
    packages. This command takes the following options:

    :param apiuser: This is filled automatically from the |authtoken|.
    :type apiuser: AuthUser

    Example output:

    .. code-block:: bash

      id : <id_given_in_input>
      result : {
        'modules': [<module name>,...]
        'py_version': <python version>,
        'platform': <platform type>,
        'rhodecode_version': <rhodecode version>
      }
      error :  null
    """

    if not has_superadmin_permission(apiuser):
        raise JSONRPCForbidden()

    return ScmModel().get_server_info(request.environ)
def get_user_groups(request, apiuser):
    """
    Lists all the existing user groups within RhodeCode.

    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

    Example error output:

    .. code-block:: bash

        id : <id_given_in_input>
        result : [<user_group_obj>,...]
        error : null
    """

    include_secrets = has_superadmin_permission(apiuser)

    result = []
    _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',)
    extras = {'user': apiuser}
    for user_group in UserGroupList(UserGroupModel().get_all(),
                                    perm_set=_perms, extra_kwargs=extras):
        result.append(
            user_group.get_api_data(include_secrets=include_secrets))
    return result
Пример #5
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
Пример #6
0
    def test_has_superadmin_permission_checks_for_admin(self):
        admin_mock = Mock()
        with self.admin_perm_patch as amock:
            amock.return_value = admin_mock
            assert utils.has_superadmin_permission('fake_user')
            amock.assert_called_once_with('hg.admin')

        admin_mock.assert_called_once_with(user='******')
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 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 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,
            )
        )
Пример #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'
        )
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))
Пример #12
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,))
Пример #13
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))
Пример #14
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
Пример #15
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,))
Пример #16
0
def get_ip(request, apiuser, userid=Optional(OAttr('apiuser'))):
    """
    Displays the IP Address as seen from the |RCE| server.

    * This command displays the IP Address, as well as all the defined IP
      addresses for the specified user. If the ``userid`` is not set, the
      data returned is for the user calling the method.

    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: Sets the userid for which associated IP Address data
        is returned.
    :type userid: Optional(str or int)

    Example output:

    .. code-block:: bash

        id : <id_given_in_input>
        result : {
                     "server_ip_addr": "<ip_from_clien>",
                     "user_ips": [
                                    {
                                       "ip_addr": "<ip_with_mask>",
                                       "ip_range": ["<start_ip>", "<end_ip>"],
                                    },
                                    ...
                                 ]
        }

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

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

    user = get_user_or_error(userid)
    ips = UserIpMap.query().filter(UserIpMap.user == user).all()
    return {
        'server_ip_addr': request.rpc_ip_addr,
        'user_ips': ips
    }
Пример #17
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 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 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
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,))
Пример #23
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
            )
        )
Пример #24
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
Пример #25
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 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
            )
        )
Пример #27
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, ))
Пример #28
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 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
            )
        )
Пример #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, ))