Changeset - 2dd317e9cc4b
[Not reviewed]
stable
0 2 0
Mads Kiilerich (mads) - 3 years ago 2022-10-14 13:17:57
mads@kiilerich.com
Grafted from: a63d2890b5be
api docs: make examples use comma more like json does
2 files changed with 61 insertions and 61 deletions:
0 comments (0 inline, 0 general)
docs/api/api.rst
Show inline comments
 
@@ -82,1168 +82,1168 @@ providing the ``repoid`` as a parameter:
 
        "clone_uri": null,
 
        "created_on": "2015-08-31T14:55:19.042",
 
    ...
 

	
 
To avoid specifying ``apihost`` and ``apikey`` every time, run::
 

	
 
    kallithea-api --save-config --apihost=<Kallithea URL> --apikey=<API key>
 

	
 
This will create a ``~/.config/kallithea`` with the specified URL and API key
 
so you don't have to specify them every time.
 

	
 

	
 
API methods
 
-----------
 

	
 

	
 
pull
 
^^^^
 

	
 
Pull the given repo from remote location. Can be used to automatically keep
 
remote repos up to date.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "pull"
 
    args :    {
 
                "repoid" : "<reponame or repo_id>"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : "Pulled from `<reponame>`"
 
    error : null
 

	
 
rescan_repos
 
^^^^^^^^^^^^
 

	
 
Rescan repositories. If ``remove_obsolete`` is set,
 
Kallithea will delete repos that are in the database but not in the filesystem.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "rescan_repos"
 
    args :    {
 
                "remove_obsolete" : "<boolean = Optional(False)>"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : "{'added': [<list of names of added repos>],
 
               'removed': [<list of names of removed repos>]}"
 
    error : null
 

	
 
invalidate_cache
 
^^^^^^^^^^^^^^^^
 

	
 
Invalidate the cache for a repository.
 
This command can only be executed using the api_key of a user with admin rights,
 
or that of a regular user with admin or write access to the repository.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "invalidate_cache"
 
    args :    {
 
                "repoid" : "<reponame or repo_id>"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : "Caches of repository `<reponame>`"
 
    error : null
 

	
 
get_ip
 
^^^^^^
 

	
 
Return IP address as seen from Kallithea server, together with all
 
defined IP addresses for given user.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "get_ip"
 
    args :    {
 
                "userid" : "<user_id or username>",
 
                "userid" : "<user_id or username>"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
                 "ip_addr_server" : <ip_from_client>",
 
                 "user_ips" : [
 
                                {
 
                                   "ip_addr" : "<ip_with_mask>",
 
                                   "ip_range" : ["<start_ip>", "<end_ip>"],
 
                                   "ip_range" : ["<start_ip>", "<end_ip>"]
 
                                },
 
                                ...
 
                              ]
 
             }
 
    error : null
 

	
 
get_user
 
^^^^^^^^
 

	
 
Get a user by username or userid. The result is empty if user can't be found.
 
If userid param is skipped, it is set to id of user who is calling this method.
 
Any userid can be specified when the command is executed using the api_key of a user with admin rights.
 
Regular users can only specify their own userid.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "get_user"
 
    args :    {
 
                "userid" : "<username or user_id Optional(=apiuser)>"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : None if user does not exist or
 
             {
 
                "user_id" :     "<user_id>",
 
                "api_key" :     "<api_key>",
 
                "username" :    "<username>",
 
                "firstname" :   "<firstname>",
 
                "lastname" :    "<lastname>",
 
                "email" :       "<email>",
 
                "emails" :      "<list_of_all_additional_emails>",
 
                "ip_addresses": "<list_of_ip_addresses_for_user>",
 
                "active" :      "<bool>",
 
                "admin" :       "<bool>",
 
                "ldap_dn" :     "<ldap_dn>",
 
                "last_login" :  "<last_login>",
 
                "permissions": {
 
                    "global": ["hg.create.repository",
 
                               "repository.read",
 
                               "hg.register.manual_activate"],
 
                    "repositories" : {"repo1" : "repository.none"},
 
                    "repositories_groups" : {"Group1" : "group.read"}
 
                 },
 
                 }
 
             }
 
    error : null
 

	
 
get_users
 
^^^^^^^^^
 

	
 
List all existing users.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "get_users"
 
    args :    { }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : [
 
              {
 
                "user_id" :     "<user_id>",
 
                "api_key" :     "<api_key>",
 
                "username" :    "<username>",
 
                "firstname" :   "<firstname>",
 
                "lastname" :    "<lastname>",
 
                "email" :       "<email>",
 
                "emails" :      "<list_of_all_additional_emails>",
 
                "ip_addresses": "<list_of_ip_addresses_for_user>",
 
                "active" :      "<bool>",
 
                "admin" :       "<bool>",
 
                "ldap_dn" :     "<ldap_dn>",
 
                "last_login" :  "<last_login>",
 
                "last_login" :  "<last_login>"
 
              },
 
              …
 
             ]
 
    error : null
 

	
 
.. _create-user:
 

	
 
create_user
 
^^^^^^^^^^^
 

	
 
Create new user.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "create_user"
 
    args :    {
 
                "username" :  "<username>",
 
                "email" :     "<useremail>",
 
                "password" :  "<password = Optional(None)>",
 
                "firstname" : "<firstname> = Optional(None)",
 
                "lastname" :  "<lastname> = Optional(None)",
 
                "active" :    "<bool> = Optional(True)",
 
                "admin" :     "<bool> = Optional(False)",
 
                "ldap_dn" :   "<ldap_dn> = Optional(None)"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
              "msg" : "created new user `<username>`",
 
              "user" : {
 
                "user_id" :  "<user_id>",
 
                "username" : "<username>",
 
                "firstname": "<firstname>",
 
                "lastname" : "<lastname>",
 
                "email" :    "<email>",
 
                "emails" :   "<list_of_all_additional_emails>",
 
                "active" :   "<bool>",
 
                "admin" :    "<bool>",
 
                "ldap_dn" :  "<ldap_dn>",
 
                "last_login": "<last_login>",
 
              },
 
                "last_login": "<last_login>"
 
              }
 
             }
 
    error : null
 

	
 
Example::
 

	
 
    kallithea-api create_user username:bent email:bent@example.com firstname:Bent lastname:Bentsen extern_type:ldap extern_name:uid=bent,dc=example,dc=com
 

	
 
update_user
 
^^^^^^^^^^^
 

	
 
Update the given user if such user exists.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "update_user"
 
    args :    {
 
                "userid" : "<user_id or username>",
 
                "username" :  "<username> = Optional(None)",
 
                "email" :     "<useremail> = Optional(None)",
 
                "password" :  "<password> = Optional(None)",
 
                "firstname" : "<firstname> = Optional(None)",
 
                "lastname" :  "<lastname> = Optional(None)",
 
                "active" :    "<bool> = Optional(None)",
 
                "admin" :     "<bool> = Optional(None)",
 
                "ldap_dn" :   "<ldap_dn> = Optional(None)"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
              "msg" : "updated user ID:<userid> <username>",
 
              "user" : {
 
                "user_id" :  "<user_id>",
 
                "api_key" :  "<api_key>",
 
                "username" : "<username>",
 
                "firstname": "<firstname>",
 
                "lastname" : "<lastname>",
 
                "email" :    "<email>",
 
                "emails" :   "<list_of_all_additional_emails>",
 
                "active" :   "<bool>",
 
                "admin" :    "<bool>",
 
                "ldap_dn" :  "<ldap_dn>",
 
                "last_login": "<last_login>",
 
              },
 
                "last_login": "<last_login>"
 
              }
 
             }
 
    error : null
 

	
 
delete_user
 
^^^^^^^^^^^
 

	
 
Delete the given user if such a user exists.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "delete_user"
 
    args :    {
 
                "userid" : "<user_id or username>",
 
                "userid" : "<user_id or username>"
 
              }
 

	
 
OUTPUT::
 

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

	
 
get_user_group
 
^^^^^^^^^^^^^^
 

	
 
Get an existing user group.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "get_user_group"
 
    args :    {
 
                "usergroupid" : "<user group id or name>"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : None if group not exist
 
             {
 
               "users_group_id" : "<id>",
 
               "group_name" :     "<groupname>",
 
               "active" :         "<bool>",
 
               "members" :  [
 
                              {
 
                                "user_id" :  "<user_id>",
 
                                "api_key" :  "<api_key>",
 
                                "username" : "<username>",
 
                                "firstname": "<firstname>",
 
                                "lastname" : "<lastname>",
 
                                "email" :    "<email>",
 
                                "emails" :   "<list_of_all_additional_emails>",
 
                                "active" :   "<bool>",
 
                                "admin" :    "<bool>",
 
                                "ldap_dn" :  "<ldap_dn>",
 
                                "last_login": "<last_login>",
 
                                "last_login": "<last_login>"
 
                              },
 
                              …
 
                            ]
 
             }
 
    error : null
 

	
 
get_user_groups
 
^^^^^^^^^^^^^^^
 

	
 
List all existing user groups.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "get_user_groups"
 
    args :    { }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : [
 
               {
 
               "users_group_id" : "<id>",
 
               "group_name" :     "<groupname>",
 
               "active" :         "<bool>",
 
               "active" :         "<bool>"
 
               },
 
               …
 
              ]
 
    error : null
 

	
 
create_user_group
 
^^^^^^^^^^^^^^^^^
 

	
 
Create a new user group.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "create_user_group"
 
    args :    {
 
                "group_name": "<groupname>",
 
                "owner" :     "<owner_name_or_id = Optional(=apiuser)>",
 
                "active" :    "<bool> = Optional(True)"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
              "msg" : "created new user group `<groupname>`",
 
              "users_group" : {
 
                     "users_group_id" : "<id>",
 
                     "group_name" :     "<groupname>",
 
                     "active" :         "<bool>",
 
               },
 
                     "active" :         "<bool>"
 
               }
 
             }
 
    error : null
 

	
 
add_user_to_user_group
 
^^^^^^^^^^^^^^^^^^^^^^
 

	
 
Adds a user to a user group. If the user already is in that group, success will be
 
``false``.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "add_user_user_group"
 
    args :    {
 
                "usersgroupid" : "<user group id or name>",
 
                "userid" : "<user_id or username>",
 
                "userid" : "<user_id or username>"
 
              }
 

	
 
OUTPUT::
 

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

	
 
remove_user_from_user_group
 
^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

	
 
Remove a user from a user group. If the user isn't in the given group, success will
 
be ``false``.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "remove_user_from_user_group"
 
    args :    {
 
                "usersgroupid" : "<user group id or name>",
 
                "userid" : "<user_id or username>",
 
                "userid" : "<user_id or username>"
 
              }
 

	
 
OUTPUT::
 

	
 
    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
 

	
 
get_repo
 
^^^^^^^^
 

	
 
Get an existing repository by its name or repository_id. Members will contain
 
either users_group or users associated to that repository.
 
This command can only be executed using the api_key of a user with admin rights,
 
or that of a regular user with at least read access to the repository.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "get_repo"
 
    args :    {
 
                "repoid" : "<reponame or repo_id>",
 
                "with_revision_names" : "<bool> = Optional(False)",
 
                "with_pullrequests" : "<bool> = Optional(False)",
 
                "with_pullrequests" : "<bool> = Optional(False)"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : None if repository does not exist or
 
             {
 
                "repo_id" :          "<repo_id>",
 
                "repo_name" :        "<reponame>"
 
                "repo_name" :        "<reponame>",
 
                "repo_type" :        "<repo_type>",
 
                "clone_uri" :        "<clone_uri>",
 
                "enable_downloads" : "<bool>",
 
                "enable_statistics": "<bool>",
 
                "private" :          "<bool>",
 
                "created_on" :       "<date_time_created>",
 
                "description" :      "<description>",
 
                "landing_rev" :      "<landing_rev>",
 
                "last_changeset" :   {
 
                                         "author" :  "<full_author>",
 
                                         "date" :    "<date_time_of_commit>",
 
                                         "message" : "<commit_message>",
 
                                         "raw_id" :  "<raw_id>",
 
                                         "revision": "<numeric_revision>",
 
                                         "short_id": "<short_id>"
 
                                     },
 
                "owner" :            "<repo_owner>",
 
                "fork_of" :          "<name_of_fork_parent>",
 
                "members" :   [
 
                                  {
 
                                    "type" :       "user",
 
                                    "user_id" :    "<user_id>",
 
                                    "api_key" :    "<api_key>",
 
                                    "username" :   "<username>",
 
                                    "firstname" :  "<firstname>",
 
                                    "lastname" :   "<lastname>",
 
                                    "email" :      "<email>",
 
                                    "emails" :     "<list_of_all_additional_emails>",
 
                                    "active" :     "<bool>",
 
                                    "admin" :      "<bool>",
 
                                    "ldap_dn" :    "<ldap_dn>",
 
                                    "last_login" : "<last_login>",
 
                                    "permission" : "repository.(read|write|admin)"
 
                                  },
 
                                  …
 
                                  {
 
                                    "type" :     "users_group",
 
                                    "id" :       "<usersgroupid>",
 
                                    "name" :     "<usersgroupname>",
 
                                    "active" :   "<bool>",
 
                                    "permission" : "repository.(read|write|admin)"
 
                                  },
 
                                  …
 
                              ],
 
                "followers" : [
 
                                  {
 
                                    "user_id" :     "<user_id>",
 
                                    "username" :    "<username>",
 
                                    "api_key" :     "<api_key>",
 
                                    "firstname" :   "<firstname>",
 
                                    "lastname" :    "<lastname>",
 
                                    "email" :       "<email>",
 
                                    "emails" :      "<list_of_all_additional_emails>",
 
                                    "ip_addresses": "<list_of_ip_addresses_for_user>",
 
                                    "active" :      "<bool>",
 
                                    "admin" :       "<bool>",
 
                                    "ldap_dn" :     "<ldap_dn>",
 
                                    "last_login" :  "<last_login>",
 
                                    "last_login" :  "<last_login>"
 
                                  },
 
                                  …
 
                              ],
 
                <if with_revision_names == True>
 
                "tags" : {
 
                            "<tagname>" : "<raw_id>",
 
                            ...
 
                        },
 
                "branches" : {
 
                            "<branchname>" : "<raw_id>",
 
                            ...
 
                        },
 
                "bookmarks" : {
 
                            "<bookmarkname>" : "<raw_id>",
 
                            ...
 
                        },
 
                <if with_pullrequests == True>
 
                "pull_requests" : [
 
                  {
 
                    "status" : "<pull_request_status>",
 
                    "pull_request_id" : <pull_request_id>,
 
                    "description" : "<pull_request_description>",
 
                    "title" : "<pull_request_title>",
 
                    "url" : "<pull_request_url>",
 
                    "reviewers" : [
 
                      {
 
                        "username" : "<user_id>",
 
                        "username" : "<user_id>"
 
                      },
 
                      ...
 
                    ],
 
                    "org_repo_url" : "<repo_url>",
 
                    "org_ref_parts" : [
 
                      "<ref_type>",
 
                      "<ref_name>",
 
                      "<raw_id>"
 
                    ],
 
                    "other_ref_parts" : [
 
                      "<ref_type>",
 
                      "<ref_name>",
 
                      "<raw_id>"
 
                    ],
 
                    "comments" : [
 
                      {
 
                        "username" : "<user_id>",
 
                        "text" : "<comment text>",
 
                        "comment_id" : "<comment_id>",
 
                        "comment_id" : "<comment_id>"
 
                      },
 
                      ...
 
                    ],
 
                    "owner" : "<username>",
 
                    "statuses" : [
 
                      {
 
                        "status" : "<status_of_review>",        # "under_review", "approved" or "rejected"
 
                        "reviewer" : "<user_id>",
 
                        "modified_at" : "<date_time_of_review>" # iso 8601 date, server's timezone
 
                      },
 
                      ...
 
                    ],
 
                    "revisions" : [
 
                      "<raw_id>",
 
                      ...
 
                    ]
 
                  },
 
                  ...
 
                ]
 
             }
 
    error : null
 

	
 
get_repos
 
^^^^^^^^^
 

	
 
List all existing repositories.
 
This command can only be executed using the api_key of a user with admin rights,
 
or that of a regular user with at least read access to the repository.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "get_repos"
 
    args :    { }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : [
 
              {
 
                "repo_id" :          "<repo_id>",
 
                "repo_name" :        "<reponame>"
 
                "repo_name" :        "<reponame>",
 
                "repo_type" :        "<repo_type>",
 
                "clone_uri" :        "<clone_uri>",
 
                "private" :          "<bool>",
 
                "created_on" :       "<datetimecreated>",
 
                "description" :      "<description>",
 
                "landing_rev" :      "<landing_rev>",
 
                "owner" :            "<repo_owner>",
 
                "fork_of" :          "<name_of_fork_parent>",
 
                "enable_downloads" : "<bool>",
 
                "enable_statistics": "<bool>",
 
                "enable_statistics": "<bool>"
 
              },
 
              …
 
             ]
 
    error : null
 

	
 
get_repo_nodes
 
^^^^^^^^^^^^^^
 

	
 
Return a list of files and directories for a given path at the given revision.
 
It is possible to specify ret_type to show only ``files`` or ``dirs``.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "get_repo_nodes"
 
    args :    {
 
                "repoid" : "<reponame or repo_id>"
 
                "repoid" : "<reponame or repo_id>",
 
                "revision" :  "<revision>",
 
                "root_path" : "<root_path>",
 
                "ret_type" :  "<ret_type> = Optional('all')"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : [
 
              {
 
                "name" :        "<name>"
 
                "type" :        "<type>",
 
                "name" :        "<name>",
 
                "type" :        "<type>"
 
              },
 
              …
 
             ]
 
    error : null
 

	
 
create_repo
 
^^^^^^^^^^^
 

	
 
Create a repository. If the repository name contains "/", the repository will be
 
created in the repository group indicated by that path. Any such repository
 
groups need to exist before calling this method, or the call will fail.
 
For example "foo/bar/baz" will create a repository "baz" inside the repository
 
group "bar" which itself is in a repository group "foo", but both "foo" and
 
"bar" already need to exist before calling this method.
 
This command can only be executed using the api_key of a user with admin rights,
 
or that of a regular user with create repository permission.
 
Regular users cannot specify owner parameter.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "create_repo"
 
    args :    {
 
                "repo_name" :        "<reponame>",
 
                "owner" :            "<owner_name_or_id = Optional(=apiuser)>",
 
                "repo_type" :        "<repo_type> = Optional('hg')",
 
                "description" :      "<description> = Optional('')",
 
                "private" :          "<bool> = Optional(False)",
 
                "clone_uri" :        "<clone_uri> = Optional(None)",
 
                "landing_rev" :      "<landing_rev> = Optional('tip')",
 
                "enable_downloads" : "<bool> = Optional(False)",
 
                "enable_statistics": "<bool> = Optional(False)",
 
                "enable_statistics": "<bool> = Optional(False)"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
              "msg" : "Created new repository `<reponame>`",
 
              "repo" : {
 
                "repo_id" :          "<repo_id>",
 
                "repo_name" :        "<reponame>"
 
                "repo_name" :        "<reponame>",
 
                "repo_type" :        "<repo_type>",
 
                "clone_uri" :        "<clone_uri>",
 
                "private" :          "<bool>",
 
                "created_on" :       "<datetimecreated>",
 
                "description" :      "<description>",
 
                "landing_rev" :      "<landing_rev>",
 
                "owner" :            "<username or user_id>",
 
                "fork_of" :          "<name_of_fork_parent>",
 
                "enable_downloads" : "<bool>",
 
                "enable_statistics": "<bool>",
 
              },
 
                "enable_statistics": "<bool>"
 
              }
 
             }
 
    error : null
 

	
 
update_repo
 
^^^^^^^^^^^
 

	
 
Update a repository.
 
This command can only be executed using the api_key of a user with admin rights,
 
or that of a regular user with create repository permission.
 
Regular users cannot specify owner parameter.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "update_repo"
 
    args :    {
 
                "repoid" :           "<reponame or repo_id>"
 
                "repoid" :           "<reponame or repo_id>",
 
                "name" :             "<reponame> = Optional('')",
 
                "group" :            "<group_id> = Optional(None)",
 
                "owner" :            "<owner_name_or_id = Optional(=apiuser)>",
 
                "description" :      "<description> = Optional('')",
 
                "private" :          "<bool> = Optional(False)",
 
                "clone_uri" :        "<clone_uri> = Optional(None)",
 
                "landing_rev" :      "<landing_rev> = Optional('tip')",
 
                "enable_downloads" : "<bool> = Optional(False)",
 
                "enable_statistics": "<bool> = Optional(False)",
 
                "enable_statistics": "<bool> = Optional(False)"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
              "msg" : "updated repo ID:repo_id `<reponame>`",
 
              "repository" : {
 
                "repo_id" :          "<repo_id>",
 
                "repo_name" :        "<reponame>"
 
                "repo_name" :        "<reponame>",
 
                "repo_type" :        "<repo_type>",
 
                "clone_uri" :        "<clone_uri>",
 
                "private" :          "<bool>",
 
                "created_on" :       "<datetimecreated>",
 
                "description" :      "<description>",
 
                "landing_rev" :      "<landing_rev>",
 
                "owner" :            "<username or user_id>",
 
                "fork_of" :          "<name_of_fork_parent>",
 
                "enable_downloads" : "<bool>",
 
                "enable_statistics": "<bool>",
 
                "last_changeset" :   {
 
                                       "author" :  "<full_author>",
 
                                       "date" :    "<date_time_of_commit>",
 
                                       "message" : "<commit_message>",
 
                                       "raw_id" :  "<raw_id>",
 
                                       "revision": "<numeric_revision>",
 
                                       "short_id": "<short_id>"
 
                                     }
 
              },
 
              }
 
             }
 
    error : null
 

	
 
fork_repo
 
^^^^^^^^^
 

	
 
Create a fork of the given repo. If using Celery, this will
 
return success message immediately and a fork will be created
 
asynchronously.
 
This command can only be executed using the api_key of a user with admin
 
rights, or with the global fork permission, by a regular user with create
 
repository permission and at least read access to the repository.
 
Regular users cannot specify owner parameter.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "fork_repo"
 
    args :    {
 
                "repoid" :          "<reponame or repo_id>",
 
                "fork_name" :       "<forkname>",
 
                "owner" :           "<username or user_id = Optional(=apiuser)>",
 
                "description" :     "<description>",
 
                "copy_permissions": "<bool>",
 
                "private" :         "<bool>",
 
                "landing_rev" :     "<landing_rev>"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
              "msg" : "Created fork of `<reponame>` as `<forkname>`",
 
              "success" : true
 
             }
 
    error : null
 

	
 
delete_repo
 
^^^^^^^^^^^
 

	
 
Delete a repository.
 
This command can only be executed using the api_key of a user with admin rights,
 
or that of a regular user with admin access to the repository.
 
When ``forks`` param is set it is possible to detach or delete forks of the deleted repository.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "delete_repo"
 
    args :    {
 
                "repoid" : "<reponame or repo_id>",
 
                "forks" :  "`delete` or `detach` = Optional(None)"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
              "msg" : "Deleted repository `<reponame>`",
 
              "success" : true
 
             }
 
    error : null
 

	
 
grant_user_permission
 
^^^^^^^^^^^^^^^^^^^^^
 

	
 
Grant permission for a user on the given repository, or update the existing one if found.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "grant_user_permission"
 
    args :    {
 
                "repoid" : "<reponame or repo_id>"
 
                "userid" : "<username or user_id>"
 
                "perm" :       "(repository.(none|read|write|admin))",
 
                "repoid" : "<reponame or repo_id>",
 
                "userid" : "<username or user_id>",
 
                "perm" :       "(repository.(none|read|write|admin))"
 
              }
 

	
 
OUTPUT::
 

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

	
 
revoke_user_permission
 
^^^^^^^^^^^^^^^^^^^^^^
 

	
 
Revoke permission for a user on the given repository.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "revoke_user_permission"
 
    args :    {
 
                "repoid" : "<reponame or repo_id>"
 
                "repoid" : "<reponame or repo_id>",
 
                "userid" : "<username or user_id>"
 
              }
 

	
 
OUTPUT::
 

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

	
 
grant_user_group_permission
 
^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

	
 
Grant permission for a user group on the given repository, or update the
 
existing one if found.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "grant_user_group_permission"
 
    args :    {
 
                "repoid" : "<reponame or repo_id>"
 
                "usersgroupid" : "<user group id or name>"
 
                "perm" : "(repository.(none|read|write|admin))",
 
                "repoid" : "<reponame or repo_id>",
 
                "usersgroupid" : "<user group id or name>",
 
                "perm" : "(repository.(none|read|write|admin))"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
              "msg" : "Granted perm: `<perm>` for group: `<usersgroupname>` in repo: `<reponame>`",
 
              "success" : true
 
             }
 
    error : null
 

	
 
revoke_user_group_permission
 
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 

	
 
Revoke permission for a user group on the given repository.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "revoke_user_group_permission"
 
    args :    {
 
                "repoid" : "<reponame or repo_id>"
 
                "repoid" : "<reponame or repo_id>",
 
                "usersgroupid" : "<user group id or name>"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
              "msg" : "Revoked perm for group: `<usersgroupname>` in repo: `<reponame>`",
 
              "success" : true
 
             }
 
    error : null
 

	
 
get_changesets
 
^^^^^^^^^^^^^^
 

	
 
Get changesets of a given repository. This command can only be executed using the api_key
 
of a user with read permissions to the repository.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "get_changesets"
 
    args :    {
 
                "repoid" : "<reponame or repo_id>",
 
                "start" : "<revision number> = Optional(None)",
 
                "end" : "<revision number> = Optional(None)",
 
                "start_date" : "<date> = Optional(None)",    # in "%Y-%m-%dT%H:%M:%S" format
 
                "end_date" : "<date> = Optional(None)",      # in "%Y-%m-%dT%H:%M:%S" format
 
                "branch_name" : "<branch name filter> = Optional(None)",
 
                "reverse" : "<bool> = Optional(False)",
 
                "with_file_list" : "<bool> = Optional(False)"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : [
 
    {
 
      "raw_id" : "<raw_id>",
 
      "short_id" : "<short_id>",
 
      "author" : "<full_author>",
 
      "date" : "<date_time_of_commit>",
 
      "message" : "<commit_message>",
 
      "revision" : "<numeric_revision>",
 
      <if with_file_list == True>
 
      "added" : [<list of added files>],
 
      "changed" : [<list of changed files>],
 
      "removed" : [<list of removed files>]
 
    },
 
    ...
 
    ]
 
    error : null
 

	
 
get_changeset
 
^^^^^^^^^^^^^
 

	
 
Get information and review status for a given changeset. This command can only
 
be executed using the api_key of a user with read permissions to the
 
repository.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "get_changeset"
 
    args :    {
 
                "repoid" : "<reponame or repo_id>",
 
                "raw_id" : "<raw_id>",
 
                "with_reviews" : "<bool> = Optional(False)"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
              "author" :  "<full_author>",
 
              "date" :    "<date_time_of_commit>",
 
              "message" : "<commit_message>",
 
              "raw_id" :  "<raw_id>",
 
              "revision": "<numeric_revision>",
 
              "short_id": "<short_id>",
 
              "reviews" : [{
 
                    "reviewer" :  "<username>",
 
                    "modified_at" : "<date_time_of_review>",  # iso 8601 date, server's timezone
 
                    "status" :  "<status_of_review>",        # "under_review", "approved" or "rejected"
 
                 },
 
                 ...
 
              ]
 
             }
 
    error : null
 

	
 
Example output::
 

	
 
    {
 
      "id" : 1,
 
      "error" : null,
 
      "result" : {
 
        "author" : {
 
          "email" : "user@example.com",
 
          "name" : "Kallithea Admin"
 
        },
 
        "changed" : [],
 
        "short_id" : "e1022d3d28df",
 
        "date" : "2017-03-28T09:09:03",
 
        "added" : [
 
          "README.rst"
 
        ],
 
        "removed" : [],
 
        "revision" : 0,
 
        "raw_id" : "e1022d3d28dfba02f626cde65dbe08f4ceb0e4e7",
 
        "message" : "Added file via Kallithea",
 
        "id" : "e1022d3d28dfba02f626cde65dbe08f4ceb0e4e7",
 
        "reviews" : [
 
          {
 
            "status" : "under_review",
 
            "modified_at" : "2017-03-28T09:17:08.618",
 
            "reviewer" : "user"
 
          }
 
        ]
 
      }
 
    }
 

	
 
get_pullrequest
 
^^^^^^^^^^^^^^^
 

	
 
Get information and review status for a given pull request. This command can only be executed
 
using the api_key of a user with read permissions to the original repository.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "get_pullrequest"
 
    args :    {
 
                "pullrequest_id" : "<pullrequest_id>",
 
                "pullrequest_id" : "<pullrequest_id>"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
        "status" : "<pull_request_status>",
 
        "pull_request_id" : <pull_request_id>,
 
        "description" : "<pull_request_description>",
 
        "title" : "<pull_request_title>",
 
        "url" : "<pull_request_url>",
 
        "reviewers" : [
 
          {
 
            "username" : "<user_name>",
 
            "username" : "<user_name>"
 
          },
 
          ...
 
        ],
 
        "org_repo_url" : "<repo_url>",
 
        "org_ref_parts" : [
 
          "<ref_type>",
 
          "<ref_name>",
 
          "<raw_id>"
 
        ],
 
        "other_ref_parts" : [
 
          "<ref_type>",
 
          "<ref_name>",
 
          "<raw_id>"
 
        ],
 
        "comments" : [
 
          {
 
            "username" : "<user_name>",
 
            "text" : "<comment text>",
 
            "comment_id" : "<comment_id>",
 
            "comment_id" : "<comment_id>"
 
          },
 
          ...
 
        ],
 
        "owner" : "<username>",
 
        "statuses" : [
 
          {
 
            "status" : "<status_of_review>",        # "under_review", "approved" or "rejected"
 
            "reviewer" : "<user_name>",
 
            "modified_at" : "<date_time_of_review>" # iso 8601 date, server's timezone
 
          },
 
          ...
 
        ],
 
        "revisions" : [
 
          "<raw_id>",
 
          ...
 
        ]
 
    },
 
    error : null
 

	
 
comment_pullrequest
 
^^^^^^^^^^^^^^^^^^^
 

	
 
Add comment, change status or close a given pull request. This command can only be executed
 
using the api_key of a user with read permissions to the original repository.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "comment_pullrequest"
 
    args :    {
 
                "pull_request_id" : "<pull_request_id>",
 
                "comment_msg" :     Optional(''),
 
                "status" :          Optional(None),     # "under_review", "approved" or "rejected"
 
                "close_pr" :        Optional(False)",
 
                "close_pr" :        Optional(False)"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : True
 
    error : null
 

	
 

	
 
API access for web views
 
------------------------
 

	
 
Kallithea HTTP entry points can also be accessed without login using bearer
 
authentication by including this header with the request::
 

	
 
    Authentication: Bearer <api_key>
 

	
 
Alternatively, the API key can be passed in the URL query string using
 
``?api_key=<api_key>``, though this is not recommended due to the increased
 
risk of API key leaks, and support will likely be removed in the future.
 

	
 
Exposing raw diffs is a good way to integrate with
 
third-party services like code review, or build farms that can download archives.
kallithea/controllers/api/api.py
Show inline comments
 
@@ -81,650 +81,650 @@ def get_repo_or_error(repoid):
 
    :param repoid:
 
    """
 
    repo = RepoModel().get_repo(repoid)
 
    if repo is None:
 
        raise JSONRPCError('repository `%s` does not exist' % (repoid,))
 
    return repo
 

	
 

	
 
def get_repo_group_or_error(repogroupid):
 
    """
 
    Get repo group by id or name or return JsonRPCError if not found
 

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

	
 

	
 
def get_user_group_or_error(usergroupid):
 
    """
 
    Get user group by id or name or return JsonRPCError if not found
 

	
 
    :param usergroupid:
 
    """
 
    user_group = UserGroupModel().get_group(usergroupid)
 
    if user_group is None:
 
        raise JSONRPCError('user group `%s` does not exist' % (usergroupid,))
 
    return user_group
 

	
 

	
 
def get_perm_or_error(permid, prefix=None):
 
    """
 
    Get permission by id or name or return JsonRPCError if not found
 

	
 
    :param permid:
 
    """
 
    perm = db.Permission.get_by_key(permid)
 
    if perm is None:
 
        raise JSONRPCError('permission `%s` does not exist' % (permid,))
 
    if prefix:
 
        if not perm.permission_name.startswith(prefix):
 
            raise JSONRPCError('permission `%s` is invalid, '
 
                               'should start with %s' % (permid, prefix))
 
    return perm
 

	
 

	
 
def get_gist_or_error(gistid):
 
    """
 
    Get gist by id or gist_access_id or return JsonRPCError if not found
 

	
 
    :param gistid:
 
    """
 
    gist = GistModel().get_gist(gistid)
 
    if gist is None:
 
        raise JSONRPCError('gist `%s` does not exist' % (gistid,))
 
    return gist
 

	
 

	
 
class ApiController(JSONRPCController):
 
    """
 
    API Controller
 

	
 
    The authenticated user can be found as request.authuser.
 

	
 
    Example function::
 

	
 
        def func(arg1, arg2,...):
 
            pass
 

	
 
    Each function should also **raise** JSONRPCError for any
 
    errors that happens.
 
    """
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def test(self, args):
 
        return args
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def pull(self, repoid, clone_uri=None):
 
        """
 
        Triggers a pull from remote location on given repo. Can be used to
 
        automatically keep remote repos up to date. This command can be executed
 
        only using api_key belonging to user with admin rights
 

	
 
        :param repoid: repository name or repository id
 
        :type repoid: str or int
 
        :param clone_uri: repository URI to pull from (optional)
 
        :type clone_uri: str
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : {
 
                "msg" : "Pulled from `<repository name>`"
 
                "msg" : "Pulled from `<repository name>`",
 
                "repository" : "<repository name>"
 
            }
 
            error : null
 

	
 
        ERROR OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : null
 
            error :  {
 
                "Unable to pull changes from `<reponame>`"
 
            }
 
        """
 
        repo = get_repo_or_error(repoid)
 

	
 
        try:
 
            ScmModel().pull_changes(repo.repo_name,
 
                                    request.authuser.username,
 
                                    request.ip_addr,
 
                                    clone_uri=clone_uri)
 
            return dict(
 
                msg='Pulled from `%s`' % repo.repo_name,
 
                repository=repo.repo_name
 
            )
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'Unable to pull changes from `%s`' % repo.repo_name
 
            )
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def rescan_repos(self, remove_obsolete=False):
 
        """
 
        Triggers rescan repositories action. If remove_obsolete is set
 
        than also delete repos that are in database but not in the filesystem.
 
        aka "clean zombies". This command can be executed only using api_key
 
        belonging to user with admin rights.
 

	
 
        :param remove_obsolete: deletes repositories from
 
            database that are not found on the filesystem
 
        :type remove_obsolete: Optional(bool)
 

	
 
        OUTPUT::
 

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

	
 
        ERROR OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : null
 
            error :  {
 
                'Error occurred during rescan repositories action'
 
            }
 
        """
 
        try:
 
            rm_obsolete = remove_obsolete
 
            added, removed = repo2db_mapper(ScmModel().repo_scan(),
 
                                            remove_obsolete=rm_obsolete)
 
            return {'added': added, 'removed': removed}
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'Error occurred during rescan repositories action'
 
            )
 

	
 
    def invalidate_cache(self, repoid):
 
        """
 
        Invalidate cache for repository.
 
        This command can be executed only using api_key belonging to user with admin
 
        rights or regular user that have write or admin or write access to repository.
 

	
 
        :param repoid: repository name or repository id
 
        :type repoid: str or int
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : {
 
                'msg': Cache for repository `<repository name>` was invalidated,
 
                'repository': <repository name>
 
            }
 
            error : null
 

	
 
        ERROR OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : null
 
            error :  {
 
                'Error occurred during cache invalidation action'
 
            }
 
        """
 
        repo = get_repo_or_error(repoid)
 
        if not HasPermissionAny('hg.admin')():
 
            if not HasRepoPermissionLevel('write')(repo.repo_name):
 
                raise JSONRPCError('repository `%s` does not exist' % (repoid,))
 

	
 
        try:
 
            ScmModel().mark_for_invalidation(repo.repo_name)
 
            return dict(
 
                msg='Cache for repository `%s` was invalidated' % (repoid,),
 
                repository=repo.repo_name
 
            )
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'Error occurred during cache invalidation action'
 
            )
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def get_ip(self, userid=None):
 
        """
 
        Shows IP address as seen from Kallithea server, together with all
 
        defined IP addresses for given user. If userid is not passed data is
 
        returned for user who's calling this function.
 
        This command can be executed only using api_key belonging to user with
 
        admin rights.
 

	
 
        :param userid: username to show ips for
 
        :type userid: Optional(str or int)
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : {
 
                         "server_ip_addr" : "<ip_from_client>",
 
                         "user_ips" : [
 
                                        {
 
                                           "ip_addr" : "<ip_with_mask>",
 
                                           "ip_range" : ["<start_ip>", "<end_ip>"],
 
                                           "ip_range" : ["<start_ip>", "<end_ip>"]
 
                                        },
 
                                        ...
 
                                      ]
 
            }
 
            error : null
 
        """
 
        if userid is None:
 
            userid = request.authuser.user_id
 
        user = get_user_or_error(userid)
 
        ips = db.UserIpMap.query().filter(db.UserIpMap.user == user).all()
 
        return dict(
 
            server_ip_addr=request.ip_addr,
 
            user_ips=ips
 
        )
 

	
 
    # alias for old
 
    show_ip = get_ip
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def get_server_info(self):
 
        """
 
        return server info, including Kallithea version and installed packages
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : {
 
                'modules' : [ [<module name>, <module version>], ...]
 
                'py_version' : <python version>,
 
                'platform' : <platform type>,
 
                'kallithea_version' : <kallithea version>,
 
                'git_version' : '<git version>',
 
                'git_path' : '<git path>'
 
            }
 
            error : null
 
        """
 
        return db.Setting.get_server_info()
 

	
 
    def get_user(self, userid=None):
 
        """
 
        Gets a user by username or user_id, Returns empty result if user is
 
        not found. If userid param is skipped it is set to id of user who is
 
        calling this method. This command can be executed only using api_key
 
        belonging to user with admin rights, or regular users that cannot
 
        specify different userid than theirs
 

	
 
        :param userid: user to get data for
 
        :type userid: Optional(str or int)
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : None if user does not exist or
 
                     {
 
                        "user_id" :     "<user_id>",
 
                        "username" :    "<username>",
 
                        "firstname" :   "<firstname>",
 
                        "lastname" :    "<lastname>",
 
                        "email" :       "<email>",
 
                        "emails" :      "[<list of all emails including additional ones>]",
 
                        "active" :      "<bool: user active>",
 
                        "admin" :       "<bool: user is admin>",
 
                        "permissions" : {
 
                            "global" : ["hg.create.repository",
 
                                        "repository.read",
 
                                        "hg.register.manual_activate"],
 
                            "repositories" : {"repo1" : "repository.none"},
 
                            "repositories_groups" : {"Group1" : "group.read"},
 
                            "user_groups" : { "usrgrp1" : "usergroup.admin" }
 
                         },
 
                         }
 
                     }
 
            error : null
 
        """
 
        if not HasPermissionAny('hg.admin')():
 
            # make sure normal user does not pass someone else userid,
 
            # he is not allowed to do that
 
            if userid is not None and userid != request.authuser.user_id:
 
                raise JSONRPCError(
 
                    'userid is not the same as your user'
 
                )
 

	
 
        if userid is None:
 
            userid = request.authuser.user_id
 

	
 
        user = get_user_or_error(userid)
 
        data = user.get_api_data()
 
        data['permissions'] = AuthUser(user_id=user.user_id).permissions
 
        return data
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def get_users(self):
 
        """
 
        Lists all existing users. This command can be executed only using api_key
 
        belonging to user with admin rights.
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : [<user_object>, ...]
 
            error : null
 
        """
 
        return [
 
            user.get_api_data()
 
            for user in db.User.query()
 
                .order_by(db.User.username)
 
                .filter_by(is_default_user=False)
 
        ]
 

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

	
 
        :param username: new username
 
        :type username: str or int
 
        :param email: email
 
        :type email: str
 
        :param password: password
 
        :type password: Optional(str)
 
        :param firstname: firstname
 
        :type firstname: str
 
        :param lastname: lastname
 
        :type lastname: str
 
        :param active: active
 
        :type active: Optional(bool)
 
        :param admin: admin
 
        :type admin: Optional(bool)
 
        :param extern_name: name of extern
 
        :type extern_name: Optional(str)
 
        :param extern_type: extern_type
 
        :type extern_type: Optional(str)
 

	
 
        OUTPUT::
 

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

	
 
        ERROR OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : null
 
            error :  {
 
                "user `<username>` already exist"
 
                or
 
                "email `<email>` already exist"
 
                or
 
                "failed to create user `<username>`"
 
            }
 
        """
 
        if db.User.get_by_username(username):
 
            raise JSONRPCError("user `%s` already exist" % (username,))
 

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

	
 
        try:
 
            user = UserModel().create_or_update(
 
                username=username,
 
                password=password,
 
                email=email,
 
                firstname=firstname,
 
                lastname=lastname,
 
                active=active,
 
                admin=admin,
 
                extern_type=extern_type,
 
                extern_name=extern_name
 
            )
 
            meta.Session().commit()
 
            return dict(
 
                msg='created new user `%s`' % username,
 
                user=user.get_api_data()
 
            )
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError('failed to create user `%s`' % (username,))
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def update_user(self, userid, username=None,
 
                    email=None, password=None,
 
                    firstname=None, lastname=None,
 
                    active=None, admin=None,
 
                    extern_type=None, extern_name=None):
 
        """
 
        updates given user if such user exists. This command can
 
        be executed only using api_key belonging to user with admin rights.
 

	
 
        :param userid: userid to update
 
        :type userid: str or int
 
        :param username: new username
 
        :type username: Optional(str or int)
 
        :param email: email
 
        :type email: Optional(str)
 
        :param password: password
 
        :type password: Optional(str)
 
        :param firstname: firstname
 
        :type firstname: Optional(str)
 
        :param lastname: lastname
 
        :type lastname: Optional(str)
 
        :param active: active
 
        :type active: Optional(bool)
 
        :param admin: admin
 
        :type admin: Optional(bool)
 
        :param extern_name:
 
        :type extern_name: Optional(str)
 
        :param extern_type:
 
        :type extern_type: Optional(str)
 

	
 
        OUTPUT::
 

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

	
 
        ERROR OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : null
 
            error :  {
 
                "failed to update user `<username>`"
 
            }
 
        """
 
        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)
 
            meta.Session().commit()
 
            return dict(
 
                msg='updated user ID:%s %s' % (user.user_id, user.username),
 
                user=user.get_api_data()
 
            )
 
        except DefaultUserException:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError('editing default user is forbidden')
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError('failed to update user `%s`' % (userid,))
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def delete_user(self, userid):
 
        """
 
        deletes given user if such user exists. This command can
 
        be executed only using api_key belonging to user with admin rights.
 

	
 
        :param userid: user to delete
 
        :type userid: str or int
 

	
 
        OUTPUT::
 

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

	
 
        ERROR OUTPUT::
 

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

	
 
        try:
 
            UserModel().delete(userid)
 
            meta.Session().commit()
 
            return dict(
 
                msg='deleted user ID:%s %s' % (user.user_id, user.username),
 
                user=None
 
            )
 
        except Exception:
 

	
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError('failed to delete user ID:%s %s'
 
                               % (user.user_id, user.username))
 

	
 
    # permission check inside
 
    def get_user_group(self, usergroupid):
 
        """
 
        Gets an existing user group. This command can be executed only using api_key
 
        belonging to user with admin rights or user who has at least
 
        read access to user group.
 

	
 
        :param usergroupid: id of user_group to edit
 
        :type usergroupid: str or int
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : None if group not exist
 
                     {
 
                       "users_group_id" : "<id>",
 
                       "group_name" :     "<groupname>",
 
                       "group_description" : "<description>"
 
                       "group_description" : "<description>",
 
                       "active" :         "<bool>",
 
                       "owner" :          "<username>"
 
                       "owner" :          "<username>",
 
                       "members" :        [<user_obj>,...]
 
                     }
 
            error : null
 
        """
 
        user_group = get_user_group_or_error(usergroupid)
 
        if not HasPermissionAny('hg.admin')():
 
            if not HasUserGroupPermissionLevel('read')(user_group.users_group_name):
 
                raise JSONRPCError('user group `%s` does not exist' % (usergroupid,))
 

	
 
        data = user_group.get_api_data()
 
        return data
 

	
 
    # permission check inside
 
    def get_user_groups(self):
 
        """
 
        Lists all existing user groups. This command can be executed only using
 
        api_key belonging to user with admin rights or user who has at least
 
        read access to user group.
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : [<user_group_obj>,...]
 
            error : null
 
        """
 
        return [
 
            user_group.get_api_data()
 
            for user_group in UserGroupList(db.UserGroup.query().all(), perm_level='read')
 
        ]
 

	
 
    @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
 
    def create_user_group(self, group_name, description='',
 
                          owner=None, active=True):
 
        """
 
        Creates new user group. This command can be executed only using api_key
 
        belonging to user with admin rights or an user who has create user group
 
        permission
 

	
 
        :param group_name: name of new user group
 
        :type group_name: str
 
        :param description: group description
 
        :type description: Optional(str)
 
        :param owner: owner of group. If not passed apiuser is the owner
 
        :type owner: Optional(str or int)
 
        :param active: group is active
 
        :type active: Optional(bool)
 

	
 
        OUTPUT::
 

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

	
 
        ERROR OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : null
 
            error :  {
 
                "user group `<group name>` already exist"
 
                or
 
                "failed to create group `<group name>`"
 
            }
 
        """
 
        if UserGroupModel().get_by_name(group_name):
 
            raise JSONRPCError("user group `%s` already exist" % (group_name,))
 

	
 
        try:
 
            if owner is None:
 
                owner = request.authuser.user_id
 

	
 
            owner = get_user_or_error(owner)
 
            ug = UserGroupModel().create(name=group_name, description=description,
 
                                         owner=owner, active=active)
 
            meta.Session().commit()
 
            return dict(
 
                msg='created new user group `%s`' % group_name,
 
                user_group=ug.get_api_data()
 
            )
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError('failed to create group `%s`' % (group_name,))
 

	
 
    # permission check inside
 
    def update_user_group(self, usergroupid, group_name=None,
 
                          description=None, owner=None,
 
                          active=None):
 
        """
 
        Updates given usergroup.  This command can be executed only using api_key
 
        belonging to user with admin rights or an admin of given user group
 

	
 
        :param usergroupid: id of user group to update
 
        :type usergroupid: str or int
 
        :param group_name: name of new user group
 
@@ -853,344 +853,344 @@ class ApiController(JSONRPCController):
 

	
 
        ERROR OUTPUT::
 

	
 
            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 HasPermissionAny('hg.admin')():
 
            if not HasUserGroupPermissionLevel('admin')(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'
 
            meta.Session().commit()
 

	
 
            return dict(
 
                success=success,
 
                msg=msg
 
            )
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'failed to add member to user group `%s`' % (
 
                    user_group.users_group_name,
 
                )
 
            )
 

	
 
    # permission check inside
 
    def remove_user_from_user_group(self, usergroupid, userid):
 
        """
 
        Removes a user from a user group. If user is not in given group success will
 
        be `false`. This command can be executed only
 
        using api_key belonging to user with admin rights or an admin of given user group
 

	
 
        :param usergroupid:
 
        :param userid:
 

	
 
        OUTPUT::
 

	
 
            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 HasPermissionAny('hg.admin')():
 
            if not HasUserGroupPermissionLevel('admin')(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"
 
            meta.Session().commit()
 
            return dict(success=success, msg=msg)
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'failed to remove member from user group `%s`' % (
 
                    user_group.users_group_name,
 
                )
 
            )
 

	
 
    # permission check inside
 
    def get_repo(self, repoid,
 
                 with_revision_names=False,
 
                 with_pullrequests=False):
 
        """
 
        Gets an existing repository by it's name or repository_id. Members will return
 
        either users_group or user associated to that repository. This command can be
 
        executed only using api_key belonging to user with admin
 
        rights or regular user that have at least read access to repository.
 

	
 
        :param repoid: repository name or repository id
 
        :type repoid: str or int
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : {
 
                        "repo_id" :          "<repo_id>",
 
                        "repo_name" :        "<reponame>"
 
                        "repo_name" :        "<reponame>",
 
                        "repo_type" :        "<repo_type>",
 
                        "clone_uri" :        "<clone_uri>",
 
                        "enable_downloads" : "<bool>",
 
                        "enable_statistics": "<bool>",
 
                        "private" :          "<bool>",
 
                        "created_on" :       "<date_time_created>",
 
                        "description" :      "<description>",
 
                        "landing_rev" :      "<landing_rev>",
 
                        "last_changeset" :   {
 
                                                 "author" :  "<full_author>",
 
                                                 "date" :    "<date_time_of_commit>",
 
                                                 "message" : "<commit_message>",
 
                                                 "raw_id" :  "<raw_id>",
 
                                                 "revision": "<numeric_revision>",
 
                                                 "short_id": "<short_id>"
 
                                             }
 
                                             },
 
                        "owner" :            "<repo_owner>",
 
                        "fork_of" :          "<name_of_fork_parent>",
 
                        "members" :     [
 
                                            {
 
                                                "name" :    "<username>",
 
                                                "type" :    "user",
 
                                                "permission" : "repository.(read|write|admin)"
 
                                            },
 
                                            …
 
                                            {
 
                                                "name" :    "<usergroup name>",
 
                                                "type" :    "user_group",
 
                                                "permission" : "usergroup.(read|write|admin)"
 
                                            },
 
                                            …
 
                                        ]
 
                                        ],
 
                        "followers" :  [<user_obj>, ...],
 
                        <if with_revision_names == True>
 
                        "tags" : {
 
                                    "<tagname>" : "<raw_id>",
 
                                    ...
 
                                },
 
                        "branches" : {
 
                                    "<branchname>" : "<raw_id>",
 
                                    ...
 
                                },
 
                        "bookmarks" : {
 
                                    "<bookmarkname>" : "<raw_id>",
 
                                    ...
 
                                },
 
                                }
 
                     }
 
            error : null
 
        """
 
        repo = get_repo_or_error(repoid)
 

	
 
        if not HasPermissionAny('hg.admin')():
 
            if not HasRepoPermissionLevel('read')(repo.repo_name):
 
                raise JSONRPCError('repository `%s` does not exist' % (repoid,))
 

	
 
        members = []
 
        for user in repo.repo_to_perm:
 
            perm = user.permission.permission_name
 
            user = user.user
 
            user_data = {
 
                'name': user.username,
 
                'type': "user",
 
                'permission': perm
 
            }
 
            members.append(user_data)
 

	
 
        for user_group in repo.users_group_to_perm:
 
            perm = user_group.permission.permission_name
 
            user_group = user_group.users_group
 
            user_group_data = {
 
                'name': user_group.users_group_name,
 
                'type': "user_group",
 
                'permission': perm
 
            }
 
            members.append(user_group_data)
 

	
 
        followers = [
 
            uf.user.get_api_data()
 
            for uf in repo.followers
 
        ]
 

	
 
        data = repo.get_api_data(with_revision_names=with_revision_names,
 
                                 with_pullrequests=with_pullrequests)
 
        data['members'] = members
 
        data['followers'] = followers
 
        return data
 

	
 
    # permission check inside
 
    def get_repos(self):
 
        """
 
        Lists all existing repositories. This command can be executed only using
 
        api_key belonging to user with admin rights or regular user that have
 
        admin, write or read access to repository.
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : [
 
                      {
 
                        "repo_id" :          "<repo_id>",
 
                        "repo_name" :        "<reponame>"
 
                        "repo_name" :        "<reponame>",
 
                        "repo_type" :        "<repo_type>",
 
                        "clone_uri" :        "<clone_uri>",
 
                        "private" :          "<bool>",
 
                        "created_on" :       "<datetimecreated>",
 
                        "description" :      "<description>",
 
                        "landing_rev" :      "<landing_rev>",
 
                        "owner" :            "<repo_owner>",
 
                        "fork_of" :          "<name_of_fork_parent>",
 
                        "enable_downloads" : "<bool>",
 
                        "enable_statistics": "<bool>",
 
                        "enable_statistics": "<bool>"
 
                      },
 
                      …
 
                     ]
 
            error : null
 
        """
 
        if not HasPermissionAny('hg.admin')():
 
            repos = request.authuser.get_all_user_repos()
 
        else:
 
            repos = db.Repository.query()
 

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

	
 
    # permission check inside
 
    def get_repo_nodes(self, repoid, revision, root_path,
 
                       ret_type='all'):
 
        """
 
        returns a list of nodes and it's children in a flat list for a given path
 
        at given revision. It's possible to specify ret_type to show only `files` or
 
        `dirs`.  This command can be executed only using api_key belonging to
 
        user with admin rights or regular user that have at least read access to repository.
 

	
 
        :param repoid: repository name or repository id
 
        :type repoid: str or int
 
        :param revision: revision for which listing should be done
 
        :type revision: str
 
        :param root_path: path from which start displaying
 
        :type root_path: str
 
        :param ret_type: return type 'all|files|dirs' nodes
 
        :type ret_type: Optional(str)
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : [
 
                      {
 
                        "name" :        "<name>"
 
                        "type" :        "<type>",
 
                        "name" :        "<name>",
 
                        "type" :        "<type>"
 
                      },
 
                      …
 
                     ]
 
            error : null
 
        """
 
        repo = get_repo_or_error(repoid)
 

	
 
        if not HasPermissionAny('hg.admin')():
 
            if not HasRepoPermissionLevel('read')(repo.repo_name):
 
                raise JSONRPCError('repository `%s` does not exist' % (repoid,))
 

	
 
        _map = {}
 
        try:
 
            _d, _f = ScmModel().get_nodes(repo, revision, root_path,
 
                                          flat=False)
 
            _map = {
 
                'all': _d + _f,
 
                'files': _f,
 
                'dirs': _d,
 
            }
 
            return _map[ret_type]
 
        except KeyError:
 
            raise JSONRPCError('ret_type must be one of %s'
 
                               % (','.join(sorted(_map))))
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'failed to get repo: `%s` nodes' % repo.repo_name
 
            )
 

	
 
    # permission check inside
 
    def create_repo(self, repo_name, owner=None,
 
                    repo_type=None, description='',
 
                    private=False, clone_uri=None,
 
                    landing_rev='rev:tip',
 
                    enable_statistics=None,
 
                    enable_downloads=None,
 
                    copy_permissions=False):
 
        """
 
        Creates a repository. The repository name contains the full path, but the
 
        parent repository group must exist. For example "foo/bar/baz" require the groups
 
        "foo" and "bar" (with "foo" as parent), and create "baz" repository with
 
        "bar" as group. This command can be executed only using api_key
 
        belonging to user with admin rights or regular user that have create
 
        repository permission. Regular users cannot specify owner parameter
 

	
 
        :param repo_name: repository name
 
        :type repo_name: str
 
        :param owner: user_id or username
 
        :type owner: Optional(str)
 
        :param repo_type: 'hg' or 'git'
 
        :type repo_type: Optional(str)
 
        :param description: repository description
 
        :type description: Optional(str)
 
        :param private:
 
        :type private: bool
 
        :param clone_uri:
 
        :type clone_uri: str
 
        :param landing_rev: <rev_type>:<rev>
 
        :type landing_rev: str
 
        :param enable_downloads:
 
        :type enable_downloads: bool
 
        :param enable_statistics:
 
        :type enable_statistics: bool
 
        :param copy_permissions: Copy permission from group that repository is
 
            being created.
 
        :type copy_permissions: bool
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : {
 
                      "msg" : "Created new repository `<reponame>`",
 
                      "success" : true
 
                     }
 
            error : null
 

	
 
        ERROR OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : null
 
            error :  {
 
                'failed to create repository `<repo_name>`
 
            }
 
        """
 
        group_name = None
 
        repo_name_parts = repo_name.split('/')
 
        if len(repo_name_parts) > 1:
 
            group_name = '/'.join(repo_name_parts[:-1])
 
            repo_group = db.RepoGroup.get_by_group_name(group_name)
 
            if repo_group is None:
 
                raise JSONRPCError("repo group `%s` not found" % group_name)
 
            if not(HasPermissionAny('hg.admin')() or HasRepoGroupPermissionLevel('write')(group_name)):
 
                raise JSONRPCError("no permission to create repo in %s" % group_name)
 
        else:
 
            if not HasPermissionAny('hg.admin', 'hg.create.repository')():
 
@@ -1651,193 +1651,193 @@ class ApiController(JSONRPCController):
 
            if not HasRepoPermissionLevel('admin')(repo.repo_name):
 
                raise JSONRPCError('repository `%s` does not exist' % (repoid,))
 

	
 
            if not HasUserGroupPermissionLevel('read')(user_group.users_group_name):
 
                raise JSONRPCError('user group `%s` does not exist' % (usergroupid,))
 

	
 
        try:
 
            RepoModel().revoke_user_group_permission(
 
                repo=repo, group_name=user_group)
 

	
 
            meta.Session().commit()
 
            return dict(
 
                msg='Revoked perm for user group: `%s` in repo: `%s`' % (
 
                    user_group.users_group_name, repo.repo_name
 
                ),
 
                success=True
 
            )
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'failed to edit permission for user group: `%s` in '
 
                'repo: `%s`' % (
 
                    user_group.users_group_name, repo.repo_name
 
                )
 
            )
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def get_repo_group(self, repogroupid):
 
        """
 
        Returns given repo group together with permissions, and repositories
 
        inside the group
 

	
 
        :param repogroupid: id/name of repository group
 
        :type repogroupid: str or int
 
        """
 
        repo_group = get_repo_group_or_error(repogroupid)
 

	
 
        members = []
 
        for user in repo_group.repo_group_to_perm:
 
            perm = user.permission.permission_name
 
            user = user.user
 
            user_data = {
 
                'name': user.username,
 
                'type': "user",
 
                'permission': perm
 
            }
 
            members.append(user_data)
 

	
 
        for user_group in repo_group.users_group_to_perm:
 
            perm = user_group.permission.permission_name
 
            user_group = user_group.users_group
 
            user_group_data = {
 
                'name': user_group.users_group_name,
 
                'type': "user_group",
 
                'permission': perm
 
            }
 
            members.append(user_group_data)
 

	
 
        data = repo_group.get_api_data()
 
        data["members"] = members
 
        return data
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def get_repo_groups(self):
 
        """
 
        Returns all repository groups
 
        """
 
        return [
 
            repo_group.get_api_data()
 
            for repo_group in db.RepoGroup.query()
 
        ]
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def create_repo_group(self, group_name, description='',
 
                          owner=None,
 
                          parent=None,
 
                          copy_permissions=False):
 
        """
 
        Creates a repository group. This command can be executed only using
 
        api_key belonging to user with admin rights.
 

	
 
        :param group_name:
 
        :type group_name:
 
        :param description:
 
        :type description:
 
        :param owner:
 
        :type owner:
 
        :param parent:
 
        :type parent:
 
        :param copy_permissions:
 
        :type copy_permissions:
 

	
 
        OUTPUT::
 

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

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            failed to create repo group `<repogroupid>`
 
          }
 
        """
 
        if db.RepoGroup.get_by_group_name(group_name):
 
            raise JSONRPCError("repo group `%s` already exist" % (group_name,))
 

	
 
        if owner is None:
 
            owner = request.authuser.user_id
 
        group_description = description
 
        parent_group = None
 
        if parent is not None:
 
            parent_group = get_repo_group_or_error(parent)
 

	
 
        try:
 
            repo_group = RepoGroupModel().create(
 
                group_name=group_name,
 
                group_description=group_description,
 
                owner=owner,
 
                parent=parent_group,
 
                copy_permissions=copy_permissions
 
            )
 
            meta.Session().commit()
 
            return dict(
 
                msg='created new repo group `%s`' % group_name,
 
                repo_group=repo_group.get_api_data()
 
            )
 
        except Exception:
 

	
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError('failed to create repo group `%s`' % (group_name,))
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def update_repo_group(self, repogroupid, group_name=None,
 
                          description=None,
 
                          owner=None,
 
                          parent=None):
 
        repo_group = get_repo_group_or_error(repogroupid)
 

	
 
        updates = {}
 
        try:
 
            store_update(updates, group_name, 'group_name')
 
            store_update(updates, description, 'group_description')
 
            store_update(updates, owner, 'owner')
 
            store_update(updates, parent, 'parent_group')
 
            repo_group = RepoGroupModel().update(repo_group, updates)
 
            meta.Session().commit()
 
            return dict(
 
                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.error(traceback.format_exc())
 
            raise JSONRPCError('failed to update repository group `%s`'
 
                               % (repogroupid,))
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def delete_repo_group(self, repogroupid):
 
        """
 
        :param repogroupid: name or id of repository group
 
        :type repogroupid: str or int
 

	
 
        OUTPUT::
 

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

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "failed to delete repo group ID:<repogroupid> <repogroupname>"
 
          }
 
        """
 
        repo_group = get_repo_group_or_error(repogroupid)
 

	
 
        try:
 
            RepoGroupModel().delete(repo_group)
 
            meta.Session().commit()
 
            return dict(
 
                msg='deleted repo group ID:%s %s' %
 
                    (repo_group.group_id, repo_group.group_name),
0 comments (0 inline, 0 general)