|
Pierre-Yves Chibon |
a1265e |
# -*- coding: utf-8 -*-
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Pierre-Yves Chibon |
a1265e |
"""
|
|
Pierre-Yves Chibon |
01d0f2 |
(c) 2015-2019 - Copyright Red Hat Inc
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Pierre-Yves Chibon |
a1265e |
Authors:
|
|
Pierre-Yves Chibon |
a1265e |
Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Pierre-Yves Chibon |
a1265e |
"""
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Pierre-Yves Chibon |
67d1cc |
from __future__ import unicode_literals, absolute_import
|
|
Aurélien Bompard |
dcf6f6 |
|
|
Pierre-Yves Chibon |
a1265e |
import flask
|
|
Pierre-Yves Chibon |
b130e5 |
import logging
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Pierre-Yves Chibon |
9f9b1e |
from sqlalchemy.exc import SQLAlchemyError
|
|
mprahl |
7d811e |
from six import string_types
|
|
Pierre-Yves Chibon |
8715b5 |
from pygit2 import GitError, Repository
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Pierre-Yves Chibon |
a1265e |
import pagure
|
|
Pierre-Yves Chibon |
8715b5 |
import pagure.forms
|
|
Pierre-Yves Chibon |
a1265e |
import pagure.exceptions
|
|
Matt Prahl |
cd940d |
import pagure.lib.git
|
|
Pierre-Yves Chibon |
930073 |
import pagure.lib.query
|
|
Pierre-Yves Chibon |
b130e5 |
import pagure.utils
|
|
Pierre-Yves Chibon |
9c2953 |
from pagure.api import (
|
|
Pierre-Yves Chibon |
9c2953 |
API,
|
|
Pierre-Yves Chibon |
9c2953 |
api_method,
|
|
Pierre-Yves Chibon |
9c2953 |
APIERROR,
|
|
Pierre-Yves Chibon |
9c2953 |
api_login_required,
|
|
Pierre-Yves Chibon |
9c2953 |
get_authorized_api_project,
|
|
Pierre-Yves Chibon |
9c2953 |
api_login_optional,
|
|
Pierre-Yves Chibon |
9c2953 |
get_request_data,
|
|
Pierre-Yves Chibon |
9c2953 |
get_page,
|
|
Pierre-Yves Chibon |
9c2953 |
get_per_page,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
01d0f2 |
from pagure.api.utils import _get_repo, _check_token
|
|
Pierre-Yves Chibon |
b130e5 |
from pagure.config import config as pagure_config
|
|
Pierre-Yves Chibon |
b130e5 |
|
|
Pierre-Yves Chibon |
b130e5 |
|
|
Pierre-Yves Chibon |
b130e5 |
_log = logging.getLogger(__name__)
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<repo>/git/tags")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<namespace>/<repo>/git/tags")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<repo>/git/tags")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<namespace>/<repo>/git/tags")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
a1265e |
@api_method
|
|
Pierre-Yves Chibon |
34ece4 |
def api_git_tags(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
a1265e |
"""
|
|
Pierre-Yves Chibon |
a1265e |
Project git tags
|
|
Pierre-Yves Chibon |
a1265e |
----------------
|
|
Lei Yang |
566c51 |
List the tags made on the project Git repository.
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Pierre-Yves Chibon |
a1265e |
::
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Lei Yang |
566c51 |
GET /api/0/<repo>/git/tags</repo>
|
|
Pierre-Yves Chibon |
34ece4 |
GET /api/0/<namespace>/<repo>/git/tags</repo></namespace>
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Lei Yang |
566c51 |
::
|
|
Lei Yang |
566c51 |
|
|
Lei Yang |
566c51 |
GET /api/0/fork/<username>/<repo>/git/tags</repo></username>
|
|
Pierre-Yves Chibon |
34ece4 |
GET /api/0/fork/<username>/<namespace>/<repo>/git/tags</repo></namespace></username>
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Pierre-Yves Chibon |
06f5ad |
Parameters
|
|
Pierre-Yves Chibon |
06f5ad |
^^^^^^^^^^
|
|
Pierre-Yves Chibon |
06f5ad |
|
|
Pierre-Yves Chibon |
06f5ad |
+-----------------+----------+---------------+--------------------------+
|
|
Pierre-Yves Chibon |
06f5ad |
| Key | Type | Optionality | Description |
|
|
Pierre-Yves Chibon |
06f5ad |
+=================+==========+===============+==========================+
|
|
Pierre-Yves Chibon |
06f5ad |
| ``with_commits``| string | Optional | | Include the commit hash|
|
|
Pierre-Yves Chibon |
06f5ad |
| | | | corresponding to the |
|
|
Pierre-Yves Chibon |
06f5ad |
| | | | tags found in the repo |
|
|
Pierre-Yves Chibon |
06f5ad |
+-----------------+----------+---------------+--------------------------+
|
|
Pierre-Yves Chibon |
06f5ad |
|
|
Lei Yang |
566c51 |
Sample response
|
|
Lei Yang |
566c51 |
^^^^^^^^^^^^^^^
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Pierre-Yves Chibon |
a1265e |
::
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Pierre-Yves Chibon |
a1265e |
{
|
|
Pierre-Yves Chibon |
7a734f |
"total_tags": 2,
|
|
Pierre-Yves Chibon |
adc200 |
"tags": ["0.0.1", "0.0.2"]
|
|
Pierre-Yves Chibon |
a1265e |
}
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Pierre-Yves Chibon |
06f5ad |
|
|
Pierre-Yves Chibon |
06f5ad |
{
|
|
Pierre-Yves Chibon |
06f5ad |
"total_tags": 2,
|
|
Pierre-Yves Chibon |
06f5ad |
"tags": {
|
|
Pierre-Yves Chibon |
06f5ad |
"0.0.1": "bb8fa2aa199da08d6085e1c9badc3d83d188d38c",
|
|
Pierre-Yves Chibon |
06f5ad |
"0.0.2": "d16fe107eca31a1bdd66fb32c6a5c568e45b627e"
|
|
Pierre-Yves Chibon |
06f5ad |
}
|
|
Pierre-Yves Chibon |
06f5ad |
}
|
|
Pierre-Yves Chibon |
06f5ad |
|
|
Pierre-Yves Chibon |
a1265e |
"""
|
|
Aurélien Bompard |
619e2a |
with_commits = pagure.utils.is_true(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.request.values.get("with_commits", False)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
06f5ad |
|
|
Pierre-Yves Chibon |
01d0f2 |
repo = _get_repo(repo, username, namespace)
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Pierre-Yves Chibon |
06f5ad |
tags = pagure.lib.git.get_git_tags(repo, with_commits=with_commits)
|
|
Pierre-Yves Chibon |
a1265e |
|
|
Pierre-Yves Chibon |
9c2953 |
jsonout = flask.jsonify({"total_tags": len(tags), "tags": tags})
|
|
Pierre-Yves Chibon |
a1265e |
return jsonout
|
|
Pierre-Yves Chibon |
47269d |
|
|
Pierre-Yves Chibon |
47269d |
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<repo>/watchers")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<namespace>/<repo>/watchers")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<repo>/watchers")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<namespace>/<repo>/watchers")</repo></namespace></username>
|
|
Matt Prahl |
733eaa |
@api_method
|
|
Matt Prahl |
733eaa |
def api_project_watchers(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
9c2953 |
"""
|
|
Matt Prahl |
733eaa |
Project watchers
|
|
Matt Prahl |
733eaa |
----------------
|
|
Matt Prahl |
733eaa |
List the watchers on the project.
|
|
Matt Prahl |
733eaa |
|
|
Matt Prahl |
733eaa |
::
|
|
Matt Prahl |
733eaa |
|
|
Matt Prahl |
733eaa |
GET /api/0/<repo>/watchers</repo>
|
|
Matt Prahl |
733eaa |
GET /api/0/<namespace>/<repo>/watchers</repo></namespace>
|
|
Matt Prahl |
733eaa |
|
|
Matt Prahl |
733eaa |
::
|
|
Matt Prahl |
733eaa |
|
|
Matt Prahl |
733eaa |
GET /api/0/fork/<username>/<repo>/watchers</repo></username>
|
|
Matt Prahl |
733eaa |
GET /api/0/fork/<username>/<namespace>/<repo>/watchers</repo></namespace></username>
|
|
Matt Prahl |
733eaa |
|
|
Matt Prahl |
733eaa |
Sample response
|
|
Matt Prahl |
733eaa |
^^^^^^^^^^^^^^^
|
|
Matt Prahl |
733eaa |
|
|
Matt Prahl |
733eaa |
::
|
|
Matt Prahl |
733eaa |
|
|
Matt Prahl |
733eaa |
{
|
|
Matt Prahl |
733eaa |
"total_watchers": 1,
|
|
Matt Prahl |
733eaa |
"watchers": {
|
|
Matt Prahl |
733eaa |
"mprahl": [
|
|
Matt Prahl |
733eaa |
"issues",
|
|
Matt Prahl |
733eaa |
"commits"
|
|
Matt Prahl |
733eaa |
]
|
|
Matt Prahl |
733eaa |
}
|
|
Matt Prahl |
733eaa |
}
|
|
Pierre-Yves Chibon |
9c2953 |
"""
|
|
Pierre-Yves Chibon |
01d0f2 |
repo = _get_repo(repo, username, namespace)
|
|
Matt Prahl |
733eaa |
|
|
Pierre-Yves Chibon |
12d7b9 |
implicit_watch_users = set([repo.user.username])
|
|
Pierre-Yves Chibon |
12d7b9 |
for access_type in repo.access_users:
|
|
Pierre-Yves Chibon |
12d7b9 |
implicit_watch_users = implicit_watch_users.union(
|
|
Pierre-Yves Chibon |
12d7b9 |
set([user.username for user in repo.access_users[access_type]])
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
fd3701 |
|
|
Matt Prahl |
733eaa |
watching_users_to_watch_level = {}
|
|
Matt Prahl |
733eaa |
for implicit_watch_user in implicit_watch_users:
|
|
Pierre-Yves Chibon |
930073 |
user_watch_level = pagure.lib.query.get_watch_level_on_repo(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, implicit_watch_user, repo
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Matt Prahl |
733eaa |
watching_users_to_watch_level[implicit_watch_user] = user_watch_level
|
|
Matt Prahl |
733eaa |
|
|
Ralph Bean |
e69883 |
for access_type in repo.access_groups.keys():
|
|
Pierre-Yves Chibon |
9c2953 |
group_names = [
|
|
Pierre-Yves Chibon |
9c2953 |
"@" + group.group_name for group in repo.access_groups[access_type]
|
|
Pierre-Yves Chibon |
9c2953 |
]
|
|
Ralph Bean |
e69883 |
for group_name in group_names:
|
|
Ralph Bean |
02a9ce |
if group_name not in watching_users_to_watch_level:
|
|
Ralph Bean |
e69883 |
watching_users_to_watch_level[group_name] = set()
|
|
Pierre-Yves Chibon |
930073 |
# By the logic in pagure.lib.query.get_watch_level_on_repo, group
|
|
Pierre-Yves Chibon |
930073 |
# members only by default watch issues. If they want to watch
|
|
Pierre-Yves Chibon |
930073 |
# commits they have to explicitly subscribe.
|
|
Pierre-Yves Chibon |
9c2953 |
watching_users_to_watch_level[group_name].add("issues")
|
|
Ralph Bean |
e69883 |
|
|
Pierre-Yves Chibon |
a55479 |
for key in watching_users_to_watch_level:
|
|
Pierre-Yves Chibon |
a55479 |
watching_users_to_watch_level[key] = list(
|
|
Pierre-Yves Chibon |
9c2953 |
watching_users_to_watch_level[key]
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
a55479 |
|
|
Matt Prahl |
733eaa |
# Get the explicit watch statuses
|
|
Matt Prahl |
733eaa |
for watcher in repo.watchers:
|
|
Matt Prahl |
733eaa |
if watcher.watch_issues or watcher.watch_commits:
|
|
Pierre-Yves Chibon |
9c2953 |
watching_users_to_watch_level[
|
|
Pierre-Yves Chibon |
9c2953 |
watcher.user.username
|
|
Pierre-Yves Chibon |
930073 |
] = pagure.lib.query.get_watch_level_on_repo(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, watcher.user.username, repo
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Matt Prahl |
733eaa |
else:
|
|
Matt Prahl |
733eaa |
if watcher.user.username in watching_users_to_watch_level:
|
|
Matt Prahl |
733eaa |
watching_users_to_watch_level.pop(watcher.user.username, None)
|
|
Matt Prahl |
733eaa |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.jsonify(
|
|
Pierre-Yves Chibon |
9c2953 |
{
|
|
Pierre-Yves Chibon |
9c2953 |
"total_watchers": len(watching_users_to_watch_level),
|
|
Pierre-Yves Chibon |
9c2953 |
"watchers": watching_users_to_watch_level,
|
|
Pierre-Yves Chibon |
9c2953 |
}
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Matt Prahl |
733eaa |
|
|
Matt Prahl |
733eaa |
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<repo>/git/urls")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<namespace>/<repo>/git/urls")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<repo>/git/urls")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<namespace>/<repo>/git/urls")</repo></namespace></username>
|
|
Matt Prahl |
ad5147 |
@api_login_optional()
|
|
Matt Prahl |
ad5147 |
@api_method
|
|
Matt Prahl |
ad5147 |
def api_project_git_urls(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
9c2953 |
"""
|
|
Matt Prahl |
ad5147 |
Project Git URLs
|
|
Matt Prahl |
ad5147 |
----------------
|
|
Matt Prahl |
ad5147 |
List the Git URLS on the project.
|
|
Matt Prahl |
ad5147 |
|
|
Matt Prahl |
ad5147 |
::
|
|
Matt Prahl |
ad5147 |
|
|
Matt Prahl |
ad5147 |
GET /api/0/<repo>/git/urls</repo>
|
|
Matt Prahl |
ad5147 |
GET /api/0/<namespace>/<repo>/git/urls</repo></namespace>
|
|
Matt Prahl |
ad5147 |
|
|
Matt Prahl |
ad5147 |
::
|
|
Matt Prahl |
ad5147 |
|
|
Matt Prahl |
ad5147 |
GET /api/0/fork/<username>/<repo>/git/urls</repo></username>
|
|
Matt Prahl |
ad5147 |
GET /api/0/fork/<username>/<namespace>/<repo>/git/urls</repo></namespace></username>
|
|
Matt Prahl |
ad5147 |
|
|
Matt Prahl |
ad5147 |
Sample response
|
|
Matt Prahl |
ad5147 |
^^^^^^^^^^^^^^^
|
|
Matt Prahl |
ad5147 |
|
|
Matt Prahl |
ad5147 |
::
|
|
Matt Prahl |
ad5147 |
|
|
Matt Prahl |
ad5147 |
{
|
|
Matt Prahl |
ad5147 |
"total_urls": 2,
|
|
Matt Prahl |
ad5147 |
"urls": {
|
|
Matt Prahl |
ad5147 |
"ssh": "ssh://git@pagure.io/mprahl-test123.git",
|
|
Matt Prahl |
ad5147 |
"git": "https://pagure.io/mprahl-test123.git"
|
|
Matt Prahl |
ad5147 |
}
|
|
Matt Prahl |
ad5147 |
}
|
|
Pierre-Yves Chibon |
9c2953 |
"""
|
|
Pierre-Yves Chibon |
01d0f2 |
repo = _get_repo(repo, username, namespace)
|
|
Pierre-Yves Chibon |
7f5772 |
|
|
Pierre-Yves Chibon |
01d0f2 |
git_urls = {}
|
|
Pierre-Yves Chibon |
9c2953 |
git_url_ssh = pagure_config.get("GIT_URL_SSH")
|
|
Pierre-Yves Chibon |
8d8fb0 |
if pagure.utils.api_authenticated() and git_url_ssh:
|
|
Pierre-Yves Chibon |
7f5772 |
try:
|
|
Pierre-Yves Chibon |
7f5772 |
git_url_ssh = git_url_ssh.format(
|
|
Pierre-Yves Chibon |
9c2953 |
username=flask.g.fas_user.username
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
7f5772 |
except (KeyError, IndexError):
|
|
Pierre-Yves Chibon |
7f5772 |
pass
|
|
Pierre-Yves Chibon |
7f5772 |
|
|
Pierre-Yves Chibon |
7f5772 |
if git_url_ssh:
|
|
Pierre-Yves Chibon |
9c2953 |
git_urls["ssh"] = "{0}{1}.git".format(git_url_ssh, repo.fullname)
|
|
Pierre-Yves Chibon |
9c2953 |
if pagure_config.get("GIT_URL_GIT"):
|
|
Pierre-Yves Chibon |
9c2953 |
git_urls["git"] = "{0}{1}.git".format(
|
|
Pierre-Yves Chibon |
9c2953 |
pagure_config["GIT_URL_GIT"], repo.fullname
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Matt Prahl |
ad5147 |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.jsonify({"total_urls": len(git_urls), "urls": git_urls})
|
|
Matt Prahl |
ad5147 |
|
|
Matt Prahl |
ad5147 |
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<repo>/git/branches")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<namespace>/<repo>/git/branches")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<repo>/git/branches")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<namespace>/<repo>/git/branches")</repo></namespace></username>
|
|
Matt Prahl |
3114c1 |
@api_method
|
|
Matt Prahl |
cd940d |
def api_git_branches(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
9c2953 |
"""
|
|
Matt Prahl |
398dcf |
List project branches
|
|
Matt Prahl |
398dcf |
---------------------
|
|
Matt Prahl |
cd940d |
List the branches associated with a Pagure git repository
|
|
Matt Prahl |
cd940d |
|
|
Matt Prahl |
cd940d |
::
|
|
Matt Prahl |
cd940d |
|
|
Matt Prahl |
cd940d |
GET /api/0/<repo>/git/branches</repo>
|
|
Matt Prahl |
cd940d |
GET /api/0/<namespace>/<repo>/git/branches</repo></namespace>
|
|
Matt Prahl |
cd940d |
|
|
Matt Prahl |
cd940d |
::
|
|
Matt Prahl |
cd940d |
|
|
Matt Prahl |
cd940d |
GET /api/0/fork/<username>/<repo>/git/branches</repo></username>
|
|
Matt Prahl |
cd940d |
GET /api/0/fork/<username>/<namespace>/<repo>/git/branches</repo></namespace></username>
|
|
Matt Prahl |
cd940d |
|
|
Brian Stinson |
4f81f7 |
Parameters
|
|
Brian Stinson |
4f81f7 |
^^^^^^^^^^
|
|
Brian Stinson |
4f81f7 |
|
|
Brian Stinson |
4f81f7 |
+-----------------+----------+---------------+--------------------------+
|
|
Brian Stinson |
4f81f7 |
| Key | Type | Optionality | Description |
|
|
Brian Stinson |
4f81f7 |
+=================+==========+===============+==========================+
|
|
Julen Landa Alustiza |
444a82 |
| ``with_commits``| boolean | Optional | | Include the commit hash|
|
|
Brian Stinson |
4f81f7 |
| | | | corresponding to the |
|
|
Brian Stinson |
4f81f7 |
| | | | HEAD of each branch |
|
|
Brian Stinson |
4f81f7 |
+-----------------+----------+---------------+--------------------------+
|
|
Brian Stinson |
4f81f7 |
|
|
Matt Prahl |
cd940d |
Sample response
|
|
Matt Prahl |
cd940d |
^^^^^^^^^^^^^^^
|
|
Matt Prahl |
cd940d |
|
|
Matt Prahl |
cd940d |
::
|
|
Matt Prahl |
cd940d |
|
|
Matt Prahl |
cd940d |
{
|
|
Matt Prahl |
cd940d |
"total_branches": 2,
|
|
Matt Prahl |
cd940d |
"branches": ["master", "dev"]
|
|
Matt Prahl |
cd940d |
}
|
|
Matt Prahl |
cd940d |
|
|
Brian Stinson |
4f81f7 |
{
|
|
Brian Stinson |
4f81f7 |
"total_branches": 2,
|
|
Brian Stinson |
4f81f7 |
"branches": {
|
|
Brian Stinson |
4f81f7 |
"master": "16ae2a4df107658b52750063ae203f978cf02ff7",
|
|
Brian Stinson |
4f81f7 |
"dev": "8351c460167a41defc393f5b6c1d51fe1b3b82b8"
|
|
Brian Stinson |
4f81f7 |
}
|
|
Brian Stinson |
4f81f7 |
}
|
|
Brian Stinson |
4f81f7 |
|
|
Pierre-Yves Chibon |
9c2953 |
"""
|
|
Brian Stinson |
4f81f7 |
|
|
Brian Stinson |
4f81f7 |
with_commits = pagure.utils.is_true(
|
|
Brian Stinson |
4f81f7 |
flask.request.values.get("with_commits", False)
|
|
Brian Stinson |
4f81f7 |
)
|
|
Brian Stinson |
4f81f7 |
|
|
Pierre-Yves Chibon |
01d0f2 |
repo = _get_repo(repo, username, namespace)
|
|
Matt Prahl |
cd940d |
|
|
Brian Stinson |
4f81f7 |
branches = pagure.lib.git.get_git_branches(repo, with_commits=with_commits)
|
|
Matt Prahl |
cd940d |
|
|
Matt Prahl |
cd940d |
return flask.jsonify(
|
|
Pierre-Yves Chibon |
9c2953 |
{"total_branches": len(branches), "branches": branches}
|
|
Matt Prahl |
cd940d |
)
|
|
Matt Prahl |
cd940d |
|
|
Matt Prahl |
cd940d |
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/projects")
|
|
Pierre-Yves Chibon |
47269d |
@api_method
|
|
Pierre-Yves Chibon |
47269d |
def api_projects():
|
|
Pierre-Yves Chibon |
47269d |
"""
|
|
Pierre-Yves Chibon |
47269d |
List projects
|
|
Pierre-Yves Chibon |
47269d |
--------------
|
|
Pierre-Yves Chibon |
47269d |
Search projects given the specified criterias.
|
|
Pierre-Yves Chibon |
47269d |
|
|
Pierre-Yves Chibon |
47269d |
::
|
|
Pierre-Yves Chibon |
47269d |
|
|
Pierre-Yves Chibon |
47269d |
GET /api/0/projects
|
|
Pierre-Yves Chibon |
47269d |
|
|
Pierre-Yves Chibon |
47269d |
::
|
|
Pierre-Yves Chibon |
47269d |
|
|
Pierre-Yves Chibon |
47269d |
GET /api/0/projects?tags=fedora-infra
|
|
Pierre-Yves Chibon |
47269d |
|
|
Matt Prahl |
a01c25 |
::
|
|
Matt Prahl |
a01c25 |
|
|
Matt Prahl |
a01c25 |
GET /api/0/projects?page=1&per_page=50
|
|
Matt Prahl |
a01c25 |
|
|
Pierre-Yves Chibon |
47269d |
Parameters
|
|
Pierre-Yves Chibon |
47269d |
^^^^^^^^^^
|
|
Pierre-Yves Chibon |
47269d |
|
|
Pierre-Yves Chibon |
47269d |
+---------------+----------+---------------+--------------------------+
|
|
Pierre-Yves Chibon |
47269d |
| Key | Type | Optionality | Description |
|
|
Pierre-Yves Chibon |
47269d |
+===============+==========+===============+==========================+
|
|
Pierre-Yves Chibon |
47269d |
| ``tags`` | string | Optional | | Filters the projects |
|
|
Pierre-Yves Chibon |
47269d |
| | | | returned by their tags |
|
|
Pierre-Yves Chibon |
47269d |
+---------------+----------+---------------+--------------------------+
|
|
Ryan Lerch |
7c38e4 |
| ``pattern`` | string | Optional | | Filters the projects |
|
|
Ryan Lerch |
7c38e4 |
| | | | by the pattern string |
|
|
Ryan Lerch |
7c38e4 |
+---------------+----------+---------------+--------------------------+
|
|
Pierre-Yves Chibon |
47269d |
| ``username`` | string | Optional | | Filters the projects |
|
|
Pierre-Yves Chibon |
47269d |
| | | | returned by the users |
|
|
Pierre-Yves Chibon |
47269d |
| | | | having commit rights |
|
|
Pierre-Yves Chibon |
47269d |
| | | | to it |
|
|
Pierre-Yves Chibon |
47269d |
+---------------+----------+---------------+--------------------------+
|
|
Matt Prahl |
7403a2 |
| ``owner`` | string | Optional | | Filters the projects |
|
|
Pierre-Yves Chibon |
6dc7c9 |
| | | | by ownership. |
|
|
Pierre-Yves Chibon |
6dc7c9 |
| | | | If the argument is of |
|
|
Pierre-Yves Chibon |
6dc7c9 |
| | | | the form then |
|
|
Pierre-Yves Chibon |
6dc7c9 |
| | | | the project returned |
|
|
Pierre-Yves Chibon |
6dc7c9 |
| | | | are the ones *not* |
|
|
Pierre-Yves Chibon |
6dc7c9 |
| | | | owned by this user. |
|
|
Matt Prahl |
7403a2 |
+---------------+----------+---------------+--------------------------+
|
|
Matt Prahl |
6c3d54 |
| ``namespace`` | string | Optional | | Filters the projects |
|
|
Matt Prahl |
6c3d54 |
| | | | by namespace |
|
|
Matt Prahl |
6c3d54 |
+---------------+----------+---------------+--------------------------+
|
|
Pierre-Yves Chibon |
47269d |
| ``fork`` | boolean | Optional | | Filters the projects |
|
|
Pierre-Yves Chibon |
47269d |
| | | | returned depending if |
|
|
Pierre-Yves Chibon |
47269d |
| | | | they are forks or not |
|
|
Pierre-Yves Chibon |
47269d |
+---------------+----------+---------------+--------------------------+
|
|
Pierre-Yves Chibon |
1ca90b |
| ``short`` | boolean | Optional | | Whether to return the |
|
|
Pierre-Yves Chibon |
1ca90b |
| | | | entrie project JSON |
|
|
Pierre-Yves Chibon |
1ca90b |
| | | | or just a sub-set |
|
|
Pierre-Yves Chibon |
1ca90b |
+---------------+----------+---------------+--------------------------+
|
|
Karsten Hopp |
a5d5f1 |
| ``page`` | int | Optional | | Specifies which |
|
|
Karsten Hopp |
a5d5f1 |
| | | | page to return |
|
|
Karsten Hopp |
a5d5f1 |
| | | | (defaults to: 1) |
|
|
Matt Prahl |
a01c25 |
+---------------+----------+---------------+--------------------------+
|
|
Matt Prahl |
a01c25 |
| ``per_page`` | int | Optional | | The number of projects |
|
|
Matt Prahl |
a01c25 |
| | | | to return per page. |
|
|
Matt Prahl |
a01c25 |
| | | | The maximum is 100. |
|
|
Matt Prahl |
a01c25 |
+---------------+----------+---------------+--------------------------+
|
|
Pierre-Yves Chibon |
47269d |
|
|
Pierre-Yves Chibon |
47269d |
Sample response
|
|
Pierre-Yves Chibon |
47269d |
^^^^^^^^^^^^^^^
|
|
Pierre-Yves Chibon |
47269d |
|
|
Pierre-Yves Chibon |
47269d |
::
|
|
Pierre-Yves Chibon |
47269d |
|
|
Pierre-Yves Chibon |
47269d |
{
|
|
Matt Prahl |
a01c25 |
"args": {
|
|
Matt Prahl |
a01c25 |
"fork": null,
|
|
Matt Prahl |
a01c25 |
"namespace": null,
|
|
Matt Prahl |
a01c25 |
"owner": null,
|
|
Matt Prahl |
a01c25 |
"page": 1,
|
|
Matt Prahl |
a01c25 |
"pattern": null,
|
|
Matt Prahl |
a01c25 |
"per_page": 2,
|
|
Matt Prahl |
a01c25 |
"short": false,
|
|
Matt Prahl |
a01c25 |
"tags": [],
|
|
Matt Prahl |
a01c25 |
"username": null
|
|
Matt Prahl |
a01c25 |
},
|
|
Matt Prahl |
a01c25 |
"pagination": {
|
|
Matt Prahl |
a01c25 |
"first": "http://127.0.0.1:5000/api/0/projects?per_page=2&page=1",
|
|
Matt Prahl |
a01c25 |
"last": "http://127.0.0.1:5000/api/0/projects?per_page=2&page=500",
|
|
Matt Prahl |
a01c25 |
"next": "http://127.0.0.1:5000/api/0/projects?per_page=2&page=2",
|
|
Matt Prahl |
a01c25 |
"page": 1,
|
|
Matt Prahl |
a01c25 |
"pages": 500,
|
|
Matt Prahl |
a01c25 |
"per_page": 2,
|
|
Matt Prahl |
a01c25 |
"prev": null
|
|
Matt Prahl |
a01c25 |
},
|
|
Matt Prahl |
a01c25 |
"projects": [
|
|
Matt Prahl |
a01c25 |
{
|
|
Matt Prahl |
a01c25 |
"access_groups": {
|
|
Matt Prahl |
a01c25 |
"admin": [],
|
|
Matt Prahl |
a01c25 |
"commit": [],
|
|
Matt Prahl |
a01c25 |
"ticket": []
|
|
Matt Prahl |
a01c25 |
},
|
|
Matt Prahl |
a01c25 |
"access_users": {
|
|
Matt Prahl |
a01c25 |
"admin": [],
|
|
Matt Prahl |
a01c25 |
"commit": [],
|
|
Matt Prahl |
a01c25 |
"owner": [
|
|
Matt Prahl |
a01c25 |
"mprahl"
|
|
Matt Prahl |
a01c25 |
],
|
|
Matt Prahl |
a01c25 |
"ticket": []
|
|
Matt Prahl |
a01c25 |
},
|
|
Matt Prahl |
a01c25 |
"close_status": [],
|
|
Matt Prahl |
a01c25 |
"custom_keys": [],
|
|
Matt Prahl |
a01c25 |
"date_created": "1498841289",
|
|
Matt Prahl |
a01c25 |
"description": "test1",
|
|
Matt Prahl |
a01c25 |
"fullname": "test1",
|
|
Matt Prahl |
a01c25 |
"id": 1,
|
|
Matt Prahl |
a01c25 |
"milestones": {},
|
|
Matt Prahl |
a01c25 |
"name": "test1",
|
|
Matt Prahl |
a01c25 |
"namespace": null,
|
|
Matt Prahl |
a01c25 |
"parent": null,
|
|
Matt Prahl |
a01c25 |
"priorities": {},
|
|
Matt Prahl |
a01c25 |
"tags": [],
|
|
Karsten Hopp |
46ce34 |
"url_path": "test1",
|
|
Matt Prahl |
a01c25 |
"user": {
|
|
Matt Prahl |
a01c25 |
"fullname": "Matt Prahl",
|
|
Matt Prahl |
a01c25 |
"name": "mprahl"
|
|
Matt Prahl |
a01c25 |
}
|
|
Matt Prahl |
a01c25 |
},
|
|
Matt Prahl |
a01c25 |
{
|
|
Matt Prahl |
a01c25 |
"access_groups": {
|
|
Matt Prahl |
a01c25 |
"admin": [],
|
|
Matt Prahl |
a01c25 |
"commit": [],
|
|
Matt Prahl |
a01c25 |
"ticket": []
|
|
Matt Prahl |
a01c25 |
},
|
|
Matt Prahl |
a01c25 |
"access_users": {
|
|
Matt Prahl |
a01c25 |
"admin": [],
|
|
Matt Prahl |
a01c25 |
"commit": [],
|
|
Matt Prahl |
a01c25 |
"owner": [
|
|
Matt Prahl |
a01c25 |
"mprahl"
|
|
Matt Prahl |
a01c25 |
],
|
|
Matt Prahl |
a01c25 |
"ticket": []
|
|
Matt Prahl |
a01c25 |
},
|
|
Matt Prahl |
a01c25 |
"close_status": [],
|
|
Matt Prahl |
a01c25 |
"custom_keys": [],
|
|
Matt Prahl |
a01c25 |
"date_created": "1499795310",
|
|
Matt Prahl |
a01c25 |
"description": "test2",
|
|
Matt Prahl |
a01c25 |
"fullname": "test2",
|
|
Matt Prahl |
a01c25 |
"id": 2,
|
|
Matt Prahl |
a01c25 |
"milestones": {},
|
|
Matt Prahl |
a01c25 |
"name": "test2",
|
|
Matt Prahl |
a01c25 |
"namespace": null,
|
|
Matt Prahl |
a01c25 |
"parent": null,
|
|
Matt Prahl |
a01c25 |
"priorities": {},
|
|
Matt Prahl |
a01c25 |
"tags": [],
|
|
Karsten Hopp |
46ce34 |
"url_path": "test2",
|
|
Matt Prahl |
a01c25 |
"user": {
|
|
Matt Prahl |
a01c25 |
"fullname": "Matt Prahl",
|
|
Matt Prahl |
a01c25 |
"name": "mprahl"
|
|
Matt Prahl |
a01c25 |
}
|
|
Matt Prahl |
a01c25 |
}
|
|
Matt Prahl |
a01c25 |
],
|
|
Matt Prahl |
a01c25 |
"total_projects": 1000
|
|
Matt Prahl |
a01c25 |
}
|
|
Pierre-Yves Chibon |
47269d |
"""
|
|
Pierre-Yves Chibon |
9c2953 |
tags = flask.request.values.getlist("tags")
|
|
Pierre-Yves Chibon |
9c2953 |
username = flask.request.values.get("username", None)
|
|
Pierre-Yves Chibon |
9c2953 |
fork = flask.request.values.get("fork", None)
|
|
Pierre-Yves Chibon |
9c2953 |
namespace = flask.request.values.get("namespace", None)
|
|
Pierre-Yves Chibon |
9c2953 |
owner = flask.request.values.get("owner", None)
|
|
Pierre-Yves Chibon |
9c2953 |
pattern = flask.request.values.get("pattern", None)
|
|
Pierre-Yves Chibon |
9c2953 |
short = pagure.utils.is_true(flask.request.values.get("short", False))
|
|
Pierre-Yves Chibon |
47269d |
|
|
Aurélien Bompard |
619e2a |
if fork is not None:
|
|
Aurélien Bompard |
619e2a |
fork = pagure.utils.is_true(fork)
|
|
Pierre-Yves Chibon |
47269d |
|
|
farhaanbukhsh |
7ca1b1 |
private = False
|
|
Pierre-Yves Chibon |
9c2953 |
if pagure.utils.authenticated() and username == flask.g.fas_user.username:
|
|
farhaanbukhsh |
7ca1b1 |
private = flask.g.fas_user.username
|
|
farhaanbukhsh |
7ca1b1 |
|
|
Pierre-Yves Chibon |
930073 |
project_count = pagure.lib.query.search_projects(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
fork=fork,
|
|
Pierre-Yves Chibon |
9c2953 |
tags=tags,
|
|
Pierre-Yves Chibon |
9c2953 |
pattern=pattern,
|
|
Pierre-Yves Chibon |
9c2953 |
private=private,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
owner=owner,
|
|
Pierre-Yves Chibon |
9c2953 |
count=True,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Karsten Hopp |
a5d5f1 |
|
|
Pierre-Yves Chibon |
90cfb8 |
# Pagination code inspired by Flask-SQLAlchemy
|
|
Pierre-Yves Chibon |
90cfb8 |
page = get_page()
|
|
Pierre-Yves Chibon |
90cfb8 |
per_page = get_per_page()
|
|
Pierre-Yves Chibon |
930073 |
pagination_metadata = pagure.lib.query.get_pagination_metadata(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.request, page, per_page, project_count
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Karsten Hopp |
a5d5f1 |
query_start = (page - 1) * per_page
|
|
Karsten Hopp |
a5d5f1 |
query_limit = per_page
|
|
Matt Prahl |
a01c25 |
|
|
Pierre-Yves Chibon |
930073 |
projects = pagure.lib.query.search_projects(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session,
|
|
Pierre-Yves Chibon |
9c2953 |
username=username,
|
|
Pierre-Yves Chibon |
9c2953 |
fork=fork,
|
|
Pierre-Yves Chibon |
9c2953 |
tags=tags,
|
|
Pierre-Yves Chibon |
9c2953 |
pattern=pattern,
|
|
Pierre-Yves Chibon |
9c2953 |
private=private,
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
owner=owner,
|
|
Pierre-Yves Chibon |
9c2953 |
limit=query_limit,
|
|
Pierre-Yves Chibon |
9c2953 |
start=query_start,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
47269d |
|
|
Vivek Anand |
dfe82f |
# prepare the output json
|
|
Vivek Anand |
dfe82f |
jsonout = {
|
|
Pierre-Yves Chibon |
9c2953 |
"total_projects": project_count,
|
|
Pierre-Yves Chibon |
9c2953 |
"projects": projects,
|
|
Pierre-Yves Chibon |
9c2953 |
"args": {
|
|
Pierre-Yves Chibon |
9c2953 |
"tags": tags,
|
|
Pierre-Yves Chibon |
9c2953 |
"username": username,
|
|
Pierre-Yves Chibon |
9c2953 |
"fork": fork,
|
|
Pierre-Yves Chibon |
9c2953 |
"pattern": pattern,
|
|
Pierre-Yves Chibon |
9c2953 |
"namespace": namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
"owner": owner,
|
|
Pierre-Yves Chibon |
9c2953 |
"short": short,
|
|
Pierre-Yves Chibon |
9c2953 |
},
|
|
Vivek Anand |
dfe82f |
}
|
|
Pierre-Yves Chibon |
47269d |
|
|
Pierre-Yves Chibon |
1ca90b |
if not short:
|
|
Pierre-Yves Chibon |
1ca90b |
projects = [p.to_json(api=True, public=True) for p in projects]
|
|
Pierre-Yves Chibon |
1ca90b |
else:
|
|
Pierre-Yves Chibon |
1ca90b |
projects = [
|
|
Pierre-Yves Chibon |
1ca90b |
{
|
|
Pierre-Yves Chibon |
9c2953 |
"name": p.name,
|
|
Pierre-Yves Chibon |
9c2953 |
"namespace": p.namespace,
|
|
Pierre-Yves Chibon |
9c2953 |
"fullname": p.fullname.replace("forks/", "fork/", 1)
|
|
Pierre-Yves Chibon |
9c2953 |
if p.fullname.startswith("forks/")
|
|
Pierre-Yves Chibon |
9c2953 |
else p.fullname,
|
|
Pierre-Yves Chibon |
9c2953 |
"description": p.description,
|
|
Pierre-Yves Chibon |
1ca90b |
}
|
|
Pierre-Yves Chibon |
1ca90b |
for p in projects
|
|
Pierre-Yves Chibon |
1ca90b |
]
|
|
Pierre-Yves Chibon |
1ca90b |
|
|
Pierre-Yves Chibon |
9c2953 |
jsonout["projects"] = projects
|
|
Matt Prahl |
a01c25 |
if pagination_metadata:
|
|
Pierre-Yves Chibon |
9c2953 |
jsonout["args"]["page"] = page
|
|
Pierre-Yves Chibon |
9c2953 |
jsonout["args"]["per_page"] = per_page
|
|
Pierre-Yves Chibon |
9c2953 |
jsonout["pagination"] = pagination_metadata
|
|
Matt Prahl |
a01c25 |
return flask.jsonify(jsonout)
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<repo>")</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<namespace>/<repo>")</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<repo>")</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<namespace>/<repo>")</repo></namespace></username>
|
|
Pierre-Yves Chibon |
b42ba1 |
@api_method
|
|
Pierre-Yves Chibon |
b42ba1 |
def api_project(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
b42ba1 |
"""
|
|
Pierre-Yves Chibon |
b42ba1 |
Project information
|
|
Pierre-Yves Chibon |
b42ba1 |
-------------------
|
|
Pierre-Yves Chibon |
b42ba1 |
Return information about a specific project
|
|
Pierre-Yves Chibon |
b42ba1 |
|
|
Pierre-Yves Chibon |
b42ba1 |
::
|
|
Pierre-Yves Chibon |
b42ba1 |
|
|
Pierre-Yves Chibon |
b42ba1 |
GET /api/0/<repo></repo>
|
|
Pierre-Yves Chibon |
b42ba1 |
GET /api/0/<namespace>/<repo></repo></namespace>
|
|
Pierre-Yves Chibon |
b42ba1 |
|
|
Pierre-Yves Chibon |
b42ba1 |
::
|
|
Pierre-Yves Chibon |
b42ba1 |
|
|
Pierre-Yves Chibon |
b42ba1 |
GET /api/0/fork/<username>/<repo></repo></username>
|
|
Pierre-Yves Chibon |
b42ba1 |
GET /api/0/fork/<username>/<namespace>/<repo></repo></namespace></username>
|
|
Pierre-Yves Chibon |
b42ba1 |
|
|
Pierre-Yves Chibon |
b42ba1 |
Sample response
|
|
Pierre-Yves Chibon |
b42ba1 |
^^^^^^^^^^^^^^^
|
|
Pierre-Yves Chibon |
b42ba1 |
|
|
Pierre-Yves Chibon |
b42ba1 |
::
|
|
Pierre-Yves Chibon |
b42ba1 |
|
|
Pierre-Yves Chibon |
b42ba1 |
{
|
|
Pierre-Yves Chibon |
b6f024 |
"access_groups": {
|
|
Pierre-Yves Chibon |
b6f024 |
"admin": [],
|
|
Pierre-Yves Chibon |
b6f024 |
"commit": [],
|
|
Pierre-Yves Chibon |
b6f024 |
"ticket": []
|
|
Pierre-Yves Chibon |
b6f024 |
},
|
|
Pierre-Yves Chibon |
b6f024 |
"access_users": {
|
|
Pierre-Yves Chibon |
b6f024 |
"admin": [
|
|
Pierre-Yves Chibon |
b6f024 |
"ryanlerch"
|
|
Pierre-Yves Chibon |
b6f024 |
],
|
|
Pierre-Yves Chibon |
b6f024 |
"commit": [
|
|
Pierre-Yves Chibon |
b6f024 |
"puiterwijk"
|
|
Pierre-Yves Chibon |
b6f024 |
],
|
|
Pierre-Yves Chibon |
b6f024 |
"owner": [
|
|
Pierre-Yves Chibon |
b6f024 |
"pingou"
|
|
Pierre-Yves Chibon |
b6f024 |
],
|
|
Pierre-Yves Chibon |
b6f024 |
"ticket": [
|
|
Pierre-Yves Chibon |
b6f024 |
"vivekanand1101",
|
|
Pierre-Yves Chibon |
b6f024 |
"mprahl",
|
|
Pierre-Yves Chibon |
b6f024 |
"jcline",
|
|
Pierre-Yves Chibon |
b6f024 |
"lslebodn",
|
|
Pierre-Yves Chibon |
b6f024 |
"cverna",
|
|
Pierre-Yves Chibon |
b6f024 |
"farhaan"
|
|
Pierre-Yves Chibon |
b6f024 |
]
|
|
Pierre-Yves Chibon |
b6f024 |
},
|
|
Pierre-Yves Chibon |
b6f024 |
"close_status": [
|
|
Pierre-Yves Chibon |
b6f024 |
"Invalid",
|
|
Pierre-Yves Chibon |
b6f024 |
"Insufficient data",
|
|
Pierre-Yves Chibon |
b6f024 |
"Fixed",
|
|
Pierre-Yves Chibon |
b6f024 |
"Duplicate"
|
|
Pierre-Yves Chibon |
b6f024 |
],
|
|
Pierre-Yves Chibon |
b6f024 |
"custom_keys": [],
|
|
Pierre-Yves Chibon |
b6f024 |
"date_created": "1431549490",
|
|
Pierre-Yves Chibon |
b6f024 |
"date_modified": "1431549490",
|
|
Pierre-Yves Chibon |
b6f024 |
"description": "A git centered forge",
|
|
Pierre-Yves Chibon |
b6f024 |
"fullname": "pagure",
|
|
Pierre-Yves Chibon |
b6f024 |
"id": 10,
|
|
Pierre-Yves Chibon |
b6f024 |
"milestones": {},
|
|
Pierre-Yves Chibon |
b6f024 |
"name": "pagure",
|
|
Pierre-Yves Chibon |
b6f024 |
"namespace": null,
|
|
Pierre-Yves Chibon |
b6f024 |
"parent": null,
|
|
Pierre-Yves Chibon |
b6f024 |
"priorities": {},
|
|
Pierre-Yves Chibon |
b6f024 |
"tags": [
|
|
Pierre-Yves Chibon |
b6f024 |
"pagure",
|
|
Pierre-Yves Chibon |
b6f024 |
"fedmsg"
|
|
Pierre-Yves Chibon |
b6f024 |
],
|
|
Pierre-Yves Chibon |
b6f024 |
"user": {
|
|
Pierre-Yves Chibon |
b6f024 |
"fullname": "Pierre-YvesChibon",
|
|
Pierre-Yves Chibon |
b6f024 |
"name": "pingou"
|
|
Pierre-Yves Chibon |
b6f024 |
}
|
|
Pierre-Yves Chibon |
b42ba1 |
}
|
|
Pierre-Yves Chibon |
b42ba1 |
|
|
Pierre-Yves Chibon |
b42ba1 |
"""
|
|
Pierre-Yves Chibon |
01d0f2 |
repo = _get_repo(repo, username, namespace)
|
|
Pierre-Yves Chibon |
b42ba1 |
|
|
Aurélien Bompard |
619e2a |
expand_group = pagure.utils.is_true(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.request.values.get("expand_group", False)
|
|
Aurélien Bompard |
619e2a |
)
|
|
Pierre-Yves Chibon |
fd3701 |
|
|
Pierre-Yves Chibon |
fd3701 |
output = repo.to_json(api=True, public=True)
|
|
Pierre-Yves Chibon |
fd3701 |
|
|
Pierre-Yves Chibon |
fd3701 |
if expand_group:
|
|
Pierre-Yves Chibon |
fd3701 |
group_details = {}
|
|
Pierre-Yves Chibon |
fd3701 |
for grp in repo.projects_groups:
|
|
Pierre-Yves Chibon |
fd3701 |
group_details[grp.group.group_name] = [
|
|
Pierre-Yves Chibon |
9c2953 |
user.username for user in grp.group.users
|
|
Pierre-Yves Chibon |
9c2953 |
]
|
|
Pierre-Yves Chibon |
9c2953 |
output["group_details"] = group_details
|
|
Pierre-Yves Chibon |
fd3701 |
|
|
Pierre-Yves Chibon |
fd3701 |
jsonout = flask.jsonify(output)
|
|
Pierre-Yves Chibon |
b42ba1 |
return jsonout
|
|
Pierre-Yves Chibon |
b42ba1 |
|
|
Pierre-Yves Chibon |
b42ba1 |
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/new/", methods=["POST"])
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/new", methods=["POST"])
|
|
Pierre-Yves Chibon |
9c2953 |
@api_login_required(acls=["create_project"])
|
|
Pierre-Yves Chibon |
9f9b1e |
@api_method
|
|
Pierre-Yves Chibon |
9f9b1e |
def api_new_project():
|
|
Pierre-Yves Chibon |
9f9b1e |
"""
|
|
Pierre-Yves Chibon |
9f9b1e |
Create a new project
|
|
Pierre-Yves Chibon |
9f9b1e |
--------------------
|
|
Pierre-Yves Chibon |
9f9b1e |
Create a new project on this pagure instance.
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Patrick Uiterwijk |
bb08fb |
This is an asynchronous call.
|
|
Patrick Uiterwijk |
bb08fb |
|
|
Pierre-Yves Chibon |
9f9b1e |
::
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Matt Prahl |
e7ba58 |
POST /api/0/new
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Pierre-Yves Chibon |
9f9b1e |
Input
|
|
Pierre-Yves Chibon |
9f9b1e |
^^^^^
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Pierre-Yves Chibon |
bdc553 |
+----------------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
bdc553 |
| Key | Type | Optionality | Description |
|
|
Pierre-Yves Chibon |
bdc553 |
+============================+=========+==============+===========================+
|
|
Pierre-Yves Chibon |
bdc553 |
| ``name`` | string | Mandatory | | The name of the new |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | project. |
|
|
Pierre-Yves Chibon |
bdc553 |
+----------------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
bdc553 |
| ``description`` | string | Mandatory | | A short description of |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | the new project. |
|
|
Pierre-Yves Chibon |
bdc553 |
+----------------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
bdc553 |
| ``namespace`` | string | Optional | | The namespace of the |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | project to fork. |
|
|
Pierre-Yves Chibon |
bdc553 |
+----------------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
bdc553 |
| ``url`` | string | Optional | | An url providing more |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | information about the |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | project. |
|
|
Pierre-Yves Chibon |
bdc553 |
+----------------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
bdc553 |
| ``avatar_email`` | string | Optional | | An email address for the|
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | avatar of the project. |
|
|
Pierre-Yves Chibon |
bdc553 |
+----------------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
bdc553 |
| ``create_readme`` | boolean | Optional | | A boolean to specify if |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | there should be a readme|
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | added to the project on |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | creation. |
|
|
Pierre-Yves Chibon |
bdc553 |
+----------------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
bdc553 |
| ``private`` | boolean | Optional | | A boolean to specify if |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | the project to create |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | is private. |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | Note: not all pagure |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | instance support private|
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | projects, confirm this |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | with your administrators|
|
|
Pierre-Yves Chibon |
bdc553 |
+----------------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
bdc553 |
| ``ignore_existing_repos`` | boolean | Optional | | Only available to admins|
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | this option allows them |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | to make project creation|
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | pass even if there is |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | already a coresopnding |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | git repository on disk |
|
|
Pierre-Yves Chibon |
bdc553 |
+----------------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
bdc553 |
| ``repospanner_region`` | boolean | Optional | | Only available to admins|
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | this option allows them |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | to override the default |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | respoSpanner region |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | configured |
|
|
Pierre-Yves Chibon |
bdc553 |
+----------------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
bdc553 |
| ``wait`` | boolean | Optional | | A boolean to specify if |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | this API call should |
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | return a taskid or if it|
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | should wait for the task|
|
|
Pierre-Yves Chibon |
bdc553 |
| | | | to finish. |
|
|
Pierre-Yves Chibon |
bdc553 |
+----------------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Pierre-Yves Chibon |
9f9b1e |
Sample response
|
|
Pierre-Yves Chibon |
9f9b1e |
^^^^^^^^^^^^^^^
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Pierre-Yves Chibon |
9f9b1e |
::
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Patrick Uiterwijk |
0281ff |
wait=False:
|
|
Pierre-Yves Chibon |
9f9b1e |
{
|
|
Patrick Uiterwijk |
bb08fb |
'message': 'Project creation queued',
|
|
Patrick Uiterwijk |
bb08fb |
'taskid': '123-abcd'
|
|
Pierre-Yves Chibon |
9f9b1e |
}
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Patrick Uiterwijk |
0281ff |
wait=True:
|
|
Patrick Uiterwijk |
0281ff |
{
|
|
Patrick Uiterwijk |
0281ff |
'message': 'Project creation queued'
|
|
Patrick Uiterwijk |
0281ff |
}
|
|
Patrick Uiterwijk |
0281ff |
|
|
Pierre-Yves Chibon |
bdc553 |
""" # noqa
|
|
Pierre-Yves Chibon |
930073 |
user = pagure.lib.query.search_user(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, username=flask.g.fas_user.username
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9f9b1e |
output = {}
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Pierre-Yves Chibon |
9c2953 |
if not pagure_config.get("ENABLE_NEW_PROJECTS", True):
|
|
Pierre-Yves Chibon |
9f9b1e |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
404, error_code=APIERROR.ENEWPROJECTDISABLED
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Pierre-Yves Chibon |
9c2953 |
namespaces = pagure_config["ALLOWED_PREFIX"][:]
|
|
Pierre-Yves Chibon |
a5c678 |
if user:
|
|
Pierre-Yves Chibon |
a5c678 |
namespaces.extend([grp for grp in user.groups])
|
|
Pierre-Yves Chibon |
a5c678 |
|
|
Pierre-Yves Chibon |
9c2953 |
form = pagure.forms.ProjectForm(namespaces=namespaces, csrf_enabled=False)
|
|
Pierre-Yves Chibon |
9f9b1e |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
9f9b1e |
name = form.name.data
|
|
Pierre-Yves Chibon |
9f9b1e |
description = form.description.data
|
|
Pierre-Yves Chibon |
fe2a31 |
namespace = form.namespace.data
|
|
Pierre-Yves Chibon |
9f9b1e |
url = form.url.data
|
|
Pierre-Yves Chibon |
9f9b1e |
avatar_email = form.avatar_email.data
|
|
Pierre-Yves Chibon |
9f9b1e |
create_readme = form.create_readme.data
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Pierre-Yves Chibon |
3175b1 |
if namespace:
|
|
Pierre-Yves Chibon |
3175b1 |
namespace = namespace.strip()
|
|
Pierre-Yves Chibon |
3175b1 |
|
|
Pierre-Yves Chibon |
3a7944 |
private = False
|
|
Pierre-Yves Chibon |
9c2953 |
if pagure_config.get("PRIVATE_PROJECTS", False):
|
|
Pierre-Yves Chibon |
3a7944 |
private = form.private.data
|
|
Patrick Uiterwijk |
3f97f6 |
if form.repospanner_region:
|
|
Patrick Uiterwijk |
3f97f6 |
repospanner_region = form.repospanner_region.data
|
|
Patrick Uiterwijk |
3f97f6 |
else:
|
|
Patrick Uiterwijk |
3f97f6 |
repospanner_region = None
|
|
Pierre-Yves Chibon |
7cc66f |
if form.ignore_existing_repos:
|
|
Pierre-Yves Chibon |
7cc66f |
ignore_existing_repos = form.ignore_existing_repos.data
|
|
Pierre-Yves Chibon |
7cc66f |
else:
|
|
Pierre-Yves Chibon |
7cc66f |
ignore_existing_repos = False
|
|
Pierre-Yves Chibon |
3a7944 |
|
|
Pierre-Yves Chibon |
9f9b1e |
try:
|
|
Pierre-Yves Chibon |
930073 |
task = pagure.lib.query.new_project(
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session,
|
|
Pierre-Yves Chibon |
9f9b1e |
name=name,
|
|
Pierre-Yves Chibon |
34ece4 |
namespace=namespace,
|
|
Patrick Uiterwijk |
3f97f6 |
repospanner_region=repospanner_region,
|
|
Pierre-Yves Chibon |
7cc66f |
ignore_existing_repo=ignore_existing_repos,
|
|
Pierre-Yves Chibon |
9f9b1e |
description=description,
|
|
Pierre-Yves Chibon |
3a7944 |
private=private,
|
|
Pierre-Yves Chibon |
9f9b1e |
url=url,
|
|
Pierre-Yves Chibon |
9f9b1e |
avatar_email=avatar_email,
|
|
Pierre-Yves Chibon |
9f9b1e |
user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
9c2953 |
blacklist=pagure_config["BLACKLISTED_PROJECTS"],
|
|
Pierre-Yves Chibon |
9c2953 |
allowed_prefix=pagure_config["ALLOWED_PREFIX"],
|
|
Pierre-Yves Chibon |
9f9b1e |
add_readme=create_readme,
|
|
Pierre-Yves Chibon |
9f9b1e |
userobj=user,
|
|
Pierre-Yves Chibon |
b130e5 |
prevent_40_chars=pagure_config.get(
|
|
Pierre-Yves Chibon |
9c2953 |
"OLD_VIEW_COMMIT_ENABLED", False
|
|
Pierre-Yves Chibon |
9c2953 |
),
|
|
Pierre-Yves Chibon |
9c2953 |
user_ns=pagure_config.get("USER_NAMESPACE", False),
|
|
Pierre-Yves Chibon |
9f9b1e |
)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
9c2953 |
output = {"message": "Project creation queued", "taskid": task.id}
|
|
Patrick Uiterwijk |
0281ff |
|
|
Pierre-Yves Chibon |
9c2953 |
if get_request_data().get("wait", True):
|
|
Aurélien Bompard |
a7f281 |
result = task.get()
|
|
Pierre-Yves Chibon |
930073 |
project = pagure.lib.query._get_project(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session,
|
|
Pierre-Yves Chibon |
9c2953 |
name=result["repo"],
|
|
Pierre-Yves Chibon |
9c2953 |
namespace=result["namespace"],
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
output = {"message": 'Project "%s" created' % project.fullname}
|
|
Pierre-Yves Chibon |
9f9b1e |
except pagure.exceptions.PagureException as err:
|
|
Pierre-Yves Chibon |
9f9b1e |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
400, error_code=APIERROR.ENOCODE, error=str(err)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9f9b1e |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
_log.exception(err)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
9f9b1e |
raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)
|
|
Pierre-Yves Chibon |
9f9b1e |
else:
|
|
Pierre-Yves Chibon |
f7fcaa |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
400, error_code=APIERROR.EINVALIDREQ, errors=form.errors
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9f9b1e |
|
|
Pierre-Yves Chibon |
9f9b1e |
jsonout = flask.jsonify(output)
|
|
Pierre-Yves Chibon |
9f9b1e |
return jsonout
|
|
Pierre-Yves Chibon |
dc21df |
|
|
Pierre-Yves Chibon |
dc21df |
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<repo>", methods=["PATCH"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<namespace>/<repo>", methods=["PATCH"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@api_login_required(acls=["modify_project"])
|
|
Matt Prahl |
30f8b1 |
@api_method
|
|
Matt Prahl |
30f8b1 |
def api_modify_project(repo, namespace=None):
|
|
Matt Prahl |
30f8b1 |
"""
|
|
Matt Prahl |
30f8b1 |
Modify a project
|
|
Matt Prahl |
30f8b1 |
----------------
|
|
Matt Prahl |
30f8b1 |
Modify an existing project on this Pagure instance.
|
|
Matt Prahl |
30f8b1 |
|
|
Matt Prahl |
30f8b1 |
::
|
|
Matt Prahl |
30f8b1 |
|
|
Matt Prahl |
30f8b1 |
PATCH /api/0/<repo></repo>
|
|
Matt Prahl |
30f8b1 |
|
|
Matt Prahl |
30f8b1 |
|
|
Matt Prahl |
30f8b1 |
Input
|
|
Matt Prahl |
30f8b1 |
^^^^^
|
|
Matt Prahl |
30f8b1 |
|
|
Matt Prahl |
30f8b1 |
+------------------+---------+--------------+---------------------------+
|
|
Matt Prahl |
30f8b1 |
| Key | Type | Optionality | Description |
|
|
Matt Prahl |
30f8b1 |
+==================+=========+==============+===========================+
|
|
Matt Prahl |
30f8b1 |
| ``main_admin`` | string | Mandatory | | The new main admin of |
|
|
Matt Prahl |
30f8b1 |
| | | | the project. |
|
|
Matt Prahl |
30f8b1 |
+------------------+---------+--------------+---------------------------+
|
|
mprahl |
8f40ee |
| ``retain_access``| string | Optional | | The old main admin |
|
|
mprahl |
8f40ee |
| | | | retains access on the |
|
|
mprahl |
8f40ee |
| | | | project when giving the |
|
|
mprahl |
8f40ee |
| | | | project. Defaults to |
|
|
mprahl |
8f40ee |
| | | | ``False``. |
|
|
mprahl |
8f40ee |
+------------------+---------+--------------+---------------------------+
|
|
Matt Prahl |
30f8b1 |
|
|
Matt Prahl |
30f8b1 |
Sample response
|
|
Matt Prahl |
30f8b1 |
^^^^^^^^^^^^^^^
|
|
Matt Prahl |
30f8b1 |
|
|
Matt Prahl |
30f8b1 |
::
|
|
Matt Prahl |
30f8b1 |
|
|
Matt Prahl |
30f8b1 |
{
|
|
Matt Prahl |
30f8b1 |
"access_groups": {
|
|
Matt Prahl |
30f8b1 |
"admin": [],
|
|
Matt Prahl |
30f8b1 |
"commit": [],
|
|
Matt Prahl |
30f8b1 |
"ticket": []
|
|
Matt Prahl |
30f8b1 |
},
|
|
Matt Prahl |
30f8b1 |
"access_users": {
|
|
Matt Prahl |
30f8b1 |
"admin": [],
|
|
Matt Prahl |
30f8b1 |
"commit": [],
|
|
Matt Prahl |
30f8b1 |
"owner": [
|
|
Matt Prahl |
30f8b1 |
"testuser1"
|
|
Matt Prahl |
30f8b1 |
],
|
|
Matt Prahl |
30f8b1 |
"ticket": []
|
|
Matt Prahl |
30f8b1 |
},
|
|
Matt Prahl |
30f8b1 |
"close_status": [],
|
|
Matt Prahl |
30f8b1 |
"custom_keys": [],
|
|
Matt Prahl |
30f8b1 |
"date_created": "1496326387",
|
|
Matt Prahl |
30f8b1 |
"description": "Test",
|
|
Matt Prahl |
30f8b1 |
"fullname": "test-project2",
|
|
Matt Prahl |
30f8b1 |
"id": 2,
|
|
Matt Prahl |
30f8b1 |
"milestones": {},
|
|
Matt Prahl |
30f8b1 |
"name": "test-project2",
|
|
Matt Prahl |
30f8b1 |
"namespace": null,
|
|
Matt Prahl |
30f8b1 |
"parent": null,
|
|
Matt Prahl |
30f8b1 |
"priorities": {},
|
|
Matt Prahl |
30f8b1 |
"tags": [],
|
|
Matt Prahl |
30f8b1 |
"user": {
|
|
Matt Prahl |
30f8b1 |
"default_email": "testuser1@domain.local",
|
|
Matt Prahl |
30f8b1 |
"emails": [],
|
|
Matt Prahl |
30f8b1 |
"fullname": "Test User1",
|
|
Matt Prahl |
30f8b1 |
"name": "testuser1"
|
|
Matt Prahl |
30f8b1 |
}
|
|
Matt Prahl |
30f8b1 |
}
|
|
Matt Prahl |
30f8b1 |
|
|
Matt Prahl |
30f8b1 |
"""
|
|
Pierre-Yves Chibon |
01d0f2 |
project = _get_repo(repo, namespace=namespace)
|
|
Pierre-Yves Chibon |
01d0f2 |
_check_token(project, project_token=False)
|
|
Pierre-Yves Chibon |
e99858 |
|
|
Pierre-Yves Chibon |
b130e5 |
is_site_admin = pagure.utils.is_admin()
|
|
Pierre-Yves Chibon |
9c2953 |
admins = [u.username for u in project.get_project_users("admin")]
|
|
Matt Prahl |
ab0f46 |
# Only allow the main admin, the admins of the project, and Pagure site
|
|
Matt Prahl |
ab0f46 |
# admins to modify projects, even if the user has the right ACLs on their
|
|
Matt Prahl |
ab0f46 |
# token
|
|
Pierre-Yves Chibon |
9c2953 |
if (
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.fas_user.username not in admins
|
|
Pierre-Yves Chibon |
9c2953 |
and flask.g.fas_user.username != project.user.username
|
|
Pierre-Yves Chibon |
9c2953 |
and not is_site_admin
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Matt Prahl |
30f8b1 |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
401, error_code=APIERROR.EMODIFYPROJECTNOTALLOWED
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Matt Prahl |
30f8b1 |
|
|
Pierre-Yves Chibon |
9c2953 |
valid_keys = ["main_admin", "retain_access"]
|
|
mprahl |
0f9ac5 |
# Check if it's JSON or form data
|
|
Pierre-Yves Chibon |
9c2953 |
if flask.request.headers.get("Content-Type") == "application/json":
|
|
mprahl |
0f9ac5 |
# Set force to True to ignore the mimetype. Set silent so that None is
|
|
mprahl |
0f9ac5 |
# returned if it's invalid JSON.
|
|
mprahl |
0f9ac5 |
args = flask.request.get_json(force=True, silent=True) or {}
|
|
Pierre-Yves Chibon |
9c2953 |
retain_access = args.get("retain_access", False)
|
|
mprahl |
0f9ac5 |
else:
|
|
Slavek Kabrda |
727932 |
args = get_request_data()
|
|
Pierre-Yves Chibon |
9c2953 |
retain_access = args.get("retain_access", "").lower() in ["true", "1"]
|
|
mprahl |
0f9ac5 |
|
|
mprahl |
0f9ac5 |
if not args:
|
|
Matt Prahl |
30f8b1 |
raise pagure.exceptions.APIError(400, error_code=APIERROR.EINVALIDREQ)
|
|
Matt Prahl |
30f8b1 |
|
|
Matt Prahl |
30f8b1 |
# Check to make sure there aren't parameters we don't support
|
|
mprahl |
0f9ac5 |
for key in args.keys():
|
|
Matt Prahl |
30f8b1 |
if key not in valid_keys:
|
|
Matt Prahl |
30f8b1 |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
400, error_code=APIERROR.EINVALIDREQ
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Matt Prahl |
30f8b1 |
|
|
Pierre-Yves Chibon |
9c2953 |
if "main_admin" in args:
|
|
Pierre-Yves Chibon |
9c2953 |
if (
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.fas_user.username != project.user.username
|
|
Pierre-Yves Chibon |
9c2953 |
and not is_site_admin
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Matt Prahl |
30f8b1 |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
401, error_code=APIERROR.ENOTMAINADMIN
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Matt Prahl |
30f8b1 |
# If the main_admin is already set correctly, don't do anything
|
|
Matt Prahl |
58c0b0 |
if flask.g.fas_user.username == project.user:
|
|
Matt Prahl |
30f8b1 |
return flask.jsonify(project.to_json(public=False, api=True))
|
|
Matt Prahl |
30f8b1 |
|
|
Matt Prahl |
30f8b1 |
try:
|
|
Pierre-Yves Chibon |
930073 |
new_main_admin = pagure.lib.query.get_user(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, args["main_admin"]
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Matt Prahl |
30f8b1 |
except pagure.exceptions.PagureException:
|
|
Matt Prahl |
30f8b1 |
raise pagure.exceptions.APIError(400, error_code=APIERROR.ENOUSER)
|
|
Matt Prahl |
30f8b1 |
|
|
mprahl |
8f40ee |
old_main_admin = project.user.user
|
|
Pierre-Yves Chibon |
930073 |
pagure.lib.query.set_project_owner(
|
|
Pierre-Yves Chibon |
930073 |
flask.g.session, project, new_main_admin
|
|
Pierre-Yves Chibon |
930073 |
)
|
|
mprahl |
8f40ee |
if retain_access and flask.g.fas_user.username == old_main_admin:
|
|
Pierre-Yves Chibon |
930073 |
pagure.lib.query.add_user_to_project(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session,
|
|
Pierre-Yves Chibon |
9c2953 |
project,
|
|
Pierre-Yves Chibon |
9c2953 |
new_user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
9c2953 |
user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Matt Prahl |
30f8b1 |
|
|
Matt Prahl |
30f8b1 |
try:
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Matt Prahl |
30f8b1 |
except SQLAlchemyError: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
9c2953 |
raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)
|
|
Matt Prahl |
30f8b1 |
|
|
Pierre-Yves Chibon |
fd97af |
pagure.lib.git.generate_gitolite_acls(project=project)
|
|
Pierre-Yves Chibon |
fd97af |
|
|
Matt Prahl |
30f8b1 |
return flask.jsonify(project.to_json(public=False, api=True))
|
|
Matt Prahl |
30f8b1 |
|
|
Matt Prahl |
30f8b1 |
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/", methods=["POST"])
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork", methods=["POST"])
|
|
Pierre-Yves Chibon |
9c2953 |
@api_login_required(acls=["fork_project"])
|
|
Pierre-Yves Chibon |
dc21df |
@api_method
|
|
Pierre-Yves Chibon |
dc21df |
def api_fork_project():
|
|
Pierre-Yves Chibon |
dc21df |
"""
|
|
Pierre-Yves Chibon |
dc21df |
Fork a project
|
|
Pierre-Yves Chibon |
dc21df |
--------------------
|
|
Pierre-Yves Chibon |
dc21df |
Fork a project on this pagure instance.
|
|
Pierre-Yves Chibon |
dc21df |
|
|
Patrick Uiterwijk |
bb08fb |
This is an asynchronous call.
|
|
Patrick Uiterwijk |
bb08fb |
|
|
Pierre-Yves Chibon |
dc21df |
::
|
|
Pierre-Yves Chibon |
dc21df |
|
|
ishcherb |
720ff5 |
POST /api/0/fork
|
|
Pierre-Yves Chibon |
dc21df |
|
|
Pierre-Yves Chibon |
dc21df |
|
|
Pierre-Yves Chibon |
dc21df |
Input
|
|
Pierre-Yves Chibon |
dc21df |
^^^^^
|
|
Pierre-Yves Chibon |
dc21df |
|
|
Pierre-Yves Chibon |
dc21df |
+------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
dc21df |
| Key | Type | Optionality | Description |
|
|
Pierre-Yves Chibon |
dc21df |
+==================+=========+==============+===========================+
|
|
Pierre-Yves Chibon |
dc21df |
| ``repo`` | string | Mandatory | | The name of the project |
|
|
Pierre-Yves Chibon |
dc21df |
| | | | to fork. |
|
|
Pierre-Yves Chibon |
dc21df |
+------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
34ece4 |
| ``namespace`` | string | Optional | | The namespace of the |
|
|
Pierre-Yves Chibon |
34ece4 |
| | | | project to fork. |
|
|
Pierre-Yves Chibon |
34ece4 |
+------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
dc21df |
| ``username`` | string | Optional | | The username of the user|
|
|
Pierre-Yves Chibon |
dc21df |
| | | | of the fork. |
|
|
Pierre-Yves Chibon |
dc21df |
+------------------+---------+--------------+---------------------------+
|
|
Patrick Uiterwijk |
0281ff |
| ``wait`` | boolean | Optional | | A boolean to specify if |
|
|
Patrick Uiterwijk |
0281ff |
| | | | this API call should |
|
|
Patrick Uiterwijk |
0281ff |
| | | | return a taskid or if it|
|
|
Patrick Uiterwijk |
0281ff |
| | | | should wait for the task|
|
|
Patrick Uiterwijk |
0281ff |
| | | | to finish. |
|
|
Patrick Uiterwijk |
0281ff |
+------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
dc21df |
|
|
Pierre-Yves Chibon |
dc21df |
|
|
Pierre-Yves Chibon |
dc21df |
Sample response
|
|
Pierre-Yves Chibon |
dc21df |
^^^^^^^^^^^^^^^
|
|
Pierre-Yves Chibon |
dc21df |
|
|
Pierre-Yves Chibon |
dc21df |
::
|
|
Pierre-Yves Chibon |
dc21df |
|
|
Patrick Uiterwijk |
0281ff |
wait=False:
|
|
Pierre-Yves Chibon |
dc21df |
{
|
|
Patrick Uiterwijk |
bb08fb |
"message": "Project forking queued",
|
|
Patrick Uiterwijk |
bb08fb |
"taskid": "123-abcd"
|
|
Pierre-Yves Chibon |
dc21df |
}
|
|
Pierre-Yves Chibon |
dc21df |
|
|
Patrick Uiterwijk |
0281ff |
wait=True:
|
|
Patrick Uiterwijk |
0281ff |
{
|
|
Patrick Uiterwijk |
0281ff |
"message": 'Repo "test" cloned to "pingou/test"
|
|
Patrick Uiterwijk |
0281ff |
}
|
|
Patrick Uiterwijk |
0281ff |
|
|
Pierre-Yves Chibon |
dc21df |
"""
|
|
Pierre-Yves Chibon |
dc21df |
output = {}
|
|
Pierre-Yves Chibon |
dc21df |
|
|
Pierre-Yves Chibon |
5c561c |
form = pagure.forms.ForkRepoForm(csrf_enabled=False)
|
|
Pierre-Yves Chibon |
dc21df |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
dc21df |
repo = form.repo.data
|
|
Pierre-Yves Chibon |
dc21df |
username = form.username.data or None
|
|
Pierre-Yves Chibon |
096375 |
namespace = form.namespace.data.strip() or None
|
|
Pierre-Yves Chibon |
dc21df |
|
|
Patrick Uiterwijk |
eabc8e |
repo = get_authorized_api_project(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, repo, user=username, namespace=namespace
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
dc21df |
if repo is None:
|
|
Pierre-Yves Chibon |
dc21df |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
404, error_code=APIERROR.ENOPROJECT
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
dc21df |
|
|
Pierre-Yves Chibon |
dc21df |
try:
|
|
Pierre-Yves Chibon |
930073 |
task = pagure.lib.query.fork_project(
|
|
Patrick Uiterwijk |
3f97f6 |
flask.g.session, user=flask.g.fas_user.username, repo=repo
|
|
Pierre-Yves Chibon |
dc21df |
)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
9c2953 |
output = {"message": "Project forking queued", "taskid": task.id}
|
|
Patrick Uiterwijk |
0281ff |
|
|
Pierre-Yves Chibon |
9c2953 |
if get_request_data().get("wait", True):
|
|
Aurélien Bompard |
a7f281 |
task.get()
|
|
Pierre-Yves Chibon |
9c2953 |
output = {
|
|
Pierre-Yves Chibon |
9c2953 |
"message": 'Repo "%s" cloned to "%s/%s"'
|
|
Pierre-Yves Chibon |
9c2953 |
% (repo.fullname, flask.g.fas_user.username, repo.fullname)
|
|
Pierre-Yves Chibon |
9c2953 |
}
|
|
Pierre-Yves Chibon |
dc21df |
except pagure.exceptions.PagureException as err:
|
|
Pierre-Yves Chibon |
dc21df |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
400, error_code=APIERROR.ENOCODE, error=str(err)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
dc21df |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
_log.exception(err)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
9c2953 |
raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)
|
|
Pierre-Yves Chibon |
dc21df |
else:
|
|
Pierre-Yves Chibon |
dc21df |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
400, error_code=APIERROR.EINVALIDREQ, errors=form.errors
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
dc21df |
|
|
Pierre-Yves Chibon |
dc21df |
jsonout = flask.jsonify(output)
|
|
Pierre-Yves Chibon |
dc21df |
return jsonout
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<repo>/git/generateacls", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<namespace>/<repo>/git/generateacls", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<repo>/git/generateacls", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/git/generateacls", methods=["POST"]</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
@api_login_required(acls=["generate_acls_project"])
|
|
Matt Prahl |
489ad1 |
@api_method
|
|
Matt Prahl |
489ad1 |
def api_generate_acls(repo, username=None, namespace=None):
|
|
Matt Prahl |
489ad1 |
"""
|
|
Matt Prahl |
489ad1 |
Generate Gitolite ACLs on a project
|
|
Matt Prahl |
489ad1 |
-----------------------------------
|
|
Matt Prahl |
489ad1 |
Generate Gitolite ACLs on a project. This is restricted to Pagure admins.
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
This is an asynchronous call.
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
::
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
POST /api/0/rpms/python-requests/git/generateacls
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
Input
|
|
Matt Prahl |
489ad1 |
^^^^^
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
+------------------+---------+--------------+---------------------------+
|
|
Matt Prahl |
489ad1 |
| Key | Type | Optionality | Description |
|
|
Matt Prahl |
489ad1 |
+==================+=========+==============+===========================+
|
|
Matt Prahl |
489ad1 |
| ``wait`` | boolean | Optional | | A boolean to specify if |
|
|
Matt Prahl |
489ad1 |
| | | | this API call should |
|
|
Matt Prahl |
489ad1 |
| | | | return a taskid or if it|
|
|
Matt Prahl |
489ad1 |
| | | | should wait for the task|
|
|
Matt Prahl |
489ad1 |
| | | | to finish. |
|
|
Matt Prahl |
489ad1 |
+------------------+---------+--------------+---------------------------+
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
Sample response
|
|
Matt Prahl |
489ad1 |
^^^^^^^^^^^^^^^
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
::
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
wait=False:
|
|
Matt Prahl |
489ad1 |
{
|
|
Matt Prahl |
489ad1 |
'message': 'Project ACL generation queued',
|
|
Matt Prahl |
489ad1 |
'taskid': '123-abcd'
|
|
Matt Prahl |
489ad1 |
}
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
wait=True:
|
|
Matt Prahl |
489ad1 |
{
|
|
Matt Prahl |
489ad1 |
'message': 'Project ACLs generated'
|
|
Matt Prahl |
489ad1 |
}
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
"""
|
|
Pierre-Yves Chibon |
01d0f2 |
project = _get_repo(repo, username, namespace)
|
|
Pierre-Yves Chibon |
01d0f2 |
_check_token(project, project_token=False)
|
|
Pierre-Yves Chibon |
e99858 |
|
|
mprahl |
0f9ac5 |
# Check if it's JSON or form data
|
|
Pierre-Yves Chibon |
9c2953 |
if flask.request.headers.get("Content-Type") == "application/json":
|
|
mprahl |
0f9ac5 |
# Set force to True to ignore the mimetype. Set silent so that None is
|
|
mprahl |
0f9ac5 |
# returned if it's invalid JSON.
|
|
mprahl |
0f9ac5 |
json = flask.request.get_json(force=True, silent=True) or {}
|
|
Pierre-Yves Chibon |
9c2953 |
wait = json.get("wait", False)
|
|
mprahl |
0f9ac5 |
else:
|
|
Pierre-Yves Chibon |
9c2953 |
wait = pagure.utils.is_true(get_request_data().get("wait"))
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
try:
|
|
Pierre-Yves Chibon |
9c2953 |
task = pagure.lib.git.generate_gitolite_acls(project=project)
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
if wait:
|
|
Aurélien Bompard |
a7f281 |
task.get()
|
|
Pierre-Yves Chibon |
9c2953 |
output = {"message": "Project ACLs generated"}
|
|
Matt Prahl |
489ad1 |
else:
|
|
Pierre-Yves Chibon |
9c2953 |
output = {
|
|
Pierre-Yves Chibon |
9c2953 |
"message": "Project ACL generation queued",
|
|
Pierre-Yves Chibon |
9c2953 |
"taskid": task.id,
|
|
Pierre-Yves Chibon |
9c2953 |
}
|
|
Matt Prahl |
489ad1 |
except pagure.exceptions.PagureException as err:
|
|
Matt Prahl |
489ad1 |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
400, error_code=APIERROR.ENOCODE, error=str(err)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Matt Prahl |
489ad1 |
|
|
Matt Prahl |
489ad1 |
jsonout = flask.jsonify(output)
|
|
Matt Prahl |
489ad1 |
return jsonout
|
|
mprahl |
7d811e |
|
|
mprahl |
7d811e |
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<repo>/git/branch", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<namespace>/<repo>/git/branch", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<repo>/git/branch", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<namespace>/<repo>/git/branch", methods=["POST"])</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@api_login_required(acls=["create_branch"])
|
|
mprahl |
7d811e |
@api_method
|
|
mprahl |
7d811e |
def api_new_branch(repo, username=None, namespace=None):
|
|
mprahl |
7d811e |
"""
|
|
mprahl |
7d811e |
Create a new git branch on a project
|
|
mprahl |
7d811e |
------------------------------------
|
|
mprahl |
7d811e |
Create a new git branch on a project
|
|
mprahl |
7d811e |
|
|
mprahl |
7d811e |
::
|
|
mprahl |
7d811e |
|
|
mprahl |
7d811e |
POST /api/0/rpms/python-requests/git/branch
|
|
mprahl |
7d811e |
|
|
mprahl |
7d811e |
|
|
mprahl |
7d811e |
Input
|
|
mprahl |
7d811e |
^^^^^
|
|
mprahl |
7d811e |
|
|
mprahl |
7d811e |
+------------------+---------+--------------+---------------------------+
|
|
mprahl |
7d811e |
| Key | Type | Optionality | Description |
|
|
mprahl |
7d811e |
+==================+=========+==============+===========================+
|
|
mprahl |
7d811e |
| ``branch`` | string | Mandatory | | A string of the branch |
|
|
mprahl |
7d811e |
| | | | to create. |
|
|
mprahl |
7d811e |
+------------------+---------+--------------+---------------------------+
|
|
mprahl |
7d811e |
| ``from_branch`` | string | Optional | | A string of the branch |
|
|
mprahl |
7d811e |
| | | | to branch off of. This |
|
|
mprahl |
7d811e |
| | | | defaults to "master". |
|
|
mprahl |
97e56a |
| | | | if ``from_commit`` |
|
|
mprahl |
97e56a |
| | | | isn't set. |
|
|
mprahl |
97e56a |
+------------------+---------+--------------+---------------------------+
|
|
mprahl |
97e56a |
| ``from_commit`` | string | Optional | | A string of the commit |
|
|
mprahl |
97e56a |
| | | | to branch off of. |
|
|
mprahl |
7d811e |
+------------------+---------+--------------+---------------------------+
|
|
mprahl |
7d811e |
|
|
mprahl |
7d811e |
|
|
mprahl |
7d811e |
Sample response
|
|
mprahl |
7d811e |
^^^^^^^^^^^^^^^
|
|
mprahl |
7d811e |
|
|
mprahl |
7d811e |
::
|
|
mprahl |
7d811e |
|
|
mprahl |
7d811e |
{
|
|
mprahl |
7d811e |
'message': 'Project branch was created'
|
|
mprahl |
7d811e |
}
|
|
mprahl |
7d811e |
|
|
mprahl |
7d811e |
"""
|
|
Pierre-Yves Chibon |
01d0f2 |
project = _get_repo(repo, username, namespace)
|
|
Pierre-Yves Chibon |
01d0f2 |
_check_token(project, project_token=False)
|
|
Pierre-Yves Chibon |
446bcc |
|
|
mprahl |
7d811e |
# Check if it's JSON or form data
|
|
Pierre-Yves Chibon |
9c2953 |
if flask.request.headers.get("Content-Type") == "application/json":
|
|
mprahl |
7d811e |
# Set force to True to ignore the mimetype. Set silent so that None is
|
|
mprahl |
7d811e |
# returned if it's invalid JSON.
|
|
mprahl |
7d811e |
args = flask.request.get_json(force=True, silent=True) or {}
|
|
mprahl |
7d811e |
else:
|
|
Slavek Kabrda |
727932 |
args = get_request_data()
|
|
mprahl |
7d811e |
|
|
Pierre-Yves Chibon |
9c2953 |
branch = args.get("branch")
|
|
Pierre-Yves Chibon |
9c2953 |
from_branch = args.get("from_branch")
|
|
Pierre-Yves Chibon |
9c2953 |
from_commit = args.get("from_commit")
|
|
mprahl |
7d811e |
|
|
mprahl |
7d811e |
if from_branch and from_commit:
|
|
mprahl |
7d811e |
raise pagure.exceptions.APIError(400, error_code=APIERROR.EINVALIDREQ)
|
|
mprahl |
7d811e |
|
|
Pierre-Yves Chibon |
9c2953 |
if (
|
|
Pierre-Yves Chibon |
9c2953 |
not branch
|
|
Pierre-Yves Chibon |
9c2953 |
or not isinstance(branch, string_types)
|
|
Pierre-Yves Chibon |
9c2953 |
or (from_branch and not isinstance(from_branch, string_types))
|
|
Pierre-Yves Chibon |
9c2953 |
or (from_commit and not isinstance(from_commit, string_types))
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
mprahl |
7d811e |
raise pagure.exceptions.APIError(400, error_code=APIERROR.EINVALIDREQ)
|
|
mprahl |
7d811e |
|
|
mprahl |
7d811e |
try:
|
|
Pierre-Yves Chibon |
9c2953 |
pagure.lib.git.new_git_branch(
|
|
Patrick Uiterwijk |
03a519 |
flask.g.fas_user.username,
|
|
Patrick Uiterwijk |
03a519 |
project,
|
|
Patrick Uiterwijk |
03a519 |
branch,
|
|
Patrick Uiterwijk |
03a519 |
from_branch=from_branch,
|
|
Patrick Uiterwijk |
03a519 |
from_commit=from_commit,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
mprahl |
7d811e |
except GitError: # pragma: no cover
|
|
mprahl |
7d811e |
raise pagure.exceptions.APIError(400, error_code=APIERROR.EGITERROR)
|
|
mprahl |
7d811e |
except pagure.exceptions.PagureException as error:
|
|
mprahl |
7d811e |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
400, error_code=APIERROR.ENOCODE, error=str(error)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
mprahl |
7d811e |
|
|
Pierre-Yves Chibon |
9c2953 |
output = {"message": "Project branch was created"}
|
|
mprahl |
7d811e |
jsonout = flask.jsonify(output)
|
|
mprahl |
7d811e |
return jsonout
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
faedb1 |
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<repo>/c/<commit_hash>/flag")</commit_hash></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<namespace>/<repo>/c/<commit_hash>/flag")</commit_hash></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<repo>/c/<commit_hash>/flag")</commit_hash></repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<namespace>/<repo>/c/<commit_hash>/flag")</commit_hash></repo></namespace></username>
|
|
Slavek Kabrda |
3e4583 |
@api_method
|
|
Slavek Kabrda |
3e4583 |
def api_commit_flags(repo, commit_hash, username=None, namespace=None):
|
|
Slavek Kabrda |
3e4583 |
"""
|
|
Slavek Kabrda |
3e4583 |
Flags for a commit
|
|
Slavek Kabrda |
3e4583 |
------------------
|
|
Slavek Kabrda |
3e4583 |
Return all flags for given commit of given project
|
|
Slavek Kabrda |
3e4583 |
|
|
Slavek Kabrda |
3e4583 |
::
|
|
Slavek Kabrda |
3e4583 |
|
|
Slavek Kabrda |
3e4583 |
GET /api/0/<repo>/c/<commit_hash>/flag</commit_hash></repo>
|
|
Slavek Kabrda |
3e4583 |
GET /api/0/<namespace>/<repo>/c/<commit_hash>/flag</commit_hash></repo></namespace>
|
|
Slavek Kabrda |
3e4583 |
|
|
Slavek Kabrda |
3e4583 |
::
|
|
Slavek Kabrda |
3e4583 |
|
|
Slavek Kabrda |
3e4583 |
GET /api/0/fork/<username>/<repo>/c/<commit_hash>/flag</commit_hash></repo></username>
|
|
Slavek Kabrda |
3e4583 |
GET /api/0/fork/<username>/<namespace>/<repo>/c/<commit_hash>/flag</commit_hash></repo></namespace></username>
|
|
Slavek Kabrda |
3e4583 |
|
|
Slavek Kabrda |
3e4583 |
Sample response
|
|
Slavek Kabrda |
3e4583 |
^^^^^^^^^^^^^^^
|
|
Slavek Kabrda |
3e4583 |
|
|
Slavek Kabrda |
3e4583 |
::
|
|
Slavek Kabrda |
3e4583 |
|
|
Slavek Kabrda |
3e4583 |
{
|
|
Slavek Kabrda |
3e4583 |
"flags": [
|
|
Slavek Kabrda |
3e4583 |
{
|
|
Slavek Kabrda |
3e4583 |
"comment": "flag-comment",
|
|
Slavek Kabrda |
3e4583 |
"commit_hash": "28f1f7fe844301f0e5f7aecacae0a1e5ec50a090",
|
|
Slavek Kabrda |
3e4583 |
"date_created": "1520341983",
|
|
Slavek Kabrda |
3e4583 |
"percent": null,
|
|
Slavek Kabrda |
3e4583 |
"status": "success",
|
|
Slavek Kabrda |
3e4583 |
"url": "https://some.url.com",
|
|
Slavek Kabrda |
3e4583 |
"user": {
|
|
Slavek Kabrda |
3e4583 |
"fullname": "Full name",
|
|
Slavek Kabrda |
3e4583 |
"name": "fname"
|
|
Slavek Kabrda |
3e4583 |
},
|
|
Slavek Kabrda |
3e4583 |
"username": "somename"
|
|
Slavek Kabrda |
3e4583 |
},
|
|
Slavek Kabrda |
3e4583 |
{
|
|
Slavek Kabrda |
3e4583 |
"comment": "different-comment",
|
|
Slavek Kabrda |
3e4583 |
"commit_hash": "28f1f7fe844301f0e5f7aecacae0a1e5ec50a090",
|
|
Slavek Kabrda |
3e4583 |
"date_created": "1520512543",
|
|
Slavek Kabrda |
3e4583 |
"percent": null,
|
|
Slavek Kabrda |
3e4583 |
"status": "pending",
|
|
Slavek Kabrda |
3e4583 |
"url": "https://other.url.com",
|
|
Slavek Kabrda |
3e4583 |
"user": {
|
|
Slavek Kabrda |
3e4583 |
"fullname": "Other Name",
|
|
Slavek Kabrda |
3e4583 |
"name": "oname"
|
|
Slavek Kabrda |
3e4583 |
},
|
|
Slavek Kabrda |
3e4583 |
"username": "differentname"
|
|
Slavek Kabrda |
3e4583 |
}
|
|
Slavek Kabrda |
3e4583 |
],
|
|
Slavek Kabrda |
3e4583 |
"total_flags": 2
|
|
Slavek Kabrda |
3e4583 |
}
|
|
Slavek Kabrda |
3e4583 |
|
|
Slavek Kabrda |
3e4583 |
"""
|
|
Pierre-Yves Chibon |
01d0f2 |
repo = _get_repo(repo, username, namespace)
|
|
Slavek Kabrda |
3e4583 |
|
|
Slavek Kabrda |
3e4583 |
reponame = pagure.utils.get_repo_path(repo)
|
|
Slavek Kabrda |
3e4583 |
repo_obj = Repository(reponame)
|
|
Slavek Kabrda |
3e4583 |
try:
|
|
Slavek Kabrda |
3e4583 |
repo_obj.get(commit_hash)
|
|
Slavek Kabrda |
3e4583 |
except ValueError:
|
|
Pierre-Yves Chibon |
9c2953 |
raise pagure.exceptions.APIError(404, error_code=APIERROR.ENOCOMMIT)
|
|
Slavek Kabrda |
3e4583 |
|
|
Pierre-Yves Chibon |
930073 |
flags = pagure.lib.query.get_commit_flag(
|
|
Pierre-Yves Chibon |
930073 |
flask.g.session, repo, commit_hash
|
|
Pierre-Yves Chibon |
930073 |
)
|
|
Slavek Kabrda |
3e4583 |
flags = [f.to_json(public=True) for f in flags]
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.jsonify({"total_flags": len(flags), "flags": flags})
|
|
Slavek Kabrda |
3e4583 |
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<repo>/c/<commit_hash>/flag", methods=["POST"])</commit_hash></repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<namespace>/<repo>/c/<commit_hash>/flag", methods=["POST"])</commit_hash></repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<repo>/c/<commit_hash>/flag", methods=["POST"])</commit_hash></repo></username>
|
|
Pierre-Yves Chibon |
8715b5 |
@API.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/c/<commit_hash>/flag",</commit_hash></repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
methods=["POST"],
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
@api_login_required(acls=["commit_flag"])
|
|
Pierre-Yves Chibon |
8715b5 |
@api_method
|
|
Pierre-Yves Chibon |
8715b5 |
def api_commit_add_flag(repo, commit_hash, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
8715b5 |
"""
|
|
Pierre-Yves Chibon |
8715b5 |
Flag a commit
|
|
Pierre-Yves Chibon |
8715b5 |
-------------------
|
|
Pierre-Yves Chibon |
8715b5 |
Add or edit flags on a commit.
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
8715b5 |
::
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
8715b5 |
POST /api/0/<repo>/c/<commit_hash>/flag</commit_hash></repo>
|
|
Pierre-Yves Chibon |
8715b5 |
POST /api/0/<namespace>/<repo>/c/<commit_hash>/flag</commit_hash></repo></namespace>
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
8715b5 |
::
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
8715b5 |
POST /api/0/fork/<username>/<repo>/c/<commit_hash>/flag</commit_hash></repo></username>
|
|
Pierre-Yves Chibon |
8715b5 |
POST /api/0/fork/<username>/<namespace>/<repo>/c/<commit_hash>/flag</commit_hash></repo></namespace></username>
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
8715b5 |
Input
|
|
Pierre-Yves Chibon |
8715b5 |
^^^^^
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
8715b5 |
+---------------+---------+--------------+-----------------------------+
|
|
Pierre-Yves Chibon |
8715b5 |
| Key | Type | Optionality | Description |
|
|
Pierre-Yves Chibon |
8715b5 |
+===============+=========+==============+=============================+
|
|
Pierre-Yves Chibon |
8715b5 |
| ``username`` | string | Mandatory | | The name of the |
|
|
Pierre-Yves Chibon |
8715b5 |
| | | | application to be |
|
|
Pierre-Yves Chibon |
8715b5 |
| | | | presented to users |
|
|
Pierre-Yves Chibon |
abcbf7 |
| | | | on the commit pages |
|
|
Pierre-Yves Chibon |
8715b5 |
+---------------+---------+--------------+-----------------------------+
|
|
Pierre-Yves Chibon |
8715b5 |
| ``comment`` | string | Mandatory | | A short message |
|
|
Pierre-Yves Chibon |
8715b5 |
| | | | summarizing the |
|
|
Pierre-Yves Chibon |
8715b5 |
| | | | presented results |
|
|
Pierre-Yves Chibon |
8715b5 |
+---------------+---------+--------------+-----------------------------+
|
|
Pierre-Yves Chibon |
8715b5 |
| ``url`` | string | Mandatory | | A URL to the result |
|
|
Pierre-Yves Chibon |
8715b5 |
| | | | of this flag |
|
|
Pierre-Yves Chibon |
8715b5 |
+---------------+---------+--------------+-----------------------------+
|
|
Pierre-Yves Chibon |
abcbf7 |
| ``status`` | string | Mandatory | | The status of the task, |
|
|
Slavek Kabrda |
45252f |
| | | | can be any of: |
|
|
Slavek Kabrda |
45252f |
| | | | $$FLAG_STATUSES_COMMAS$$ |
|
|
Pierre-Yves Chibon |
abcbf7 |
+---------------+---------+--------------+-----------------------------+
|
|
Pierre-Yves Chibon |
abcbf7 |
| ``percent`` | int | Optional | | A percentage of |
|
|
Pierre-Yves Chibon |
abcbf7 |
| | | | completion compared to |
|
|
Pierre-Yves Chibon |
abcbf7 |
| | | | the goal. The percentage |
|
|
Pierre-Yves Chibon |
abcbf7 |
| | | | also determine the |
|
|
Pierre-Yves Chibon |
abcbf7 |
| | | | background color of the |
|
|
Pierre-Yves Chibon |
abcbf7 |
| | | | flag on the pages |
|
|
Pierre-Yves Chibon |
abcbf7 |
+---------------+---------+--------------+-----------------------------+
|
|
Pierre-Yves Chibon |
8715b5 |
| ``uid`` | string | Optional | | A unique identifier used |
|
|
Pierre-Yves Chibon |
abcbf7 |
| | | | to identify a flag across |
|
|
Pierre-Yves Chibon |
abcbf7 |
| | | | all projects. If the |
|
|
Pierre-Yves Chibon |
8715b5 |
| | | | provided UID matches an |
|
|
Pierre-Yves Chibon |
8715b5 |
| | | | existing one, then the |
|
|
Pierre-Yves Chibon |
8715b5 |
| | | | API call will update the |
|
|
Pierre-Yves Chibon |
8715b5 |
| | | | existing one rather than |
|
|
Pierre-Yves Chibon |
8715b5 |
| | | | create a new one. |
|
|
Pierre-Yves Chibon |
8715b5 |
| | | | Maximum Length: 32 |
|
|
Pierre-Yves Chibon |
8715b5 |
| | | | characters. Default: an |
|
|
Pierre-Yves Chibon |
8715b5 |
| | | | auto generated UID |
|
|
Pierre-Yves Chibon |
8715b5 |
+---------------+---------+--------------+-----------------------------+
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
8715b5 |
Sample response
|
|
Pierre-Yves Chibon |
8715b5 |
^^^^^^^^^^^^^^^
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
8715b5 |
::
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
8715b5 |
{
|
|
Pierre-Yves Chibon |
8715b5 |
"flag": {
|
|
Pierre-Yves Chibon |
8715b5 |
"comment": "Tests passed",
|
|
Pierre-Yves Chibon |
8715b5 |
"commit_hash": "62b49f00d489452994de5010565fab81",
|
|
Pierre-Yves Chibon |
8715b5 |
"date_created": "1510742565",
|
|
Pierre-Yves Chibon |
8715b5 |
"percent": 100,
|
|
Pierre-Yves Chibon |
abcbf7 |
"status": "success",
|
|
Pierre-Yves Chibon |
8715b5 |
"url": "http://jenkins.cloud.fedoraproject.org/",
|
|
Pierre-Yves Chibon |
8715b5 |
"user": {
|
|
Pierre-Yves Chibon |
8715b5 |
"default_email": "bar@pingou.com",
|
|
Pierre-Yves Chibon |
8715b5 |
"emails": ["bar@pingou.com", "foo@pingou.com"],
|
|
Pierre-Yves Chibon |
8715b5 |
"fullname": "PY C",
|
|
Pierre-Yves Chibon |
8715b5 |
"name": "pingou"},
|
|
Pierre-Yves Chibon |
8715b5 |
"username": "Jenkins"
|
|
Pierre-Yves Chibon |
8715b5 |
},
|
|
Pierre-Yves Chibon |
8715b5 |
"message": "Flag added",
|
|
Pierre-Yves Chibon |
8715b5 |
"uid": "b1de8f80defd4a81afe2e09f39678087"
|
|
Pierre-Yves Chibon |
8715b5 |
}
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
8715b5 |
::
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
8715b5 |
{
|
|
Pierre-Yves Chibon |
8715b5 |
"flag": {
|
|
Pierre-Yves Chibon |
8715b5 |
"comment": "Tests passed",
|
|
Pierre-Yves Chibon |
8715b5 |
"commit_hash": "62b49f00d489452994de5010565fab81",
|
|
Pierre-Yves Chibon |
8715b5 |
"date_created": "1510742565",
|
|
Pierre-Yves Chibon |
8715b5 |
"percent": 100,
|
|
Pierre-Yves Chibon |
abcbf7 |
"status": "success",
|
|
Pierre-Yves Chibon |
8715b5 |
"url": "http://jenkins.cloud.fedoraproject.org/",
|
|
Pierre-Yves Chibon |
8715b5 |
"user": {
|
|
Pierre-Yves Chibon |
8715b5 |
"default_email": "bar@pingou.com",
|
|
Pierre-Yves Chibon |
8715b5 |
"emails": ["bar@pingou.com", "foo@pingou.com"],
|
|
Pierre-Yves Chibon |
8715b5 |
"fullname": "PY C",
|
|
Pierre-Yves Chibon |
8715b5 |
"name": "pingou"},
|
|
Pierre-Yves Chibon |
8715b5 |
"username": "Jenkins"
|
|
Pierre-Yves Chibon |
8715b5 |
},
|
|
Pierre-Yves Chibon |
8715b5 |
"message": "Flag updated",
|
|
Pierre-Yves Chibon |
8715b5 |
"uid": "b1de8f80defd4a81afe2e09f39678087"
|
|
Pierre-Yves Chibon |
8715b5 |
}
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
8715b5 |
""" # noqa
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
01d0f2 |
repo = _get_repo(repo, username, namespace)
|
|
Pierre-Yves Chibon |
01d0f2 |
_check_token(repo, project_token=False)
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
8715b5 |
output = {}
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
b130e5 |
reponame = pagure.utils.get_repo_path(repo)
|
|
Pierre-Yves Chibon |
8715b5 |
repo_obj = Repository(reponame)
|
|
Pierre-Yves Chibon |
8715b5 |
try:
|
|
Pierre-Yves Chibon |
8715b5 |
repo_obj.get(commit_hash)
|
|
Pierre-Yves Chibon |
8715b5 |
except ValueError:
|
|
Pierre-Yves Chibon |
9c2953 |
raise pagure.exceptions.APIError(404, error_code=APIERROR.ENOCOMMIT)
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
5c561c |
form = pagure.forms.AddPullRequestFlagForm(csrf_enabled=False)
|
|
Pierre-Yves Chibon |
8715b5 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
8715b5 |
username = form.username.data
|
|
Pierre-Yves Chibon |
abcbf7 |
percent = form.percent.data.strip() or None
|
|
Pierre-Yves Chibon |
8715b5 |
comment = form.comment.data.strip()
|
|
Pierre-Yves Chibon |
8715b5 |
url = form.url.data.strip()
|
|
Pierre-Yves Chibon |
8715b5 |
uid = form.uid.data.strip() if form.uid.data else None
|
|
Pierre-Yves Chibon |
abcbf7 |
status = form.status.data.strip()
|
|
Pierre-Yves Chibon |
8715b5 |
try:
|
|
Pierre-Yves Chibon |
8715b5 |
# New Flag
|
|
Pierre-Yves Chibon |
930073 |
message, uid = pagure.lib.query.add_commit_flag(
|
|
Pierre-Yves Chibon |
b130e5 |
session=flask.g.session,
|
|
Pierre-Yves Chibon |
8715b5 |
repo=repo,
|
|
Pierre-Yves Chibon |
8715b5 |
commit_hash=commit_hash,
|
|
Pierre-Yves Chibon |
8715b5 |
username=username,
|
|
Pierre-Yves Chibon |
8715b5 |
percent=percent,
|
|
Pierre-Yves Chibon |
8715b5 |
comment=comment,
|
|
Pierre-Yves Chibon |
abcbf7 |
status=status,
|
|
Pierre-Yves Chibon |
8715b5 |
url=url,
|
|
Pierre-Yves Chibon |
8715b5 |
uid=uid,
|
|
Pierre-Yves Chibon |
8715b5 |
user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
8715b5 |
token=flask.g.token.id,
|
|
Pierre-Yves Chibon |
8715b5 |
)
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
930073 |
c_flag = pagure.lib.query.get_commit_flag_by_uid(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, commit_hash, uid
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
output["message"] = message
|
|
Pierre-Yves Chibon |
9c2953 |
output["uid"] = uid
|
|
Pierre-Yves Chibon |
9c2953 |
output["flag"] = c_flag.to_json()
|
|
Pierre-Yves Chibon |
8715b5 |
except pagure.exceptions.PagureException as err:
|
|
Pierre-Yves Chibon |
8715b5 |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
400, error_code=APIERROR.ENOCODE, error=str(err)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
8715b5 |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
b130e5 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
5460c9 |
_log.exception(err)
|
|
Pierre-Yves Chibon |
9c2953 |
raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)
|
|
Pierre-Yves Chibon |
8715b5 |
else:
|
|
Pierre-Yves Chibon |
8715b5 |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
400, error_code=APIERROR.EINVALIDREQ, errors=form.errors
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
8715b5 |
|
|
Pierre-Yves Chibon |
8715b5 |
jsonout = flask.jsonify(output)
|
|
Pierre-Yves Chibon |
8715b5 |
return jsonout
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<repo>/watchers/update", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<namespace>/<repo>/watchers/update", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<repo>/watchers/update", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
f778bd |
@API.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/watchers/update", methods=["POST"]</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
@api_login_required(acls=["update_watch_status"])
|
|
Pierre-Yves Chibon |
f778bd |
@api_method
|
|
Pierre-Yves Chibon |
f778bd |
def api_update_project_watchers(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
9c2953 |
"""
|
|
Pierre-Yves Chibon |
f778bd |
Update project watchers
|
|
Pierre-Yves Chibon |
f778bd |
-----------------------
|
|
Pierre-Yves Chibon |
f778bd |
Allows anyone to update their own watch status on the project.
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
::
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
POST /api/0/<repo>/watchers/update</repo>
|
|
Pierre-Yves Chibon |
f778bd |
POST /api/0/<namespace>/<repo>/watchers/update</repo></namespace>
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
::
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
POST /api/0/fork/<username>/<repo>/watchers/update</repo></username>
|
|
Pierre-Yves Chibon |
f778bd |
POST /api/0/fork/<username>/<namespace>/<repo>/watchers/update</repo></namespace></username>
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
Input
|
|
Pierre-Yves Chibon |
f778bd |
^^^^^
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
+------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
f778bd |
| Key | Type | Optionality | Description |
|
|
Pierre-Yves Chibon |
f778bd |
+==================+=========+==============+===========================+
|
|
Pierre-Yves Chibon |
f778bd |
| ``repo`` | string | Mandatory | | The name of the project |
|
|
Pierre-Yves Chibon |
f778bd |
| | | | to fork. |
|
|
Pierre-Yves Chibon |
f778bd |
+------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
f778bd |
| ``status`` | string | Mandatory | | The new watch status to |
|
|
Pierre-Yves Chibon |
f778bd |
| | | | set on that project. |
|
|
Pierre-Yves Chibon |
f778bd |
| | | | (See options below) |
|
|
Pierre-Yves Chibon |
f778bd |
+------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
f778bd |
| ``watcher`` | string | Mandatory | | The name of the user |
|
|
Pierre-Yves Chibon |
f778bd |
| | | | changing their watch |
|
|
Pierre-Yves Chibon |
f778bd |
| | | | status. |
|
|
Pierre-Yves Chibon |
f778bd |
+------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
f778bd |
| ``namespace`` | string | Optional | | The namespace of the |
|
|
Pierre-Yves Chibon |
f778bd |
| | | | project to fork. |
|
|
Pierre-Yves Chibon |
f778bd |
+------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
f778bd |
| ``username`` | string | Optional | | The username of the user|
|
|
Pierre-Yves Chibon |
f778bd |
| | | | of the fork. |
|
|
Pierre-Yves Chibon |
f778bd |
+------------------+---------+--------------+---------------------------+
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
Watch Status
|
|
Pierre-Yves Chibon |
f778bd |
^^^^^^^^^^^^
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
+------------+----------------------------------------------+
|
|
Pierre-Yves Chibon |
f778bd |
| Key | Description |
|
|
Pierre-Yves Chibon |
f778bd |
+============+==============================================+
|
|
Pierre-Yves Chibon |
f778bd |
| -1 | Reset the watch status to default |
|
|
Pierre-Yves Chibon |
f778bd |
+------------+----------------------------------------------+
|
|
Pierre-Yves Chibon |
f778bd |
| 0 | Unwatch, don't notify the user of anything |
|
|
Pierre-Yves Chibon |
f778bd |
+------------+----------------------------------------------+
|
|
Pierre-Yves Chibon |
f778bd |
| 1 | Watch issues and pull-requests |
|
|
Pierre-Yves Chibon |
f778bd |
+------------+----------------------------------------------+
|
|
Pierre-Yves Chibon |
f778bd |
| 2 | Watch commits |
|
|
Pierre-Yves Chibon |
f778bd |
+------------+----------------------------------------------+
|
|
Pierre-Yves Chibon |
f778bd |
| 3 | Watch commits, issues and pull-requests |
|
|
Pierre-Yves Chibon |
f778bd |
+------------+----------------------------------------------+
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
Sample response
|
|
Pierre-Yves Chibon |
f778bd |
^^^^^^^^^^^^^^^
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
::
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
{
|
|
Pierre-Yves Chibon |
f778bd |
"message": "You are now watching issues and PRs on this project",
|
|
Pierre-Yves Chibon |
f778bd |
"status": "ok"
|
|
Pierre-Yves Chibon |
f778bd |
}
|
|
Pierre-Yves Chibon |
9c2953 |
"""
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
01d0f2 |
project = _get_repo(repo, username, namespace)
|
|
Pierre-Yves Chibon |
01d0f2 |
_check_token(project)
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
# Get the input submitted
|
|
Pierre-Yves Chibon |
f778bd |
data = get_request_data()
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
9c2953 |
watcher = data.get("watcher")
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
if not watcher:
|
|
Pierre-Yves Chibon |
9c2953 |
_log.debug("api_update_project_watchers: Invalid watcher: %s", watcher)
|
|
Pierre-Yves Chibon |
9c2953 |
raise pagure.exceptions.APIError(400, error_code=APIERROR.EINVALIDREQ)
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
is_site_admin = pagure.utils.is_admin()
|
|
Pierre-Yves Chibon |
f778bd |
# Only allow the main admin, and the user themselves to update their
|
|
Pierre-Yves Chibon |
f778bd |
# status
|
|
Pierre-Yves Chibon |
f778bd |
if not is_site_admin and flask.g.fas_user.username != watcher:
|
|
Pierre-Yves Chibon |
f778bd |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
401, error_code=APIERROR.EMODIFYPROJECTNOTALLOWED
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
try:
|
|
Pierre-Yves Chibon |
930073 |
pagure.lib.query.get_user(flask.g.session, watcher)
|
|
Karsten Hopp |
3b333e |
except pagure.exceptions.PagureException:
|
|
Pierre-Yves Chibon |
f778bd |
_log.debug(
|
|
Pierre-Yves Chibon |
9c2953 |
"api_update_project_watchers: Invalid user watching: %s", watcher
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
raise pagure.exceptions.APIError(400, error_code=APIERROR.EINVALIDREQ)
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
9c2953 |
watch_status = data.get("status")
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
f778bd |
try:
|
|
Pierre-Yves Chibon |
930073 |
msg = pagure.lib.query.update_watch_status(
|
|
Pierre-Yves Chibon |
f778bd |
session=flask.g.session,
|
|
Pierre-Yves Chibon |
f778bd |
project=project,
|
|
Pierre-Yves Chibon |
f778bd |
user=watcher,
|
|
Pierre-Yves Chibon |
9c2953 |
watch=watch_status,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
f778bd |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
f778bd |
except pagure.exceptions.PagureException as err:
|
|
Pierre-Yves Chibon |
f778bd |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
400, error_code=APIERROR.ENOCODE, error=str(err)
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
f778bd |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
f778bd |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
f778bd |
_log.exception(err)
|
|
Pierre-Yves Chibon |
9c2953 |
raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)
|
|
Pierre-Yves Chibon |
f778bd |
|
|
Pierre-Yves Chibon |
9c2953 |
return flask.jsonify({"message": msg, "status": "ok"})
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<repo>/git/modifyacls", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/<namespace>/<repo>/git/modifyacls", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route("/fork/<username>/<repo>/git/modifyacls", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
9c2953 |
@API.route(
|
|
Pierre-Yves Chibon |
9c2953 |
"/fork/<username>/<namespace>/<repo>/git/modifyacls", methods=["POST"]</repo></namespace></username>
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
@api_login_required(acls=["modify_project"])
|
|
Karsten Hopp |
be01e8 |
@api_method
|
|
Karsten Hopp |
be01e8 |
def api_modify_acls(repo, namespace=None, username=None):
|
|
Karsten Hopp |
be01e8 |
"""
|
|
Karsten Hopp |
be01e8 |
Modify ACLs on a project
|
|
Karsten Hopp |
be01e8 |
------------------------
|
|
Karsten Hopp |
be01e8 |
Add, remove or update ACLs on a project for a particular user or group.
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
This is restricted to project admins.
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
::
|
|
Karsten Hopp |
be01e8 |
|
|
Igor Gnatenko |
39113c |
POST /api/0/<repo>/git/modifyacls</repo>
|
|
Igor Gnatenko |
39113c |
POST /api/0/<namespace>/<repo>/git/modifyacls</repo></namespace>
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
::
|
|
Karsten Hopp |
be01e8 |
|
|
Igor Gnatenko |
39113c |
POST /api/0/fork/<username>/<repo>/git/modifyacls</repo></username>
|
|
Igor Gnatenko |
39113c |
POST /api/0/fork/<username>/<namespace>/<repo>/git/modifyacls</repo></namespace></username>
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
Input
|
|
Karsten Hopp |
be01e8 |
^^^^^
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
+------------------+---------+---------------+---------------------------+
|
|
Karsten Hopp |
be01e8 |
| Key | Type | Optionality | Description |
|
|
Karsten Hopp |
be01e8 |
+==================+=========+===============+===========================+
|
|
Karsten Hopp |
be01e8 |
| ``user_type`` | String | Mandatory | A string to specify if |
|
|
Karsten Hopp |
be01e8 |
| | | | the ACL should be changed |
|
|
Karsten Hopp |
be01e8 |
| | | | for a user or a group. |
|
|
Karsten Hopp |
be01e8 |
| | | | Specifying one of either |
|
|
Karsten Hopp |
be01e8 |
| | | | 'user' or 'group' is |
|
|
Karsten Hopp |
be01e8 |
| | | | mandatory |
|
|
Karsten Hopp |
be01e8 |
| | | | |
|
|
Karsten Hopp |
be01e8 |
+------------------+---------+---------------+---------------------------+
|
|
Karsten Hopp |
be01e8 |
| ``name`` | String | Mandatory | The name of the user or |
|
|
Karsten Hopp |
be01e8 |
| | | | group whose ACL |
|
|
Karsten Hopp |
be01e8 |
| | | | should be changed. |
|
|
Karsten Hopp |
be01e8 |
| | | | |
|
|
Karsten Hopp |
be01e8 |
+------------------+---------+---------------+---------------------------+
|
|
Pierre-Yves Chibon |
6ffde7 |
| ``acl`` | String | Optional | Can be either unspecified,|
|
|
Karsten Hopp |
be01e8 |
| | | | 'ticket', 'commit', |
|
|
Pierre-Yves Chibon |
6ffde7 |
| | | | 'admin'. If unspecified, |
|
|
Pierre-Yves Chibon |
6ffde7 |
| | | | the access will be removed|
|
|
Karsten Hopp |
be01e8 |
| | | | |
|
|
Karsten Hopp |
be01e8 |
+------------------+---------+---------------+---------------------------+
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
Sample response
|
|
Karsten Hopp |
be01e8 |
^^^^^^^^^^^^^^^
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
::
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
{
|
|
Karsten Hopp |
be01e8 |
"access_groups": {
|
|
Karsten Hopp |
be01e8 |
"admin": [],
|
|
Karsten Hopp |
be01e8 |
"commit": [],
|
|
Karsten Hopp |
be01e8 |
"ticket": []
|
|
Karsten Hopp |
be01e8 |
},
|
|
Karsten Hopp |
be01e8 |
"access_users": {
|
|
Karsten Hopp |
be01e8 |
"admin": [],
|
|
Karsten Hopp |
be01e8 |
"commit": [
|
|
Karsten Hopp |
be01e8 |
"ta2"
|
|
Karsten Hopp |
be01e8 |
],
|
|
Karsten Hopp |
be01e8 |
"owner": [
|
|
Karsten Hopp |
be01e8 |
"karsten"
|
|
Karsten Hopp |
be01e8 |
],
|
|
Karsten Hopp |
be01e8 |
"ticket": [
|
|
Karsten Hopp |
be01e8 |
"ta1"
|
|
Karsten Hopp |
be01e8 |
]
|
|
Karsten Hopp |
be01e8 |
},
|
|
Karsten Hopp |
be01e8 |
"close_status": [],
|
|
Karsten Hopp |
be01e8 |
"custom_keys": [],
|
|
Karsten Hopp |
be01e8 |
"date_created": "1531131619",
|
|
Karsten Hopp |
be01e8 |
"date_modified": "1531302337",
|
|
Karsten Hopp |
be01e8 |
"description": "pagure local instance",
|
|
Karsten Hopp |
be01e8 |
"fullname": "pagure",
|
|
Karsten Hopp |
be01e8 |
"id": 1,
|
|
Karsten Hopp |
be01e8 |
"milestones": {},
|
|
Karsten Hopp |
be01e8 |
"name": "pagure",
|
|
Karsten Hopp |
be01e8 |
"namespace": null,
|
|
Karsten Hopp |
be01e8 |
"parent": null,
|
|
Karsten Hopp |
be01e8 |
"priorities": {},
|
|
Karsten Hopp |
be01e8 |
"tags": [],
|
|
Karsten Hopp |
be01e8 |
"url_path": "pagure",
|
|
Karsten Hopp |
be01e8 |
"user": {
|
|
Karsten Hopp |
be01e8 |
"fullname": "KH",
|
|
Karsten Hopp |
be01e8 |
"name": "karsten"
|
|
Karsten Hopp |
be01e8 |
}
|
|
Karsten Hopp |
be01e8 |
}
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
"""
|
|
Karsten Hopp |
be01e8 |
output = {}
|
|
Karsten Hopp |
be01e8 |
|
|
Pierre-Yves Chibon |
01d0f2 |
project = _get_repo(repo, username, namespace)
|
|
Pierre-Yves Chibon |
01d0f2 |
_check_token(project, project_token=False)
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
form = pagure.forms.ModifyACLForm(csrf_enabled=False)
|
|
Karsten Hopp |
be01e8 |
if form.validate_on_submit():
|
|
Pierre-Yves Chibon |
6ffde7 |
acl = form.acl.data
|
|
Pierre-Yves Chibon |
6ffde7 |
group = None
|
|
Pierre-Yves Chibon |
6ffde7 |
user = None
|
|
Pierre-Yves Chibon |
9c2953 |
if form.user_type.data == "user":
|
|
Karsten Hopp |
be01e8 |
user = form.name.data
|
|
Karsten Hopp |
be01e8 |
else:
|
|
Karsten Hopp |
be01e8 |
group = form.name.data
|
|
Pierre-Yves Chibon |
6ffde7 |
|
|
Pierre-Yves Chibon |
6ffde7 |
is_site_admin = pagure.utils.is_admin()
|
|
Pierre-Yves Chibon |
9c2953 |
admins = [u.username for u in project.get_project_users("admin")]
|
|
Pierre-Yves Chibon |
6ffde7 |
|
|
Pierre-Yves Chibon |
6ffde7 |
if not acl:
|
|
Pierre-Yves Chibon |
9c2953 |
if (
|
|
Pierre-Yves Chibon |
9c2953 |
user
|
|
Pierre-Yves Chibon |
9c2953 |
and flask.g.fas_user.username != user
|
|
Pierre-Yves Chibon |
9c2953 |
and flask.g.fas_user.username not in admins
|
|
Pierre-Yves Chibon |
9c2953 |
and flask.g.fas_user.username != project.user.username
|
|
Pierre-Yves Chibon |
9c2953 |
and not is_site_admin
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
6ffde7 |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
401, error_code=APIERROR.EMODIFYPROJECTNOTALLOWED
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
9c2953 |
elif (
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.fas_user.username not in admins
|
|
Pierre-Yves Chibon |
9c2953 |
and flask.g.fas_user.username != project.user.username
|
|
Pierre-Yves Chibon |
9c2953 |
and not is_site_admin
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
6ffde7 |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
401, error_code=APIERROR.EMODIFYPROJECTNOTALLOWED
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
if user:
|
|
Pierre-Yves Chibon |
930073 |
user_obj = pagure.lib.query.search_user(
|
|
Pierre-Yves Chibon |
930073 |
flask.g.session, username=user
|
|
Pierre-Yves Chibon |
930073 |
)
|
|
Karsten Hopp |
be01e8 |
if not user_obj:
|
|
Karsten Hopp |
be01e8 |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
404, error_code=APIERROR.ENOUSER
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
elif group:
|
|
Pierre-Yves Chibon |
930073 |
group_obj = pagure.lib.query.search_groups(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session, group_name=group
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Karsten Hopp |
be01e8 |
if not group_obj:
|
|
Karsten Hopp |
be01e8 |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
404, error_code=APIERROR.ENOGROUP
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Karsten Hopp |
be01e8 |
|
|
Pierre-Yves Chibon |
6ffde7 |
if acl:
|
|
Pierre-Yves Chibon |
9c2953 |
if (
|
|
Pierre-Yves Chibon |
9c2953 |
user
|
|
Pierre-Yves Chibon |
9c2953 |
and user_obj not in project.access_users[acl]
|
|
Pierre-Yves Chibon |
9c2953 |
and user_obj.user != project.user.user
|
|
Pierre-Yves Chibon |
9c2953 |
):
|
|
Pierre-Yves Chibon |
6ffde7 |
_log.info(
|
|
Pierre-Yves Chibon |
9c2953 |
"Adding user %s to project: %s", user, project.fullname
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
930073 |
pagure.lib.query.add_user_to_project(
|
|
Pierre-Yves Chibon |
6ffde7 |
session=flask.g.session,
|
|
Pierre-Yves Chibon |
6ffde7 |
project=project,
|
|
Pierre-Yves Chibon |
6ffde7 |
new_user=user,
|
|
Pierre-Yves Chibon |
6ffde7 |
user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
9c2953 |
access=acl,
|
|
Pierre-Yves Chibon |
6ffde7 |
)
|
|
Pierre-Yves Chibon |
6ffde7 |
elif group and group_obj not in project.access_groups[acl]:
|
|
Pierre-Yves Chibon |
6ffde7 |
_log.info(
|
|
Pierre-Yves Chibon |
9c2953 |
"Adding group %s to project: %s", group, project.fullname
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
930073 |
pagure.lib.query.add_group_to_project(
|
|
Pierre-Yves Chibon |
6ffde7 |
session=flask.g.session,
|
|
Pierre-Yves Chibon |
6ffde7 |
project=project,
|
|
Pierre-Yves Chibon |
6ffde7 |
new_group=group,
|
|
Pierre-Yves Chibon |
6ffde7 |
user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
6ffde7 |
access=acl,
|
|
Pierre-Yves Chibon |
9c2953 |
create=pagure_config.get("ENABLE_GROUP_MNGT", False),
|
|
Pierre-Yves Chibon |
6ffde7 |
is_admin=pagure.utils.is_admin(),
|
|
Pierre-Yves Chibon |
6ffde7 |
)
|
|
Pierre-Yves Chibon |
6ffde7 |
else:
|
|
Pierre-Yves Chibon |
6ffde7 |
if user:
|
|
Pierre-Yves Chibon |
6ffde7 |
_log.info(
|
|
Pierre-Yves Chibon |
9c2953 |
"Looking at removing user %s from project %s",
|
|
Pierre-Yves Chibon |
9c2953 |
user,
|
|
Pierre-Yves Chibon |
9c2953 |
project.fullname,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
6ffde7 |
try:
|
|
Pierre-Yves Chibon |
930073 |
pagure.lib.query.remove_user_of_project(
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.session,
|
|
Pierre-Yves Chibon |
9c2953 |
user_obj,
|
|
Pierre-Yves Chibon |
9c2953 |
project,
|
|
Pierre-Yves Chibon |
9c2953 |
flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
6ffde7 |
except pagure.exceptions.PagureException as err:
|
|
Pierre-Yves Chibon |
6ffde7 |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
400, error_code=APIERROR.EINVALIDREQ, errors="%s" % err
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Pierre-Yves Chibon |
6ffde7 |
elif group:
|
|
Pierre-Yves Chibon |
6ffde7 |
pass
|
|
Pierre-Yves Chibon |
6ffde7 |
|
|
Karsten Hopp |
be01e8 |
try:
|
|
Karsten Hopp |
be01e8 |
flask.g.session.commit()
|
|
Karsten Hopp |
be01e8 |
except pagure.exceptions.PagureException as msg:
|
|
Karsten Hopp |
be01e8 |
flask.g.session.rollback()
|
|
Karsten Hopp |
be01e8 |
_log.debug(msg)
|
|
Pierre-Yves Chibon |
9c2953 |
flask.flash(str(msg), "error")
|
|
Karsten Hopp |
be01e8 |
except SQLAlchemyError as err:
|
|
Karsten Hopp |
be01e8 |
_log.exception(err)
|
|
Karsten Hopp |
be01e8 |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
9c2953 |
raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
pagure.lib.git.generate_gitolite_acls(project=project)
|
|
Karsten Hopp |
be01e8 |
output = project.to_json(api=True, public=True)
|
|
Karsten Hopp |
be01e8 |
else:
|
|
Karsten Hopp |
be01e8 |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
9c2953 |
400, error_code=APIERROR.EINVALIDREQ, errors=form.errors
|
|
Pierre-Yves Chibon |
9c2953 |
)
|
|
Karsten Hopp |
be01e8 |
|
|
Karsten Hopp |
be01e8 |
jsonout = flask.jsonify(output)
|
|
Karsten Hopp |
be01e8 |
return jsonout
|
|
Pierre-Yves Chibon |
0ede45 |
|
|
Pierre-Yves Chibon |
0ede45 |
|
|
Pierre-Yves Chibon |
0ede45 |
@API.route("/<repo>/options", methods=["GET"])</repo>
|
|
Pierre-Yves Chibon |
0ede45 |
@API.route("/<namespace>/<repo>/options", methods=["GET"])</repo></namespace>
|
|
Pierre-Yves Chibon |
0ede45 |
@API.route("/fork/<username>/<repo>/options", methods=["GET"])</repo></username>
|
|
Pierre-Yves Chibon |
0ede45 |
@API.route("/fork/<username>/<namespace>/<repo>/options", methods=["GET"])</repo></namespace></username>
|
|
Pierre-Yves Chibon |
0ede45 |
@api_login_required(acls=["modify_project"])
|
|
Pierre-Yves Chibon |
0ede45 |
@api_method
|
|
Pierre-Yves Chibon |
0ede45 |
def api_get_project_options(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
0ede45 |
"""
|
|
Pierre-Yves Chibon |
0ede45 |
Get project options
|
|
Pierre-Yves Chibon |
0ede45 |
----------------------
|
|
Pierre-Yves Chibon |
0ede45 |
Allow project admins to retrieve the current options of a project.
|
|
Pierre-Yves Chibon |
0ede45 |
|
|
Pierre-Yves Chibon |
0ede45 |
::
|
|
Pierre-Yves Chibon |
0ede45 |
|
|
Pierre-Yves Chibon |
0ede45 |
GET /api/0/<repo>/options</repo>
|
|
Pierre-Yves Chibon |
0ede45 |
GET /api/0/<namespace>/<repo>/options</repo></namespace>
|
|
Pierre-Yves Chibon |
0ede45 |
|
|
Pierre-Yves Chibon |
0ede45 |
::
|
|
Pierre-Yves Chibon |
0ede45 |
|
|
Pierre-Yves Chibon |
0ede45 |
GET /api/0/fork/<username>/<repo>/options</repo></username>
|
|
Pierre-Yves Chibon |
0ede45 |
GET /api/0/fork/<username>/<namespace>/<repo>/options</repo></namespace></username>
|
|
Pierre-Yves Chibon |
0ede45 |
|
|
Pierre-Yves Chibon |
0ede45 |
Sample response
|
|
Pierre-Yves Chibon |
0ede45 |
^^^^^^^^^^^^^^^
|
|
Pierre-Yves Chibon |
0ede45 |
|
|
Pierre-Yves Chibon |
0ede45 |
::
|
|
Pierre-Yves Chibon |
0ede45 |
|
|
Pierre-Yves Chibon |
0ede45 |
{
|
|
Pierre-Yves Chibon |
0ede45 |
"settings": {
|
|
Pierre-Yves Chibon |
0ede45 |
"Enforce_signed-off_commits_in_pull-request": false,
|
|
Pierre-Yves Chibon |
0ede45 |
"Minimum_score_to_merge_pull-request": -1,
|
|
Pierre-Yves Chibon |
0ede45 |
"Only_assignee_can_merge_pull-request": false,
|
|
Pierre-Yves Chibon |
0ede45 |
"Web-hooks": null,
|
|
Pierre-Yves Chibon |
0ede45 |
"always_merge": false,
|
|
Pierre-Yves Chibon |
0ede45 |
"disable_non_fast-forward_merges": false,
|
|
Pierre-Yves Chibon |
0ede45 |
"fedmsg_notifications": true,
|
|
Pierre-Yves Chibon |
0ede45 |
"issue_tracker": true,
|
|
Pierre-Yves Chibon |
0ede45 |
"issue_tracker_read_only": false,
|
|
Pierre-Yves Chibon |
0ede45 |
"issues_default_to_private": false,
|
|
Pierre-Yves Chibon |
0ede45 |
"notify_on_commit_flag": false,
|
|
Pierre-Yves Chibon |
0ede45 |
"notify_on_pull-request_flag": false,
|
|
Pierre-Yves Chibon |
0ede45 |
"open_metadata_access_to_all": false,
|
|
Pierre-Yves Chibon |
0ede45 |
"project_documentation": false,
|
|
Pierre-Yves Chibon |
0ede45 |
"pull_request_access_only": false,
|
|
Pierre-Yves Chibon |
0ede45 |
"pull_requests": true,
|
|
Pierre-Yves Chibon |
0ede45 |
"stomp_notifications": true
|
|
Pierre-Yves Chibon |
0ede45 |
},
|
|
Pierre-Yves Chibon |
0ede45 |
"status": "ok"
|
|
Pierre-Yves Chibon |
0ede45 |
}
|
|
Pierre-Yves Chibon |
0ede45 |
|
|
Pierre-Yves Chibon |
0ede45 |
"""
|
|
Pierre-Yves Chibon |
01d0f2 |
project = _get_repo(repo, username, namespace)
|
|
Pierre-Yves Chibon |
01d0f2 |
_check_token(project, project_token=False)
|
|
Pierre-Yves Chibon |
0ede45 |
|
|
Pierre-Yves Chibon |
0ede45 |
return flask.jsonify({"settings": project.settings, "status": "ok"})
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Fabien Boucher |
dfb30c |
@API.route("/<repo>/connector", methods=["GET"])</repo>
|
|
Fabien Boucher |
dfb30c |
@API.route("/<namespace>/<repo>/connector", methods=["GET"])</repo></namespace>
|
|
Fabien Boucher |
dfb30c |
@API.route("/fork/<username>/<repo>/connector", methods=["GET"])</repo></username>
|
|
Fabien Boucher |
dfb30c |
@API.route("/fork/<username>/<namespace>/<repo>/connector", methods=["GET"])</repo></namespace></username>
|
|
Fabien Boucher |
dfb30c |
@api_login_required(acls=["modify_project"])
|
|
Fabien Boucher |
dfb30c |
@api_method
|
|
Fabien Boucher |
dfb30c |
def api_get_project_connector(repo, username=None, namespace=None):
|
|
Fabien Boucher |
dfb30c |
"""
|
|
Fabien Boucher |
dfb30c |
Get project connector
|
|
Fabien Boucher |
dfb30c |
---------------------
|
|
Fabien Boucher |
0bccc8 |
Allow project owners and admins to retrieve their own connector tokens.
|
|
Fabien Boucher |
dfb30c |
Connector tokens are the API tokens and the Web Hook token
|
|
Fabien Boucher |
dfb30c |
of the project. Connector tokens make possible for an external
|
|
Fabien Boucher |
dfb30c |
application to listen and verify project notifications and act
|
|
Fabien Boucher |
dfb30c |
on project via the REST API.
|
|
Fabien Boucher |
dfb30c |
|
|
Fabien Boucher |
dfb30c |
::
|
|
Fabien Boucher |
dfb30c |
|
|
Fabien Boucher |
dfb30c |
GET /api/0/<repo>/connector</repo>
|
|
Fabien Boucher |
dfb30c |
GET /api/0/<namespace>/<repo>/connector</repo></namespace>
|
|
Fabien Boucher |
dfb30c |
|
|
Fabien Boucher |
dfb30c |
::
|
|
Fabien Boucher |
dfb30c |
|
|
Fabien Boucher |
dfb30c |
GET /api/0/fork/<username>/<repo>/connector</repo></username>
|
|
Fabien Boucher |
dfb30c |
GET /api/0/fork/<username>/<namespace>/<repo>/connector</repo></namespace></username>
|
|
Fabien Boucher |
dfb30c |
|
|
Fabien Boucher |
dfb30c |
Sample response
|
|
Fabien Boucher |
dfb30c |
^^^^^^^^^^^^^^^
|
|
Fabien Boucher |
dfb30c |
|
|
Fabien Boucher |
dfb30c |
::
|
|
Fabien Boucher |
dfb30c |
|
|
Fabien Boucher |
dfb30c |
{
|
|
Fabien Boucher |
dfb30c |
"connector": {
|
|
Fabien Boucher |
dfb30c |
"hook_token": "aaabbbccc",
|
|
Fabien Boucher |
dfb30c |
"api_token": [
|
|
Fabien Boucher |
0bccc8 |
{'name': 'foo token',
|
|
Fabien Boucher |
0bccc8 |
'id': "abcdefoo",
|
|
Fabien Boucher |
0bccc8 |
'expired': True}
|
|
Fabien Boucher |
0bccc8 |
{'name': 'bar token',
|
|
Fabien Boucher |
0bccc8 |
'id': "abcdebar",
|
|
Fabien Boucher |
0bccc8 |
'expired': False}
|
|
Fabien Boucher |
dfb30c |
]
|
|
Fabien Boucher |
dfb30c |
},
|
|
Fabien Boucher |
dfb30c |
"status": "ok"
|
|
Fabien Boucher |
dfb30c |
}
|
|
Fabien Boucher |
dfb30c |
|
|
Fabien Boucher |
dfb30c |
"""
|
|
Pierre-Yves Chibon |
01d0f2 |
project = _get_repo(repo, username, namespace)
|
|
Pierre-Yves Chibon |
01d0f2 |
_check_token(project, project_token=False)
|
|
Fabien Boucher |
dfb30c |
|
|
Fabien Boucher |
dfb30c |
authorized_users = [project.user.username]
|
|
Fabien Boucher |
dfb30c |
authorized_users.extend(
|
|
Karsten Hopp |
6ce2d7 |
[user.user for user in project.access_users["admin"]]
|
|
Karsten Hopp |
6ce2d7 |
)
|
|
Fabien Boucher |
dfb30c |
if flask.g.fas_user.user not in authorized_users:
|
|
Fabien Boucher |
dfb30c |
raise pagure.exceptions.APIError(
|
|
Karsten Hopp |
6ce2d7 |
401, error_code=APIERROR.ENOTHIGHENOUGH
|
|
Karsten Hopp |
6ce2d7 |
)
|
|
Fabien Boucher |
dfb30c |
|
|
Fabien Boucher |
dfb30c |
user_obj = pagure.lib.query.search_user(
|
|
Karsten Hopp |
6ce2d7 |
flask.g.session, username=flask.g.fas_user.user
|
|
Karsten Hopp |
6ce2d7 |
)
|
|
Fabien Boucher |
dfb30c |
user_project_tokens = [
|
|
Karsten Hopp |
6ce2d7 |
token for token in user_obj.tokens if token.project_id == project.id
|
|
Karsten Hopp |
6ce2d7 |
]
|
|
Fabien Boucher |
dfb30c |
|
|
Fabien Boucher |
dfb30c |
connector = {
|
|
Karsten Hopp |
6ce2d7 |
"hook_token": project.hook_token,
|
|
Karsten Hopp |
6ce2d7 |
"api_tokens": [
|
|
Karsten Hopp |
6ce2d7 |
{"description": t.description, "id": t.id, "expired": t.expired}
|
|
Karsten Hopp |
6ce2d7 |
for t in user_project_tokens
|
|
Karsten Hopp |
6ce2d7 |
],
|
|
Fabien Boucher |
dfb30c |
}
|
|
Fabien Boucher |
dfb30c |
|
|
Fabien Boucher |
dfb30c |
return flask.jsonify({"connector": connector, "status": "ok"})
|
|
Fabien Boucher |
dfb30c |
|
|
Fabien Boucher |
dfb30c |
|
|
Pierre-Yves Chibon |
473ccb |
def _check_value(value):
|
|
Pierre-Yves Chibon |
473ccb |
""" Convert the provided value into a boolean, an int or leave it as it.
|
|
Pierre-Yves Chibon |
473ccb |
"""
|
|
Pierre-Yves Chibon |
473ccb |
if str(value).lower() in ["true"]:
|
|
Pierre-Yves Chibon |
473ccb |
value = True
|
|
Pierre-Yves Chibon |
473ccb |
elif str(value).lower() in ["false"]:
|
|
Pierre-Yves Chibon |
473ccb |
value = True
|
|
Pierre-Yves Chibon |
ade066 |
elif str(value).isdigit():
|
|
Pierre-Yves Chibon |
473ccb |
value = int(value)
|
|
Pierre-Yves Chibon |
473ccb |
return value
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
@API.route("/<repo>/options/update", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
473ccb |
@API.route("/<namespace>/<repo>/options/update", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
473ccb |
@API.route("/fork/<username>/<repo>/options/update", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
473ccb |
@API.route(
|
|
Pierre-Yves Chibon |
473ccb |
"/fork/<username>/<namespace>/<repo>/options/update", methods=["POST"]</repo></namespace></username>
|
|
Pierre-Yves Chibon |
473ccb |
)
|
|
Pierre-Yves Chibon |
473ccb |
@api_login_required(acls=["modify_project"])
|
|
Pierre-Yves Chibon |
473ccb |
@api_method
|
|
Pierre-Yves Chibon |
473ccb |
def api_modify_project_options(repo, username=None, namespace=None):
|
|
Pierre-Yves Chibon |
473ccb |
"""
|
|
Pierre-Yves Chibon |
473ccb |
Update project options
|
|
Pierre-Yves Chibon |
473ccb |
----------------------
|
|
Pierre-Yves Chibon |
473ccb |
Allow project admins to modify the options of a project.
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
::
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
POST /api/0/<repo>/options/update</repo>
|
|
Pierre-Yves Chibon |
473ccb |
POST /api/0/<namespace>/<repo>/options/update</repo></namespace>
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
::
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
POST /api/0/fork/<username>/<repo>/options/update</repo></username>
|
|
Pierre-Yves Chibon |
473ccb |
POST /api/0/fork/<username>/<namespace>/<repo>/options/update</repo></namespace></username>
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
Input
|
|
Pierre-Yves Chibon |
473ccb |
^^^^^
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
Simply specify the key/values you would like to set. Beware that if you
|
|
Pierre-Yves Chibon |
473ccb |
do not specify in the request values that have been changed before they
|
|
Pierre-Yves Chibon |
473ccb |
will go back to their default value.
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
Sample response
|
|
Pierre-Yves Chibon |
473ccb |
^^^^^^^^^^^^^^^
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
::
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
{
|
|
Pierre-Yves Chibon |
473ccb |
'message': 'Edited successfully settings of repo: test',
|
|
Pierre-Yves Chibon |
473ccb |
'status': 'ok'
|
|
Pierre-Yves Chibon |
473ccb |
}
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
"""
|
|
Pierre-Yves Chibon |
01d0f2 |
project = _get_repo(repo, username, namespace)
|
|
Pierre-Yves Chibon |
01d0f2 |
_check_token(project, project_token=False)
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
settings = {}
|
|
Pierre-Yves Chibon |
473ccb |
for key in flask.request.form:
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
settings[key] = _check_value(flask.request.form[key])
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
try:
|
|
Pierre-Yves Chibon |
473ccb |
message = pagure.lib.query.update_project_settings(
|
|
Pierre-Yves Chibon |
473ccb |
flask.g.session,
|
|
Pierre-Yves Chibon |
473ccb |
repo=project,
|
|
Pierre-Yves Chibon |
473ccb |
settings=settings,
|
|
Pierre-Yves Chibon |
473ccb |
user=flask.g.fas_user.username,
|
|
Pierre-Yves Chibon |
473ccb |
from_api=True,
|
|
Pierre-Yves Chibon |
473ccb |
)
|
|
Pierre-Yves Chibon |
473ccb |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
473ccb |
except pagure.exceptions.PagureException as err:
|
|
Pierre-Yves Chibon |
473ccb |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
473ccb |
400, error_code=APIERROR.ENOCODE, error=str(err)
|
|
Pierre-Yves Chibon |
473ccb |
)
|
|
Pierre-Yves Chibon |
473ccb |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
473ccb |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
473ccb |
_log.exception(err)
|
|
Pierre-Yves Chibon |
473ccb |
raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)
|
|
Pierre-Yves Chibon |
473ccb |
|
|
Pierre-Yves Chibon |
473ccb |
return flask.jsonify({"message": message, "status": "ok"})
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
41bac9 |
|
|
Fabien Boucher |
1a6b69 |
@API.route("/<repo>/token/new", methods=["POST"])</repo>
|
|
Fabien Boucher |
1a6b69 |
@API.route("/<namespace>/<repo>/token/new", methods=["POST"])</repo></namespace>
|
|
Fabien Boucher |
1a6b69 |
@API.route("/fork/<username>/<repo>/token/new", methods=["POST"])</repo></username>
|
|
Fabien Boucher |
032e3d |
@API.route("/fork/<username>/<namespace>/<repo>/token/new", methods=["POST"])</repo></namespace></username>
|
|
Fabien Boucher |
0bf7de |
@api_login_required(acls=["modify_project"])
|
|
Fabien Boucher |
0bf7de |
@api_method
|
|
Fabien Boucher |
0bf7de |
def api_project_create_api_token(repo, namespace=None, username=None):
|
|
Fabien Boucher |
0bf7de |
"""
|
|
Fabien Boucher |
0bf7de |
Create API project Token
|
|
Fabien Boucher |
0bf7de |
------------------------
|
|
Fabien Boucher |
0bf7de |
Create a project token API for the caller user
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
0bf7de |
This is restricted to project admins.
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
0bf7de |
::
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
1a6b69 |
POST /api/0/<repo>/token/new</repo>
|
|
Fabien Boucher |
1a6b69 |
POST /api/0/<namespace>/<repo>/token/new</repo></namespace>
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
0bf7de |
::
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
1a6b69 |
POST /api/0/fork/<username>/<repo>/token/new</repo></username>
|
|
Fabien Boucher |
1a6b69 |
POST /api/0/fork/<username>/<namespace>/<repo>/token/new</repo></namespace></username>
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
0bf7de |
Input
|
|
Fabien Boucher |
0bf7de |
^^^^^
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
0bf7de |
+------------------+---------+---------------+---------------------------+
|
|
Fabien Boucher |
0bf7de |
| Key | Type | Optionality | Description |
|
|
Fabien Boucher |
0bf7de |
+==================+=========+===============+===========================+
|
|
Fabien Boucher |
53b792 |
| ``description`` | String | optional | A string to specify the |
|
|
Fabien Boucher |
0bf7de |
| | | | description of the token |
|
|
Fabien Boucher |
0bf7de |
| | | | |
|
|
Fabien Boucher |
0bf7de |
+------------------+---------+---------------+---------------------------+
|
|
Fabien Boucher |
53b792 |
| ``acls`` | List | Mandatory | The ACLs |
|
|
Fabien Boucher |
0bf7de |
| | | | |
|
|
Fabien Boucher |
0bf7de |
+------------------+---------+---------------+---------------------------+
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
0bf7de |
Sample response
|
|
Fabien Boucher |
0bf7de |
^^^^^^^^^^^^^^^
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
0bf7de |
::
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
0bf7de |
{
|
|
Fabien Boucher |
0bf7de |
"token": {
|
|
Fabien Boucher |
0bf7de |
"description": "My foo token",
|
|
Fabien Boucher |
0bf7de |
"id": "aaabbbcccfootoken",
|
|
Fabien Boucher |
0bf7de |
},
|
|
Fabien Boucher |
0bf7de |
}
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
0bf7de |
"""
|
|
Fabien Boucher |
0bf7de |
output = {}
|
|
Fabien Boucher |
0bf7de |
|
|
Pierre-Yves Chibon |
01d0f2 |
project = _get_repo(repo, username, namespace)
|
|
Pierre-Yves Chibon |
01d0f2 |
_check_token(project, project_token=False)
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
0bf7de |
authorized_users = [project.user.username]
|
|
Fabien Boucher |
0bf7de |
authorized_users.extend(
|
|
Pierre-Yves Chibon |
3b2728 |
[user.user for user in project.access_users["admin"]]
|
|
Pierre-Yves Chibon |
3b2728 |
)
|
|
Fabien Boucher |
0bf7de |
if flask.g.fas_user.user not in authorized_users:
|
|
Fabien Boucher |
0bf7de |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
3b2728 |
401, error_code=APIERROR.ENOTHIGHENOUGH
|
|
Pierre-Yves Chibon |
3b2728 |
)
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
579887 |
authorized_acls = pagure_config.get("USER_ACLS", [])
|
|
Pierre-Yves Chibon |
3b2728 |
form = pagure.forms.NewTokenForm(csrf_enabled=False, sacls=authorized_acls)
|
|
Fabien Boucher |
53b792 |
if form.validate_on_submit():
|
|
Fabien Boucher |
53b792 |
acls = form.acls.data
|
|
Fabien Boucher |
53b792 |
description = form.description.data
|
|
Fabien Boucher |
53b792 |
else:
|
|
Fabien Boucher |
0bf7de |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
3b2728 |
400, error_code=APIERROR.EINVALIDREQ, errors=form.errors
|
|
Pierre-Yves Chibon |
3b2728 |
)
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
579887 |
token = pagure.lib.query.add_token_to_user(
|
|
Pierre-Yves Chibon |
3b2728 |
flask.g.session, project, acls, flask.g.fas_user.user, description
|
|
Pierre-Yves Chibon |
3b2728 |
)
|
|
Pierre-Yves Chibon |
3b2728 |
output = {"token": {"description": token.description, "id": token.id}}
|
|
Fabien Boucher |
0bf7de |
|
|
Fabien Boucher |
0bf7de |
jsonout = flask.jsonify(output)
|
|
Fabien Boucher |
0bf7de |
return jsonout
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
@API.route("/<repo>/blockuser", methods=["POST"])</repo>
|
|
Pierre-Yves Chibon |
4b7c3e |
@API.route("/<namespace>/<repo>/blockuser", methods=["POST"])</repo></namespace>
|
|
Pierre-Yves Chibon |
4b7c3e |
@API.route("/fork/<username>/<repo>/blockuser", methods=["POST"])</repo></username>
|
|
Pierre-Yves Chibon |
4b7c3e |
@API.route("/fork/<username>/<namespace>/<repo>/blockuser", methods=["POST"])</repo></namespace></username>
|
|
Pierre-Yves Chibon |
4b7c3e |
@api_login_required(acls=["modify_project"])
|
|
Pierre-Yves Chibon |
4b7c3e |
@api_method
|
|
Pierre-Yves Chibon |
4b7c3e |
def api_project_block_user(repo, namespace=None, username=None):
|
|
Pierre-Yves Chibon |
4b7c3e |
"""
|
|
Pierre-Yves Chibon |
4b7c3e |
Block an user from a project
|
|
Pierre-Yves Chibon |
4b7c3e |
----------------------------
|
|
Pierre-Yves Chibon |
4b7c3e |
Block an user from interacting with the project
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
This is restricted to project admins.
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
::
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
POST /api/0/<repo>/blockuser</repo>
|
|
Pierre-Yves Chibon |
4b7c3e |
POST /api/0/<namespace>/<repo>/blockuser</repo></namespace>
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
::
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
POST /api/0/fork/<username>/<repo>/blockuser</repo></username>
|
|
Pierre-Yves Chibon |
4b7c3e |
POST /api/0/fork/<username>/<namespace>/<repo>/blockuser</repo></namespace></username>
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
Input
|
|
Pierre-Yves Chibon |
4b7c3e |
^^^^^
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
+------------------+---------+---------------+---------------------------+
|
|
Pierre-Yves Chibon |
4b7c3e |
| Key | Type | Optionality | Description |
|
|
Pierre-Yves Chibon |
4b7c3e |
+==================+=========+===============+===========================+
|
|
Pierre-Yves Chibon |
4b7c3e |
| ``username`` | String | optional | The username of the user |
|
|
Pierre-Yves Chibon |
4b7c3e |
| | | | to block on this project |
|
|
Pierre-Yves Chibon |
4b7c3e |
+------------------+---------+---------------+---------------------------+
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
Beware that this API endpoint updates **all** the users blocked in the
|
|
Pierre-Yves Chibon |
4b7c3e |
project, so if you are updating this list, do not submit just one username,
|
|
Pierre-Yves Chibon |
4b7c3e |
submit the updated list.
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
Sample response
|
|
Pierre-Yves Chibon |
4b7c3e |
^^^^^^^^^^^^^^^
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
::
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
{"message": "User(s) blocked"}
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
"""
|
|
Pierre-Yves Chibon |
4b7c3e |
output = {}
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
project = _get_repo(repo, username, namespace)
|
|
Pierre-Yves Chibon |
4b7c3e |
_check_token(project)
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
authorized_users = [project.user.username]
|
|
Pierre-Yves Chibon |
4b7c3e |
authorized_users.extend(
|
|
Pierre-Yves Chibon |
4b7c3e |
[user.user for user in project.access_users["admin"]]
|
|
Pierre-Yves Chibon |
4b7c3e |
)
|
|
Pierre-Yves Chibon |
4b7c3e |
if flask.g.fas_user.username not in authorized_users:
|
|
Pierre-Yves Chibon |
4b7c3e |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
4b7c3e |
401, error_code=APIERROR.ENOTHIGHENOUGH
|
|
Pierre-Yves Chibon |
4b7c3e |
)
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
usernames = flask.request.form.getlist("username")
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
try:
|
|
Pierre-Yves Chibon |
4b7c3e |
users = set()
|
|
Pierre-Yves Chibon |
4b7c3e |
for user in usernames:
|
|
Pierre-Yves Chibon |
4b7c3e |
user = user.strip()
|
|
Pierre-Yves Chibon |
4b7c3e |
if user:
|
|
Pierre-Yves Chibon |
4b7c3e |
pagure.lib.query.get_user(flask.g.session, user)
|
|
Pierre-Yves Chibon |
4b7c3e |
users.add(user)
|
|
Pierre-Yves Chibon |
4b7c3e |
project.block_users = list(users)
|
|
Pierre-Yves Chibon |
4b7c3e |
flask.g.session.add(project)
|
|
Pierre-Yves Chibon |
4b7c3e |
flask.g.session.commit()
|
|
Pierre-Yves Chibon |
4b7c3e |
output = {"message": "User(s) blocked"}
|
|
Pierre-Yves Chibon |
4b7c3e |
except pagure.exceptions.PagureException as err:
|
|
Pierre-Yves Chibon |
4b7c3e |
raise pagure.exceptions.APIError(
|
|
Pierre-Yves Chibon |
4b7c3e |
400, error_code=APIERROR.ENOCODE, error=str(err)
|
|
Pierre-Yves Chibon |
4b7c3e |
)
|
|
Pierre-Yves Chibon |
4b7c3e |
except SQLAlchemyError as err: # pragma: no cover
|
|
Pierre-Yves Chibon |
4b7c3e |
flask.g.session.rollback()
|
|
Pierre-Yves Chibon |
4b7c3e |
_log.exception(err)
|
|
Pierre-Yves Chibon |
4b7c3e |
raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)
|
|
Pierre-Yves Chibon |
4b7c3e |
|
|
Pierre-Yves Chibon |
4b7c3e |
jsonout = flask.jsonify(output)
|
|
Pierre-Yves Chibon |
4b7c3e |
return jsonout
|