diff --git a/backend/src/zango/api/platform/packages/v1/views.py b/backend/src/zango/api/platform/packages/v1/views.py index 064ffa575..6d39b53de 100644 --- a/backend/src/zango/api/platform/packages/v1/views.py +++ b/backend/src/zango/api/platform/packages/v1/views.py @@ -42,7 +42,7 @@ def get(self, request, app_uuid, *args, **kwargs): status = 500 return get_api_response(True, resp, status) try: - packages = get_all_packages(tenant.name) + packages = get_all_packages(request, tenant) if search: packages = [ obj for obj in packages if search.lower() in obj["name"].lower() diff --git a/backend/src/zango/apps/permissions/models.py b/backend/src/zango/apps/permissions/models.py index 331adc646..e41197e9a 100644 --- a/backend/src/zango/apps/permissions/models.py +++ b/backend/src/zango/apps/permissions/models.py @@ -1,7 +1,6 @@ -from django.utils import timezone - from django.db import models from django.db.models import JSONField, Q +from django.utils import timezone from zango.apps.auditlogs.registry import auditlog from zango.core.model_mixins import FullAuditMixin diff --git a/backend/src/zango/assets/error_pages/css/error403.css b/backend/src/zango/assets/error_pages/css/error403.css index 66423ebf6..dc3aa65ba 100644 --- a/backend/src/zango/assets/error_pages/css/error403.css +++ b/backend/src/zango/assets/error_pages/css/error403.css @@ -87,4 +87,4 @@ button[type='submit'] { } .each-button { margin: 10px; -} \ No newline at end of file +} diff --git a/backend/src/zango/assets/error_pages/css/error404.css b/backend/src/zango/assets/error_pages/css/error404.css index 671aa2f5e..05366a81d 100644 --- a/backend/src/zango/assets/error_pages/css/error404.css +++ b/backend/src/zango/assets/error_pages/css/error404.css @@ -87,4 +87,4 @@ } .each-button { margin: 10px; - } \ No newline at end of file + } diff --git a/backend/src/zango/assets/error_pages/css/error500.css b/backend/src/zango/assets/error_pages/css/error500.css index 50537d79e..2a006e711 100644 --- a/backend/src/zango/assets/error_pages/css/error500.css +++ b/backend/src/zango/assets/error_pages/css/error500.css @@ -86,4 +86,4 @@ button[type='submit'] { } .each-button { margin: 10px; -} \ No newline at end of file +} diff --git a/backend/src/zango/config/urls_public.py b/backend/src/zango/config/urls_public.py index 8c27618e7..496c0874b 100644 --- a/backend/src/zango/config/urls_public.py +++ b/backend/src/zango/config/urls_public.py @@ -6,6 +6,7 @@ from zango.core.decorators import internal_access_only + urlpatterns = [ re_path( r"^auth/", diff --git a/backend/src/zango/core/internal_requests.py b/backend/src/zango/core/internal_requests.py index a40682b7e..bcf71b465 100644 --- a/backend/src/zango/core/internal_requests.py +++ b/backend/src/zango/core/internal_requests.py @@ -5,6 +5,7 @@ import requests from django.db import connection +from django.http.response import HttpResponse from django.test import RequestFactory @@ -37,6 +38,8 @@ def process_internal_request(fake_request, tenant, **kwargs): ws = ws_klass(tenant, fake_request) ws.ready() view, resolve = ws.match_view(fake_request) + if not view: + return HttpResponse(status=404) response = view(fake_request, (), **kwargs) return response @@ -74,7 +77,10 @@ def internal_request_post(url, **kwargs): # Convert Django response to something that mimics requests.Response class InternalResponse: def __init__(self, django_response): - self.content = django_response.content + try: + self.content = getattr(django_response, "content", None) + except Exception: + self.content = None self.status_code = django_response.status_code def json(self): @@ -111,7 +117,10 @@ def internal_request_put(url, **kwargs): # Convert Django response to something that mimics requests.Response class InternalResponse: def __init__(self, django_response): - self.content = django_response.content + try: + self.content = getattr(django_response, "content", None) + except Exception: + self.content = None self.status_code = django_response.status_code def json(self): @@ -138,7 +147,10 @@ def internal_request_get(url, **kwargs): # Convert Django response to something that mimics requests.Response class InternalResponse: def __init__(self, django_response): - self.content = django_response.content + try: + self.content = getattr(django_response, "content", None) + except Exception: + self.content = None self.status_code = django_response.status_code def json(self): @@ -175,7 +187,10 @@ def internal_request_delete(url, **kwargs): # Convert Django response to something that mimics requests.Response class InternalResponse: def __init__(self, django_response): - self.content = django_response.content + try: + self.content = getattr(django_response, "content", None) + except Exception: + self.content = None self.status_code = django_response.status_code def json(self): diff --git a/backend/src/zango/core/package_utils.py b/backend/src/zango/core/package_utils.py index 7871c338b..836c70675 100644 --- a/backend/src/zango/core/package_utils.py +++ b/backend/src/zango/core/package_utils.py @@ -5,12 +5,14 @@ import zipfile import boto3 +import requests from botocore import UNSIGNED from botocore.config import Config from packaging.version import Version from django.conf import settings +from django.core import signing from django.db import connection from zango.core.utils import get_current_request_url @@ -29,10 +31,10 @@ def get_installed_packages(tenant): return {package["name"]: package["version"] for package in packages} -def get_all_packages(tenant=None): +def get_all_packages(request, tenant=None): installed_packages = {} if tenant is not None: - installed_packages = get_installed_packages(tenant) + installed_packages = get_installed_packages(tenant.name) packages = {} s3 = boto3.client( "s3", @@ -66,6 +68,7 @@ def get_all_packages(tenant=None): packages[package]["versions"] = [ str(version) for version in packages[package]["versions"] ] + packages[package]["config_url"] = None for package, data in packages.items(): resp_data.append({"name": package, **data}) for local_package in installed_packages.keys(): @@ -77,6 +80,13 @@ def get_all_packages(tenant=None): "installed_version": installed_packages[local_package], } ) + for package in resp_data: + url = get_package_configuration_url(request, tenant, package["name"]) + resp = requests.get(url) + if resp.status_code == 200: + package["config_url"] = f"{url}?token={signing.dumps(request.user.id)}" + else: + package["config_url"] = None return resp_data diff --git a/backend/src/zango/templates/403.html b/backend/src/zango/templates/403.html index 83035edad..b3ae10ee0 100644 --- a/backend/src/zango/templates/403.html +++ b/backend/src/zango/templates/403.html @@ -31,4 +31,4 @@ -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/backend/src/zango/templates/404.html b/backend/src/zango/templates/404.html index 63758878d..cca684c64 100644 --- a/backend/src/zango/templates/404.html +++ b/backend/src/zango/templates/404.html @@ -32,4 +32,4 @@ -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/backend/src/zango/templates/500.html b/backend/src/zango/templates/500.html index e10eda77f..7ab75d7df 100644 --- a/backend/src/zango/templates/500.html +++ b/backend/src/zango/templates/500.html @@ -33,4 +33,4 @@ -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/frontend/src/mocks/appPackagesManagementHandlers.js b/frontend/src/mocks/appPackagesManagementHandlers.js index 473789cb5..0d8db56f3 100644 --- a/frontend/src/mocks/appPackagesManagementHandlers.js +++ b/frontend/src/mocks/appPackagesManagementHandlers.js @@ -9,12 +9,13 @@ const range = (len) => { return arr; }; -const newPackage = () => { +const newPackage = () => { return { - name: 'Package ' + faker.number.int({ min: 1, max: 10 }), + name: 'Package' + faker.number.int({ min: 1, max: 10 }), versions: ['0.1.0', '0.2.0'], status: faker.helpers.shuffle(['Installed', 'Not Installed'])[0], installed_version: faker.number.int({ min: 1, max: 10 }), + config_url: null }; }; @@ -46,7 +47,7 @@ export const appPackagesManagementHandlers = [ (pageIndex + 1) * pageSize ); - if (action === 'config_url') { + if (action === 'config_url' && !req.url.searchParams.get('package_name')) { return res( ctx.delay(500), ctx.status(200), @@ -57,33 +58,58 @@ export const appPackagesManagementHandlers = [ }, }) ); - } - - return res( - ctx.delay(500), - ctx.status(200), - ctx.json({ - success: true, - response: { - packages: { - total_records: totalData, - total_pages: Math.ceil(data.length / pageSize), - next: 'http://localhost:8000/api/v1/auth/platform-users/?page=2', - previous: null, - records: searchValue ? [] : slicedData, + }else if(action === 'config_url' && req.url.searchParams.get('package_name')){ + if (req.url.searchParams.get('package_name') === 'Package1') { + return res( + ctx.delay(500), + ctx.status(200), + ctx.json({ + success: true, + response: { + message: 'Package do have a configuration page', }, - dropdown_options: { - policies: [ - { id: 1, label: 'Policy 1' }, - { id: 2, label: 'Policy 2' }, - { id: 3, label: 'Policy 3' }, - { id: 4, label: 'Policy 4' }, - ], + }) + ); + }else{ + return res( + ctx.delay(500), + ctx.status(200), + ctx.json({ + success: false, + response: { + message: 'Package does not have configuration page', + }, + }) + ); + } + } + else{ + return res( + ctx.delay(500), + ctx.status(200), + ctx.json({ + success: true, + response: { + packages: { + total_records: totalData, + total_pages: Math.ceil(data.length / pageSize), + next: 'http://localhost:8000/api/v1/auth/platform-users/?page=2', + previous: null, + records: searchValue ? [] : slicedData, + }, + dropdown_options: { + policies: [ + { id: 1, label: 'Policy 1' }, + { id: 2, label: 'Policy 2' }, + { id: 3, label: 'Policy 3' }, + { id: 4, label: 'Policy 4' }, + ], + }, + message: 'Success', }, - message: 'Success', - }, - }) - ); + }) + ); + } }), rest.post('/api/v1/apps/:appId/packages/', (req, res, ctx) => { diff --git a/frontend/src/pages/appPackagesManagement/components/AppTable/RowMenu.jsx b/frontend/src/pages/appPackagesManagement/components/AppTable/RowMenu.jsx index f9253dbbd..292fc0489 100644 --- a/frontend/src/pages/appPackagesManagement/components/AppTable/RowMenu.jsx +++ b/frontend/src/pages/appPackagesManagement/components/AppTable/RowMenu.jsx @@ -33,6 +33,10 @@ export default function RowMenu({ rowData }) { dispatch(openIsInstallPackageModalOpen(rowData)); }; + if(rowData.config_url==null && rowData.status?.toLowerCase()=='installed'){ + return null; + } + return (