diff --git a/assets/src/bundles/admin/deposit.js b/assets/src/bundles/admin/deposit.js --- a/assets/src/bundles/admin/deposit.js +++ b/assets/src/bundles/admin/deposit.js @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2020 The Software Heritage developers + * Copyright (C) 2018-2021 The Software Heritage developers * See the AUTHORS file at the top-level directory of this distribution * License: GNU Affero General Public License version 3, or any later version * See top-level LICENSE file for more information @@ -16,7 +16,7 @@ return data; } -export function initDepositAdmin() { +export function initDepositAdmin(username, isStaff) { let depositsTable; $(document).ready(() => { $.fn.dataTable.ext.errMode = 'none'; @@ -44,6 +44,9 @@ url: Urls.admin_deposit_list(), data: d => { d.excludePattern = $('#swh-admin-deposit-list-exclude-filter').val(); + if (!isStaff) { + d.username = username; + } } }, columns: [ diff --git a/swh/web/admin/deposit.py b/swh/web/admin/deposit.py --- a/swh/web/admin/deposit.py +++ b/swh/web/admin/deposit.py @@ -6,28 +6,33 @@ import sentry_sdk from django.conf import settings -from django.contrib.admin.views.decorators import staff_member_required +from django.contrib.auth.decorators import user_passes_test from django.core.paginator import Paginator from django.http import JsonResponse from django.shortcuts import render from swh.web.admin.adminurls import admin_route +from swh.web.auth.utils import ADMIN_LIST_DEPOSIT_PERMISSION from swh.web.common.utils import get_deposits_list +def _can_list_deposits(user): + return user.is_staff or user.has_perm(ADMIN_LIST_DEPOSIT_PERMISSION) + + @admin_route(r"deposit/", view_name="admin-deposit") -@staff_member_required(view_func=None, login_url=settings.LOGIN_URL) +@user_passes_test(_can_list_deposits, login_url=settings.LOGIN_URL) def _admin_origin_save(request): return render(request, "admin/deposit.html") @admin_route(r"deposit/list/", view_name="admin-deposit-list") -@staff_member_required(view_func=None, login_url=settings.LOGIN_URL) +@user_passes_test(_can_list_deposits, login_url=settings.LOGIN_URL) def _admin_deposit_list(request): table_data = {} table_data["draw"] = int(request.GET["draw"]) try: - deposits = get_deposits_list() + deposits = get_deposits_list(request.GET.get("username")) deposits_count = len(deposits) search_value = request.GET["search[value]"] if search_value: diff --git a/swh/web/auth/utils.py b/swh/web/auth/utils.py --- a/swh/web/auth/utils.py +++ b/swh/web/auth/utils.py @@ -17,6 +17,7 @@ SWH_AMBASSADOR_PERMISSION = "swh.ambassador" API_SAVE_ORIGIN_PERMISSION = "swh.web.api.save_origin" +ADMIN_LIST_DEPOSIT_PERMISSION = "swh.web.admin.list_deposits" def _get_fernet(password: bytes, salt: bytes) -> Fernet: diff --git a/swh/web/common/utils.py b/swh/web/common/utils.py --- a/swh/web/common/utils.py +++ b/swh/web/common/utils.py @@ -23,6 +23,7 @@ from django.http import HttpRequest, QueryDict from django.urls import reverse as django_reverse +from swh.web.auth.utils import ADMIN_LIST_DEPOSIT_PERMISSION from swh.web.common.exc import BadInputExc from swh.web.common.typing import QueryParameters from swh.web.config import get_config, search @@ -285,6 +286,7 @@ ), "swh_web_version": get_distribution("swh.web").version, "iframe_mode": False, + "ADMIN_LIST_DEPOSIT_PERMISSION": ADMIN_LIST_DEPOSIT_PERMISSION, } @@ -365,27 +367,41 @@ return BeautifulSoup(html, "lxml").prettify() -def get_deposits_list() -> List[Dict[str, Any]]: +def _deposits_list_url( + deposits_list_base_url: str, page_size: int, username: Optional[str] +) -> str: + deposits_list_url = f"{deposits_list_base_url}?page_size={page_size}" + if username is not None: + deposits_list_url += f"&username={username}" + return deposits_list_url + + +def get_deposits_list(username: Optional[str] = None) -> List[Dict[str, Any]]: """Return the list of software deposits using swh-deposit API """ config = get_config()["deposit"] - deposits_list_url = config["private_api_url"] + "deposits" + deposits_list_base_url = config["private_api_url"] + "deposits" deposits_list_auth = HTTPBasicAuth( config["private_api_user"], config["private_api_password"] ) + deposits_list_url = _deposits_list_url( + deposits_list_base_url, page_size=1, username=username + ) + nb_deposits = requests.get( - "%s?page_size=1" % deposits_list_url, auth=deposits_list_auth, timeout=30 + deposits_list_url, auth=deposits_list_auth, timeout=30 ).json()["count"] - deposits_data = cache.get("swh-deposit-list") + deposits_data = cache.get(f"swh-deposit-list-{username}") if not deposits_data or deposits_data["count"] != nb_deposits: + deposits_list_url = _deposits_list_url( + deposits_list_base_url, page_size=nb_deposits, username=username + ) deposits_data = requests.get( - "%s?page_size=%s" % (deposits_list_url, nb_deposits), - auth=deposits_list_auth, - timeout=30, + deposits_list_url, auth=deposits_list_auth, timeout=30, ).json() - cache.set("swh-deposit-list", deposits_data) + cache.set(f"swh-deposit-list-{username}", deposits_data) return deposits_data["results"] diff --git a/swh/web/templates/admin/deposit.html b/swh/web/templates/admin/deposit.html --- a/swh/web/templates/admin/deposit.html +++ b/swh/web/templates/admin/deposit.html @@ -1,7 +1,7 @@ {% extends "layout.html" %} {% comment %} -Copyright (C) 2018-2019 The Software Heritage developers +Copyright (C) 2018-2021 The Software Heritage developers See the AUTHORS file at the top-level directory of this distribution License: GNU Affero General Public License version 3, or any later version See top-level LICENSE file for more information @@ -54,6 +54,6 @@

{% endblock content %} diff --git a/swh/web/templates/layout.html b/swh/web/templates/layout.html --- a/swh/web/templates/layout.html +++ b/swh/web/templates/layout.html @@ -218,14 +218,16 @@

Help

- {% if user.is_authenticated and user.is_staff %} + {% if user.is_authenticated and user.is_staff or ADMIN_LIST_DEPOSIT_PERMISSION in user.get_all_permissions %} - + {% if user.is_staff %} + + {% endif %}