From 68219fd970b4a0723cf26650b6b7ab427d3875f6 Mon Sep 17 00:00:00 2001 From: bhaktinarvekar <56331957+bhaktinarvekar@users.noreply.github.com> Date: Sun, 6 Sep 2020 16:26:25 -0400 Subject: [PATCH 1/2] Update README.md --- README.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 122ab1a4..8c7f0d8b 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,20 @@ python -m venv venv ``` pip install -r requirements.txt ``` -3. Install custos client SDK in the virtual env (Follow instructions in "Install Custos Client SDK") -4. Run django server using manage.py file in custos_portal directory. +3. Install custos client SDK in the virtual env (Follow instructions in "Install Custos Client SDK") +4. Make migrations +``` +python manage.py migrate +``` +5. Run django server using manage.py file in custos_portal directory. ``` python manage.py runserver ``` -5. Run webpack development server from custos_portal/custos_portal/static/common using: +7. Install all the npm dependencies +``` +npm install +``` +6. Run webpack development server from custos_portal/custos_portal/static/common using: ``` npm run serve ``` @@ -39,4 +47,4 @@ This Django projects consists of 3 apps - Workspace: Handles all the requests for a regular users like 'create new tenant requests' We also use vuejs for the screens in Admin and Workspace folders. The components and other javascript files can be found -at ```custos_portal\static\common``` \ No newline at end of file +at ```custos_portal\static\common``` From 9d504f4a7d89db6c729e3108ee432f63e4279173 Mon Sep 17 00:00:00 2001 From: Bhakti Sunil Narvekar Date: Mon, 5 Oct 2020 00:05:10 -0400 Subject: [PATCH 2/2] airavata custos admin portal --- custos_portal/custos_portal/__init__.py | 19 +- .../custos_portal/apps/admin/apps.py | 10 +- .../custos_portal/apps/admin/urls.py | 5 +- .../custos_portal/apps/admin/views.py | 34 +- .../custos_portal/apps/auth/backends.py | 3 +- .../custos_portal/apps/auth/forms.py | 19 +- .../custos_portal/apps/auth/views.py | 67 +- .../custos_portal/apps/workspace/urls.py | 3 +- .../custos_portal/apps/workspace/views.py | 14 +- .../custos_portal/context_processors.py | 22 +- custos_portal/custos_portal/settings.ini | 5 +- custos_portal/custos_portal/settings.py | 5 +- custos_portal/custos_portal/settings_local.py | 8 - .../static/common/dist/webpack-stats.json | 2 +- .../static/common/js/apps/config/config.js | 2 + .../custos_portal_admin/EditTenantRequest.vue | 201 ++++- .../ListTenantRequestsContainer.vue | 483 +++++++++++- .../RequestNewTenantContainer.vue | 729 ++++++++++++++++++ .../ViewTenantRequestContainer.vue | 147 ++-- .../entry-admin-edit-tenant-request.js | 23 +- .../entry-admin-list-new-tenant-requests.js | 10 +- .../entry-admin-request-new-tenant.js | 33 + .../entry-admin-view-tenant-request.js | 31 +- .../js/apps/custos_portal_admin/utils/urls.js | 4 +- .../workspace/ListTenantRequestsContainer.vue | 377 ++++++++- .../workspace/RequestNewTenantContainer.vue | 397 ++++++++-- .../workspace/ViewTenantRequestContainer.vue | 103 ++- .../entry-list-new-tenant-requests.js | 12 +- .../workspace/entry-request-new-tenant.js | 14 +- .../workspace/entry-view-tenant-request.js | 33 +- .../common/js/apps/workspace/utils/urls.js | 2 +- .../static/common/js/store/index.js | 10 + .../static/common/js/store/modules/store.js | 32 + .../static/common/package-lock.json | 44 ++ .../custos_portal/static/common/package.json | 5 +- .../static/common/scss/main.scss | 10 +- .../custos_portal/static/common/vue.config.js | 3 +- .../custos_portal/static/images/auth.jpg | Bin 0 -> 25081 bytes .../custos_portal/static/images/auth.png | Bin 0 -> 46049 bytes .../custos-logo_custos-logo-color-v2.png | Bin 0 -> 2860 bytes .../custos-logo_custos-logomark-color.png | Bin 0 -> 738 bytes .../custos-logo_custos-logomark-dark.png | Bin 0 -> 742 bytes .../custos_portal/static/images/home.PNG | Bin 0 -> 65855 bytes .../custos_portal/templates/base.html | 2 +- .../templates/custos_portal/home.html | 66 +- .../custos_portal_auth/forgot_password.html | 4 +- .../form_create_account.html | 44 ++ .../templates/custos_portal_auth/login.html | 45 +- .../partials/externals_login_form.html | 77 +- .../custos_portal_auth/partials/form.html | 18 +- .../username_password_login_form.html | 96 ++- .../templates/workspace/list_requests.html | 2 +- .../workspace/request_new_tenant.html | 2 +- .../workspace/view_tenant_request.html | 2 +- 54 files changed, 2812 insertions(+), 467 deletions(-) create mode 100644 custos_portal/custos_portal/static/common/js/apps/config/config.js create mode 100644 custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/RequestNewTenantContainer.vue create mode 100644 custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-request-new-tenant.js create mode 100644 custos_portal/custos_portal/static/common/js/store/index.js create mode 100644 custos_portal/custos_portal/static/common/js/store/modules/store.js create mode 100644 custos_portal/custos_portal/static/images/auth.jpg create mode 100644 custos_portal/custos_portal/static/images/auth.png create mode 100644 custos_portal/custos_portal/static/images/custos-logo_custos-logo-color-v2.png create mode 100644 custos_portal/custos_portal/static/images/custos-logo_custos-logomark-color.png create mode 100644 custos_portal/custos_portal/static/images/custos-logo_custos-logomark-dark.png create mode 100644 custos_portal/custos_portal/static/images/home.PNG create mode 100644 custos_portal/custos_portal/templates/custos_portal_auth/form_create_account.html diff --git a/custos_portal/custos_portal/__init__.py b/custos_portal/custos_portal/__init__.py index 11a6430a..9d908c4a 100644 --- a/custos_portal/custos_portal/__init__.py +++ b/custos_portal/custos_portal/__init__.py @@ -1,5 +1,16 @@ -from clients.identity_management_client import IdentityManagementClient -from clients.user_management_client import UserManagementClient +from custos.clients.identity_management_client import IdentityManagementClient +from custos.clients.user_management_client import UserManagementClient +from custos.transport.settings import CustosServerClientSettings +import os -user_management_client = UserManagementClient() -identity_management_client = IdentityManagementClient() +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +settings = os.path.join(BASE_DIR, 'transport', 'settings.ini') + +custos_settings = CustosServerClientSettings(custos_host=custos_host, + custos_port=custos_port, + custos_client_id=custos_client_id, + custos_client_sec=custos_client_sec, + configuration_file_location=None) + +identity_management_client = IdentityManagementClient(custos_settings) +user_management_client = UserManagementClient(custos_settings) \ No newline at end of file diff --git a/custos_portal/custos_portal/apps/admin/apps.py b/custos_portal/custos_portal/apps/admin/apps.py index 7e638120..97b64030 100644 --- a/custos_portal/custos_portal/apps/admin/apps.py +++ b/custos_portal/custos_portal/apps/admin/apps.py @@ -13,7 +13,15 @@ class AdminConfig(CustosAppConfig): """ nav = [ { - 'label': 'Application Catalog', + 'label': 'Create new tenant request', + 'icon': 'fa fa-plus-square', + 'url': 'custos_portal_admin:request_new_tenant', + 'active_prefixes': ['applications', 'request-new-tenant'], + 'enabled': lambda req: (req.is_gateway_admin or + req.is_read_only_gateway_admin), + }, + { + 'label': 'List of all existing tenant requests', 'icon': 'fa fa-list', 'url': 'custos_portal_admin:list_requests', 'active_prefixes': ['applications', 'list-requests'], diff --git a/custos_portal/custos_portal/apps/admin/urls.py b/custos_portal/custos_portal/apps/admin/urls.py index 8c634327..f5258305 100644 --- a/custos_portal/custos_portal/apps/admin/urls.py +++ b/custos_portal/custos_portal/apps/admin/urls.py @@ -5,7 +5,8 @@ app_name = 'custos_portal_admin' urlpatterns = [ + url(r'^request-new-tenant', views.request_new_tenant, name='request_new_tenant'), url(r'^list-requests', views.list_new_tenant_requests, name='list_requests'), - url(r'^request/(?P[^/]+)/$', views.view_tenant_request, name="view_tenant_request"), - url(r'^edit-tenant-request/(?P[^/]+)/$', views.edit_tenant_request, name="edit_tenant_request") + url(r'^request/(?P[^/]+)/$', views.view_tenant_request, name="view_tenant_request"), + url(r'^edit-tenant-request/(?P[^/]+)/$', views.edit_tenant_request, name="edit_tenant_request") ] diff --git a/custos_portal/custos_portal/apps/admin/views.py b/custos_portal/custos_portal/apps/admin/views.py index 6be76036..ad8f6cdc 100644 --- a/custos_portal/custos_portal/apps/admin/views.py +++ b/custos_portal/custos_portal/apps/admin/views.py @@ -1,26 +1,44 @@ from django.shortcuts import render +from custos_portal import identity_management_client +from django.conf import settings +def request_new_tenant(request): + if request.method == 'POST': + logger.debug("Form is posted") + request.active_nav_item = 'admin-request-new-tenant' + token = request.COOKIES['token'] + + return render(request, 'workspace/request_new_tenant.html', { + 'bundle_name': 'admin-request-new-tenant', + 'data': token + }) def list_new_tenant_requests(request): request.active_nav_item = 'list-requests' - + # TODO fetch all the tenant requests from airavata here. + token = request.COOKIES['token'] return render(request, 'workspace/list_requests.html', { 'bundle_name': 'admin-list-requests', + 'data': token }) -def view_tenant_request(request, tenant_request_id): - print("Admin view Tenant request Id: {}".format(tenant_request_id)), +def view_tenant_request(request, client_id): + token = request.COOKIES['token'] + return render(request, 'workspace/view_tenant_request.html', { 'bundle_name': 'admin-view-request', - 'tenant_request_id': tenant_request_id + 'tenant_client_id': client_id, + 'data': token }) -def edit_tenant_request(request, tenant_request_id): - print("Edit Tenant request Id: {}".format(tenant_request_id)), +def edit_tenant_request(request, client_id): + token = request.COOKIES['token'] + return render(request, 'workspace/view_tenant_request.html', { 'bundle_name': 'admin-edit-request', - 'tenant_request_id': tenant_request_id - }) + 'tenant_client_id': client_id, + 'data': token + }) \ No newline at end of file diff --git a/custos_portal/custos_portal/apps/auth/backends.py b/custos_portal/custos_portal/apps/auth/backends.py index 33b4c4b4..0980a9f5 100644 --- a/custos_portal/custos_portal/apps/auth/backends.py +++ b/custos_portal/custos_portal/apps/auth/backends.py @@ -22,6 +22,7 @@ class CustosAuthBackend(ModelBackend): def authenticate(self, request=None, username=None, password=None, refresh_token=None): try: if username and password: + print("Entered username and password") token = self._get_token_and_userinfo_password_flow(username, password) request.session["ACCESS_TOKEN"] = token userinfo = self._get_userinfo_from_token(token) @@ -69,8 +70,6 @@ def _get_token_and_userinfo_redirect_flow(self, request): if state == saved_state: response = identity_management_client.token(settings.CUSTOS_TOKEN, redirect_uri, code) token = MessageToDict(response) - - logger.debug(token["access_token"]) return token return diff --git a/custos_portal/custos_portal/apps/auth/forms.py b/custos_portal/custos_portal/apps/auth/forms.py index d4970ff2..e5ab3fbf 100644 --- a/custos_portal/custos_portal/apps/auth/forms.py +++ b/custos_portal/custos_portal/apps/auth/forms.py @@ -1,13 +1,22 @@ import logging -from clients.user_management_client import UserManagementClient -from custos.core import IamAdminService_pb2 +from custos.clients.user_management_client import UserManagementClient +from custos.transport.settings import CustosServerClientSettings +from custos.server.core import IamAdminService_pb2 from django import forms from django.conf import settings from django.core import validators +import os logger = logging.getLogger(__name__) -user_management_client = UserManagementClient() +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +settings = os.path.join(BASE_DIR, 'transport', 'settings.ini') +custos_settings = CustosServerClientSettings(custos_host=custos_host, + custos_port=custos_port, + custos_client_id=custos_client_id, + custos_client_sec=custos_client_sec, + configuration_file_location=None) +user_management_client = UserManagementClient(custos_settings) USERNAME_VALIDATOR = validators.RegexValidator( regex=r"^[a-z0-9_-]+$", @@ -219,9 +228,9 @@ def clean(self): username = cleaned_data.get('username') check_username = user_management_client.is_username_available(settings.CUSTOS_TOKEN, username) - print(check_username.is_exist) + try: - if user_management_client.is_username_available(settings.CUSTOS_TOKEN, username).is_exist: + if user_management_client.is_username_available(settings.CUSTOS_TOKEN, username).status: logger.info("Username is available"); else: logger.info("Username is not available"); diff --git a/custos_portal/custos_portal/apps/auth/views.py b/custos_portal/custos_portal/apps/auth/views.py index ddf0f55c..f4898582 100644 --- a/custos_portal/custos_portal/apps/auth/views.py +++ b/custos_portal/custos_portal/apps/auth/views.py @@ -18,12 +18,14 @@ from django.views.decorators.debug import sensitive_variables from google.protobuf.json_format import MessageToDict from requests_oauthlib import OAuth2Session +from google.auth import jwt from . import utils from . import models from . import forms from ... import identity_management_client from ... import user_management_client +from . import backends logger = logging.getLogger(__name__) @@ -33,7 +35,15 @@ def callback(request): user = authenticate(request=request) logger.debug("Saving user to session: {}".format(user)) login(request, user) - return _handle_login_redirect(request) + sess = request.session + token = sess['ACCESS_TOKEN'] + code = request.GET.get('code').strip() + logger.info(code) + redirect_uri = request.build_absolute_uri(reverse('custos_portal_auth:callback')) + response = _handle_login_redirect(request) + response.set_cookie('token', value=token, secure=False, httponly=True) + return response + except Exception as err: logger.exception("An error occurred while processing OAuth2 " "callback: {}".format(request.build_absolute_uri())) @@ -59,43 +69,9 @@ def callback_error(request, idp_alias): def create_account(request): - if request.method == 'POST': - form = forms.CreateAccountForm(request.POST) - if form.is_valid(): - try: - username = form.cleaned_data['username'] - email = form.cleaned_data['email'] - first_name = form.cleaned_data['first_name'] - last_name = form.cleaned_data['last_name'] - password = form.cleaned_data['password'] - is_temp_password = False - result = user_management_client.register_user(settings.CUSTOS_TOKEN, username, first_name, last_name, - password, email, is_temp_password) - if result.is_registered: - logger.debug("User account successfully created for : {}".format(username)) - _create_and_send_email_verification_link(request, username, email, first_name, last_name, - settings.LOGIN_URL) - messages.success( - request, - "Account request processed successfully. Before you " - "can login you need to confirm your email address. " - "We've sent you an email with a link that you should " - "click on to complete the account creation process.") - else: - form.add_error(None, ValidationError("Failed to register the user with IAM service")) - except TypeError as e: - logger.exception( - "Failed to create account for user", exc_info=e) - form.add_error(None, ValidationError(e)) - return render(request, 'custos_portal_auth/create_account.html', { - 'options': settings.AUTHENTICATION_OPTIONS, - 'form': form - }) - else: - form = forms.CreateAccountForm() - return render(request, 'custos_portal_auth/create_account.html', { + return render(request, 'custos_portal_auth/form_create_account.html', { + 'next': request.GET.get('next', None), 'options': settings.AUTHENTICATION_OPTIONS, - 'form': form }) @@ -174,7 +150,11 @@ def handle_login(request): try: if user is not None: login(request, user) - return _handle_login_redirect(request) + response = identity_management_client.authenticate(settings.CUSTOS_TOKEN, username, password) + token = MessageToDict(response)["accessToken"] + response = _handle_login_redirect(request) + response.set_cookie('token', value=token, secure=False, httponly=True) + return response else: messages.error(request, "Login failed. Please try again.") except Exception as err: @@ -194,8 +174,7 @@ def redirect_login(request, idp_alias): client_id = settings.KEYCLOAK_CLIENT_ID auth_base_url = identity_management_client.get_oidc_configuration(settings.CUSTOS_TOKEN, client_id) - # auth_base_url = json.loads(auth_base_url.) - # print(auth_base_url) + base_authorize_url = settings.KEYCLOAK_AUTHORIZE_URL redirect_uri = request.build_absolute_uri( @@ -208,6 +187,7 @@ def redirect_login(request, idp_alias): authorization_url += '&kc_idp_hint=' + quote("oidc") # Store state in session for later validation (see backends.py) + request.session['OAUTH2_STATE'] = state request.session['OAUTH2_REDIRECT_URI'] = redirect_uri @@ -318,7 +298,9 @@ def start_login(request): def start_logout(request): logout(request) redirect_url = request.build_absolute_uri(resolve_url(settings.LOGOUT_REDIRECT_URL)) - return redirect(settings.KEYCLOAK_LOGOUT_URL + "?redirect_uri=" + quote(redirect_url)) + response = redirect(settings.KEYCLOAK_LOGOUT_URL + "?redirect_uri=" + quote(redirect_url)) + response.delete_cookie('token') + return response def start_username_password_login(request): @@ -346,8 +328,7 @@ def verify_email(request, code): if email_verification.next: login_url += "?" + urlencode({'next': email_verification.next}) - print(user_management_client.is_user_enabled(settings.CUSTOS_TOKEN, "shivam_testing_3")) - if user_management_client.is_user_enabled(settings.CUSTOS_TOKEN, username).is_exist: + if user_management_client.is_user_enabled(settings.CUSTOS_TOKEN, username).status: logger.debug("User {} is already enabled".format(username)) messages.success( request, diff --git a/custos_portal/custos_portal/apps/workspace/urls.py b/custos_portal/custos_portal/apps/workspace/urls.py index cd01d392..dab8968b 100644 --- a/custos_portal/custos_portal/apps/workspace/urls.py +++ b/custos_portal/custos_portal/apps/workspace/urls.py @@ -6,5 +6,6 @@ urlpatterns = [ url(r'^request-new-tenant', views.request_new_tenant, name='request_new_tenant'), url(r'^list-requests', views.list_new_tenant_requests, name='list_requests'), - url(r'request/(?P[^/]+)/$', views.view_tenant_request, name="view_tenant_request") + url(r'^request/(?P[^/]+)/$', views.view_tenant_request, name="view_tenant_request"), + # url(r'request/(?P[^/]+)/$', views.view_tenant_request, name="view_tenant_request") ] diff --git a/custos_portal/custos_portal/apps/workspace/views.py b/custos_portal/custos_portal/apps/workspace/views.py index a9d477ad..5a92af41 100644 --- a/custos_portal/custos_portal/apps/workspace/views.py +++ b/custos_portal/custos_portal/apps/workspace/views.py @@ -10,23 +10,31 @@ def request_new_tenant(request): if request.method == 'POST': logger.debug("Form is posted") request.active_nav_item = 'request-new-tenant' + token = request.COOKIES['token'] return render(request, 'workspace/request_new_tenant.html', { 'bundle_name': 'request-new-tenant', + 'data': token }) def list_new_tenant_requests(request): request.active_nav_item = 'list-requests' + if request.user: - print("hell") + token = request.COOKIES['token'] + return render(request, 'workspace/list_requests.html', { 'bundle_name': 'list-requests', + 'data': token }) -def view_tenant_request(request, tenant_request_id): +def view_tenant_request(request, client_id): + token = request.COOKIES['token'] + return render(request, 'workspace/view_tenant_request.html', { 'bundle_name': 'view-request', - 'tenant_request_id': tenant_request_id + 'tenant_client_id': client_id, + 'data': token }) diff --git a/custos_portal/custos_portal/context_processors.py b/custos_portal/custos_portal/context_processors.py index d1f4fd4b..90240ebe 100644 --- a/custos_portal/custos_portal/context_processors.py +++ b/custos_portal/custos_portal/context_processors.py @@ -2,27 +2,33 @@ import logging import re -from clients.identity_management_client import IdentityManagementClient -from clients.user_management_client import UserManagementClient +from custos.clients.identity_management_client import IdentityManagementClient +from custos.clients.user_management_client import UserManagementClient from django.apps import apps from django.conf import settings +from custos.transport.settings import CustosServerClientSettings +import os + from custos_portal.app_config import CustosAppConfig logger = logging.getLogger(__name__) # load APIServerClient with default configuration -client = UserManagementClient() -id_client = IdentityManagementClient() - -token = "Y3VzdG9zLTZud29xb2RzdHBlNW12Y3EwOWxoLTEwMDAwMTAxOkdpS3JHR1ZMVzd6RG9QWnd6Z0NpRk03V1V6M1BoSXVtVG1GeEFrcjc="; - +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +settings = os.path.join(BASE_DIR, 'transport', 'settings.ini') +custos_settings = CustosServerClientSettings(custos_host=custos_host, + custos_port=custos_port, + custos_client_id=custos_client_id, + custos_client_sec=custos_client_sec, + configuration_file_location=None) +client = UserManagementClient(custos_settings) +id_client = IdentityManagementClient(custos_settings) def register_user(): response = client.register_user(token, "TestingUser", "Jhon", "Smith", "12345", "jhon@iu.edu", True) - print(response) def airavata_app_registry(request): diff --git a/custos_portal/custos_portal/settings.ini b/custos_portal/custos_portal/settings.ini index ce676b80..39806e8d 100644 --- a/custos_portal/custos_portal/settings.ini +++ b/custos_portal/custos_portal/settings.ini @@ -1,4 +1,5 @@ [CustosServer] SERVER_HOST = custos.scigap.org -SERVER_SSL_PORT = 32036 -CERTIFICATE_FILE_PATH = ../cert.pem \ No newline at end of file +SERVER_SSL_PORT = 45996 +CLIENT_ID = custos Id +CLIENT_SEC = custos Sec \ No newline at end of file diff --git a/custos_portal/custos_portal/settings.py b/custos_portal/custos_portal/settings.py index 960825b6..8c400019 100644 --- a/custos_portal/custos_portal/settings.py +++ b/custos_portal/custos_portal/settings.py @@ -21,8 +21,6 @@ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = '3=(o1!l-)1p#evd@aviv56^piimx)!p=^t=#5))yn547yr9f2&' -# Custos server secret key -CUSTOS_TOKEN = 'Y3VzdG9zLTZud29xb2RzdHBlNW12Y3EwOWxoLTEwMDAwMTAxOkdpS3JHR1ZMVzd6RG9QWnd6Z0NpRk03V1V6M1BoSXVtVG1GeEFrcjc=' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -125,6 +123,7 @@ STATIC_URL = '/static/' STATICFILES_DIRS = [os.path.join(BASE_DIR, "custos_portal", "static")] + LOGIN_URL = 'custos_portal_auth:login' LOGIN_REDIRECT_URL = 'custos_portal_auth:dashboard' LOGOUT_REDIRECT_URL = '/' @@ -209,3 +208,5 @@ from custos_portal.settings_local import * # noqa except ImportError: pass + + diff --git a/custos_portal/custos_portal/settings_local.py b/custos_portal/custos_portal/settings_local.py index 81b94ae4..832a1dd9 100644 --- a/custos_portal/custos_portal/settings_local.py +++ b/custos_portal/custos_portal/settings_local.py @@ -11,14 +11,6 @@ # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -# Keycloak Configuration -KEYCLOAK_CLIENT_ID = 'custos-6nwoqodstpe5mvcq09lh-10000101' -KEYCLOAK_CLIENT_SECRET = 'GiKrGGVLW7zDoPZwzgCiFM7WUz3PhIumTmFxAkr7' -KEYCLOAK_AUTHORIZE_URL = 'https://keycloak.custos.scigap.org:31000/auth/realms/10000101/protocol/openid-connect/auth' -KEYCLOAK_TOKEN_URL = 'https://airavata.host:8443/auth/realms/default/protocol/openid-connect/token' -KEYCLOAK_LOGOUT_URL = 'https://keycloak.custos.scigap.org:31000/auth/realms/10000101/protocol/openid-connect/logout' -# Optional: specify if using self-signed certificate or certificate from unrecognized CA -# KEYCLOAK_CA_CERTFILE = os.path.join(BASE_DIR, "django_airavata", "resources", "incommon_rsa_server_ca.pem") KEYCLOAK_VERIFY_SSL = False SESSION_COOKIE_SECURE = False diff --git a/custos_portal/custos_portal/static/common/dist/webpack-stats.json b/custos_portal/custos_portal/static/common/dist/webpack-stats.json index dfe69515..fc4eb7c8 100644 --- a/custos_portal/custos_portal/static/common/dist/webpack-stats.json +++ b/custos_portal/custos_portal/static/common/dist/webpack-stats.json @@ -1 +1 @@ -{"status":"done","publicPath":"http://localhost:9000/static/common/dist/","chunks":{"admin-edit-request":[{"name":"admin-edit-request.js","publicPath":"http://localhost:9000/static/common/dist/admin-edit-request.js","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/admin-edit-request.js"},{"name":"admin-edit-request.js.map","publicPath":"http://localhost:9000/static/common/dist/admin-edit-request.js.map","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/admin-edit-request.js.map"}],"admin-list-requests":[{"name":"admin-list-requests.js","publicPath":"http://localhost:9000/static/common/dist/admin-list-requests.js","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/admin-list-requests.js"},{"name":"admin-list-requests.js.map","publicPath":"http://localhost:9000/static/common/dist/admin-list-requests.js.map","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/admin-list-requests.js.map"}],"admin-view-request":[{"name":"admin-view-request.js","publicPath":"http://localhost:9000/static/common/dist/admin-view-request.js","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/admin-view-request.js"},{"name":"admin-view-request.js.map","publicPath":"http://localhost:9000/static/common/dist/admin-view-request.js.map","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/admin-view-request.js.map"}],"app":[{"name":"app.js","publicPath":"http://localhost:9000/static/common/dist/app.js","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/app.js"},{"name":"app.js.map","publicPath":"http://localhost:9000/static/common/dist/app.js.map","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/app.js.map"}],"chunk-vendors":[{"name":"chunk-vendors.js","publicPath":"http://localhost:9000/static/common/dist/chunk-vendors.js","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/chunk-vendors.js"},{"name":"chunk-vendors.js.map","publicPath":"http://localhost:9000/static/common/dist/chunk-vendors.js.map","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/chunk-vendors.js.map"}],"cms":[{"name":"cms.js","publicPath":"http://localhost:9000/static/common/dist/cms.js","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/cms.js"},{"name":"cms.js.map","publicPath":"http://localhost:9000/static/common/dist/cms.js.map","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/cms.js.map"}],"list-requests":[{"name":"list-requests.js","publicPath":"http://localhost:9000/static/common/dist/list-requests.js","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/list-requests.js"},{"name":"list-requests.js.map","publicPath":"http://localhost:9000/static/common/dist/list-requests.js.map","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/list-requests.js.map"}],"request-new-tenant":[{"name":"request-new-tenant.js","publicPath":"http://localhost:9000/static/common/dist/request-new-tenant.js","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/request-new-tenant.js"},{"name":"request-new-tenant.js.map","publicPath":"http://localhost:9000/static/common/dist/request-new-tenant.js.map","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/request-new-tenant.js.map"}],"view-request":[{"name":"view-request.js","publicPath":"http://localhost:9000/static/common/dist/view-request.js","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/view-request.js"},{"name":"view-request.js.map","publicPath":"http://localhost:9000/static/common/dist/view-request.js.map","path":"/home/shivam/Programming/airavata-custos-portal/custos_portal/custos_portal/static/common/dist/view-request.js.map"}]}} \ No newline at end of file +{"status":"done","publicPath":"http://localhost:9000/static/common/dist/","chunks":{"admin-edit-request":[{"name":"admin-edit-request.js","publicPath":"http://localhost:9000/static/common/dist/admin-edit-request.js","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\admin-edit-request.js"},{"name":"admin-edit-request.js.map","publicPath":"http://localhost:9000/static/common/dist/admin-edit-request.js.map","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\admin-edit-request.js.map"}],"admin-list-requests":[{"name":"admin-list-requests.js","publicPath":"http://localhost:9000/static/common/dist/admin-list-requests.js","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\admin-list-requests.js"},{"name":"admin-list-requests.js.map","publicPath":"http://localhost:9000/static/common/dist/admin-list-requests.js.map","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\admin-list-requests.js.map"}],"admin-request-new-tenant":[{"name":"admin-request-new-tenant.js","publicPath":"http://localhost:9000/static/common/dist/admin-request-new-tenant.js","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\admin-request-new-tenant.js"},{"name":"admin-request-new-tenant.js.map","publicPath":"http://localhost:9000/static/common/dist/admin-request-new-tenant.js.map","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\admin-request-new-tenant.js.map"}],"admin-view-request":[{"name":"admin-view-request.js","publicPath":"http://localhost:9000/static/common/dist/admin-view-request.js","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\admin-view-request.js"},{"name":"admin-view-request.js.map","publicPath":"http://localhost:9000/static/common/dist/admin-view-request.js.map","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\admin-view-request.js.map"}],"app":[{"name":"app.js","publicPath":"http://localhost:9000/static/common/dist/app.js","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\app.js"},{"name":"app.js.map","publicPath":"http://localhost:9000/static/common/dist/app.js.map","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\app.js.map"}],"chunk-vendors":[{"name":"chunk-vendors.js","publicPath":"http://localhost:9000/static/common/dist/chunk-vendors.js","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\chunk-vendors.js"},{"name":"chunk-vendors.js.map","publicPath":"http://localhost:9000/static/common/dist/chunk-vendors.js.map","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\chunk-vendors.js.map"}],"cms":[{"name":"cms.js","publicPath":"http://localhost:9000/static/common/dist/cms.js","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\cms.js"},{"name":"cms.js.map","publicPath":"http://localhost:9000/static/common/dist/cms.js.map","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\cms.js.map"}],"list-requests":[{"name":"list-requests.js","publicPath":"http://localhost:9000/static/common/dist/list-requests.js","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\list-requests.js"},{"name":"list-requests.9a2297f2e96ba99a7f97.hot-update.js","publicPath":"http://localhost:9000/static/common/dist/list-requests.9a2297f2e96ba99a7f97.hot-update.js","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\list-requests.9a2297f2e96ba99a7f97.hot-update.js"},{"name":"list-requests.js.map","publicPath":"http://localhost:9000/static/common/dist/list-requests.js.map","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\list-requests.js.map"},{"name":"list-requests.9a2297f2e96ba99a7f97.hot-update.js.map","publicPath":"http://localhost:9000/static/common/dist/list-requests.9a2297f2e96ba99a7f97.hot-update.js.map","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\list-requests.9a2297f2e96ba99a7f97.hot-update.js.map"}],"request-new-tenant":[{"name":"request-new-tenant.js","publicPath":"http://localhost:9000/static/common/dist/request-new-tenant.js","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\request-new-tenant.js"},{"name":"request-new-tenant.js.map","publicPath":"http://localhost:9000/static/common/dist/request-new-tenant.js.map","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\request-new-tenant.js.map"}],"view-request":[{"name":"view-request.js","publicPath":"http://localhost:9000/static/common/dist/view-request.js","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\view-request.js"},{"name":"view-request.js.map","publicPath":"http://localhost:9000/static/common/dist/view-request.js.map","path":"D:\\airavata-final\\airavata-custos-portal-1\\custos_portal\\custos_portal\\static\\common\\dist\\view-request.js.map"}]}} \ No newline at end of file diff --git a/custos_portal/custos_portal/static/common/js/apps/config/config.js b/custos_portal/custos_portal/static/common/js/apps/config/config.js new file mode 100644 index 00000000..aa4fa350 --- /dev/null +++ b/custos_portal/custos_portal/static/common/js/apps/config/config.js @@ -0,0 +1,2 @@ +export const CLIENT_ID = CLIENT_ID; +export const CLIENT_SECRET = CLIENT_SECRET; \ No newline at end of file diff --git a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/EditTenantRequest.vue b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/EditTenantRequest.vue index 511b4b84..71752035 100755 --- a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/EditTenantRequest.vue +++ b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/EditTenantRequest.vue @@ -2,10 +2,10 @@
-

Update Tenant Request Form

+

Update Tenant Request Form

-
+
@@ -29,6 +29,7 @@ label-for="input-1" :invalid-feedback="invalidFeedback" :valid-feedback="validFeedback" + class="inputLabels" > - - -
+
- + - - + - - - Update - Discard - - - + +
+ +

Tenant is updated

+
+
+ Update +
@@ -285,6 +301,8 @@ \ No newline at end of file + + \ No newline at end of file diff --git a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/ListTenantRequestsContainer.vue b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/ListTenantRequestsContainer.vue index 8bd2add8..17cbf8a0 100644 --- a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/ListTenantRequestsContainer.vue +++ b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/ListTenantRequestsContainer.vue @@ -2,44 +2,123 @@
-

Existing Tenants Request

+

Existing Tenants Request

-
-
-
-
- - +
+
+ + + + + + Search + + +
+
+
+ + + + + + + + + + + + +
Client IDClient Name
+ {{tR.client_id}} + {{tR.client_name}}
+
+
+
+
Requested
+
Active
+
Deactivated
+
+
+ + - - - - + + + - - - + + + - + + + + +
Request IdClient NameCreation TimeStatusClient IDClient NameStatus
- {{tR.requestId}} + {{tR.client_id}} {{tR.clientName}}{{tR.client_name}}{{tR.tenant_status}}
+
+
+ + +
+
+
+ + + + + + + + + + + + + + +
Client IDClient NameStatus
- {{ tR.creationTime }} + {{tR.client_id}} {{tR.client_name}}{{tR.tenant_status}}
+
+
+ + +
+
+
+ + + + + + + + + + + + - -
Client IDClient NameStatus
- {{tR.status}} + {{tR.client_id}} + N/A {{tR.client_name}}{{tR.tenant_status}}
+ + +
+
+ +
+
@@ -48,36 +127,362 @@ import {now} from "moment"; import urls from "./utils/urls"; + import axios from 'axios'; + import {CLIENT_ID, CLIENT_SECRET} from '../config/config'; + import VueJwtDecode from 'vue-jwt-decode' export default { - + props: { + tokenData: { + type: String + } + }, data() { return { - tenantRequests: [] + requested: [], + active: [], + deactivated: [], + value: 1, + searchID: '', + searchList: [], + searchInd: false, + perPage: 10, + active_page: 1, + active_pages: [], + active_display: [], + requested_page: 1, + requested_pages: [], + requested_display: [], + deactivated_page: 1, + deactivated_pages: [], + deactivated_display: [], + req_offset: 0, + active_offset: 0, + deactivated_offset: 0, + req_limit: 0, + active_limit: 0, + deactive_limit: 0 + } + }, + computed: { + rows() { + return this.searchList.length; } }, beforeMount() { - this.tenantRequests.push({ - requestId: '234234324', - clientName: 'scigap', - creationTime: now(), - status: 'Active' - }); - this.tenantRequests.push({ - requestId: '54645645', - clientName: 'scigap', - creationTime: now(), - status: 'Active' + let token = this.tokenData; + + let encodedString = btoa(CLIENT_ID+":"+CLIENT_SECRET); + let decodedEmail = VueJwtDecode.decode(token).email; + + axios.get(`https://custos.scigap.org/apiserver/tenant-management/v1.0.0/tenants?limit=10&offset=${this.req_offset}`, { + headers: { + 'Authorization': `Bearer ${encodedString}` + } + }) + .then(response => { + const {tenant} = response.data; + this.requested_display = tenant; + }) + + axios.get(`https://custos.scigap.org/apiserver/tenant-management/v1.0.0/tenants?limit=10&offset=${this.offset}&status=ACTIVE`, { + headers: { + 'Authorization': `Bearer ${encodedString}` + } + }) + .then(response => { + const {tenant} = response.data; + this.active_display = tenant; + }) + + axios.get(`https://custos.scigap.org/apiserver/tenant-management/v1.0.0/tenants?limit=10&offset=${this.offset}&status=DEACTIVATED`, { + headers: { + 'Authorization': `Bearer ${encodedString}` + } + }) + .then(response => { + const {tenant} = response.data; + this.deactivated_display = tenant; }) }, methods: { viewLink(tenantRequest) { - console.log("Executed view link",tenantRequest) return urls.navigateToAdminViewRequest(tenantRequest) + }, + onClickHandler(step) + { + this.value = step; + }, + searchHandler() { + this.searchInd = true; + + let encodedString = btoa(CLIENT_ID+":"+CLIENT_SECRET); + + axios.get(`https://custos.scigap.org/apiserver/tenant-management/v1.0.0/oauth2/tenant?client_id=${this.searchID}`, { + headers: { + 'Authorization': `Bearer ${encodedString}` + } + }) + .then(res => { + this.searchList.push(res.data); + }) + }, + paginateActive(active_page) { + this.active_page = active_page; + let page = active_page; + let perPage = this.perPage; + let from = (page * perPage) - perPage; + let to = page * perPage; + this.active_display = this.active.slice(from, to); + }, + paginateRequested(active_page) { + this.requested_page = active_page; + let page = active_page; + let perPage = this.perPage; + let from = (page * perPage) - perPage; + let to = page * perPage; + this.requested_display = this.requested.slice(from, to); + }, + paginateDeactivated(active_page) { + this.deactivated_page = active_page; + let page = active_page; + let perPage = this.perPage; + let from = (page * perPage) - perPage; + let to = page * perPage; + this.deactivated_display = this.deactivated.slice(from, to); + }, + loadNextPageRequested(offset) { + let encodedString = btoa(CLIENT_ID+":"+CLIENT_SECRET); + axios.get(`https://custos.scigap.org/apiserver/tenant-management/v1.0.0/tenants?limit=10&offset=${offset}`, { + headers: { + 'Authorization': `Bearer ${encodedString}` + } + }) + .then(response => { + const {tenant} = response.data; + if(tenant.length > 0) + { + this.requested_page++; + this.requested_display = tenant; + this.req_offset = offset; + } + else + this.req_limit = 1; + }) + }, + loadPrevPageRequested(offset) + { + let encodedString = btoa(CLIENT_ID+":"+CLIENT_SECRET); + axios.get(`https://custos.scigap.org/apiserver/tenant-management/v1.0.0/tenants?limit=10&offset=${offset}`, { + headers: { + 'Authorization': `Bearer ${encodedString}` + } + }) + .then(response => { + this.req_limit = 0; + const {tenant} = response.data; + if(tenant.length > 0) + { + this.requested_page++; + this.requested_display = tenant; + this.req_offset = offset; + } + }) + }, + loadNextPageActive(offset) { + let encodedString = btoa(CLIENT_ID+":"+CLIENT_SECRET); + axios.get(`https://custos.scigap.org/apiserver/tenant-management/v1.0.0/tenants?limit=10&offset=${offset}&status=ACTIVE`, { + headers: { + 'Authorization': `Bearer ${encodedString}` + } + }) + .then(response => { + const {tenant} = response.data; + if(tenant.length > 0) + { + this.active_page++; + this.active_display = tenant; + this.active_offset = offset; + } + else + this.active_limit = 1; + }) + }, + loadPrevPageActive(offset) + { + let encodedString = btoa(CLIENT_ID+":"+CLIENT_SECRET); + axios.get(`https://custos.scigap.org/apiserver/tenant-management/v1.0.0/tenants?limit=10&offset=${offset}&status=ACTIVE`, { + headers: { + 'Authorization': `Bearer ${encodedString}` + } + }) + .then(response => { + this.active_limit = 0; + const {tenant} = response.data; + if(tenant.length > 0) + { + this.active_page++; + this.active_display = tenant; + this.active_offset = offset; + } + }) + }, + loadNextPageDeactive(offset) { + let encodedString = btoa(CLIENT_ID+":"+CLIENT_SECRET); + axios.get(`https://custos.scigap.org/apiserver/tenant-management/v1.0.0/tenants?limit=10&offset=${offset}&status=DEACTIVATED`, { + headers: { + 'Authorization': `Bearer ${encodedString}` + } + }) + .then(response => { + const {tenant} = response.data; + if(tenant.length > 0) + { + this.deactive_page++; + this.deactivated_display = tenant; + this.deactivated_offset = offset; + } + else + this.deactive_limit = 1; + }) + }, + loadPrevPageDeactive(offset) + { + let encodedString = btoa(CLIENT_ID+":"+CLIENT_SECRET); + axios.get(`https://custos.scigap.org/apiserver/tenant-management/v1.0.0/tenants?limit=10&offset=${offset}&status=DEACTIVATED`, { + headers: { + 'Authorization': `Bearer ${encodedString}` + } + }) + .then(response => { + this.deactive_limit = 0; + const {tenant} = response.data; + if(tenant.length > 0) + { + this.deactive_page++; + this.deactivated_display = tenant; + this.deactivated_offset = offset; + } + }) + }, + }, + watch: { + requested() { + let numberOfPages = Math.ceil(this.requested.length/this.perPage); + for(let i=1; i<=numberOfPages; i++) + this.requested_pages.push(i); + }, + active() { + let numberOfPages = Math.ceil(this.active.length/ this.perPage); + this.active_pages = []; + for(let i=1; i<=numberOfPages; i++) + this.active_pages.push(i); + }, + deactivated() { + let numberOfPages = Math.ceil(this.deactivated.length/this.perPage); + for(let i=1; i<=numberOfPages; i++) + this.deactivated_pages.push(i); } } }; - + \ No newline at end of file diff --git a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/RequestNewTenantContainer.vue b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/RequestNewTenantContainer.vue new file mode 100644 index 00000000..d466dd78 --- /dev/null +++ b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/RequestNewTenantContainer.vue @@ -0,0 +1,729 @@ + + + + + \ No newline at end of file diff --git a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/ViewTenantRequestContainer.vue b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/ViewTenantRequestContainer.vue index f414cd64..2467386f 100644 --- a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/ViewTenantRequestContainer.vue +++ b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/ViewTenantRequestContainer.vue @@ -2,7 +2,7 @@
-

Tenant Request Details

+

Tenant Request Details

@@ -12,57 +12,72 @@ - + + + + + - + - + - + - - + + - - + + - + - + - + - + + + + + - + +
@@ -82,12 +99,15 @@ Edit Reject
@@ -98,8 +118,6 @@
- -
Request IdClient ID -
{{tenantRequestId}}
+
{{tenantRequest.client_id}}
Client Name -
{{request.client_name}}
+
{{tenantRequest.client_name}}
Issued At{{tenantRequest.client_id_issued_at}}
Requester Email{{request.requester_email}}{{tenantRequest.requester_email}}
Admin Username{{request.admin_username}}{{tenantRequest.admin_username}}
Admin Name{{request.admin_first_name}} {{ " " }} {{request.admin_last_name}}{{tenantRequest.admin_first_name}} {{ " " }} {{tenantRequest.admin_last_name}}
Primary contact{{request.primary_contact}}Primary Contact{{tenantRequest.contacts[0]}}
Secondary contact{{request.secondary_contact}}Secondary Contact{{tenantRequest.contacts[1]}}
Redirect URI Name{{request.redirect_uris}} + + + {{uri}} + +
+
Scope{{request.scope}}{{tenantRequest.scope}}
Domain{{request.domain}}{{tenantRequest.domain}}
Client URI{{request.client_uri}}{{tenantRequest.client_uri}}
Logo URI{{tenantRequest.logo_uri}}
Comment{{request.comment}}{{tenantRequest.comment}}
@@ -111,40 +129,81 @@ \ No newline at end of file + + + \ No newline at end of file diff --git a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-edit-tenant-request.js b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-edit-tenant-request.js index 4d8f496b..ef88a050 100755 --- a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-edit-tenant-request.js +++ b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-edit-tenant-request.js @@ -1,6 +1,11 @@ import { entry } from "../../index"; import MainLayout from "../../components/MainLayout"; import EditTenantRequest from "./EditTenantRequest"; +import axios from 'axios'; +import VueJwtDecode from 'vue-jwt-decode' +import {CLIENT_ID, CLIENT_SECRET} from '../config/config'; + +// import store from '../../store'; // Expect a template with id "edit-experiment" and experiment-id data attribute // @@ -12,19 +17,29 @@ entry(Vue => { return h(MainLayout, [ h(EditTenantRequest, { props: { - tenantRequestId: this.tenantRequestId + tenantRequest: this.tenantRequest } }) ]); }, data() { return { - tenantRequestId: null + tenantRequest: null }; }, beforeMount() { - this.tenantRequestId = JSON.parse(this.$el.dataset.tenantRequestId); - console.log("Entry for admin edit tenant request is executed") + this.tenantRequestId = this.$el.dataset.tenantClientId; + + let encodedString = btoa(CLIENT_ID+":"+CLIENT_SECRET); + + axios.get(`https://custos.scigap.org/apiserver/tenant-management/v1.0.0/oauth2/tenant?client_id=${this.tenantRequestId}`, { + headers: { + 'Authorization': `Bearer ${encodedString}` + } + }) + .then(res => { + this.tenantRequest = res.data; + }) } }).$mount("#admin-edit-request"); }); diff --git a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-list-new-tenant-requests.js b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-list-new-tenant-requests.js index 3676b1ca..b3aafc3f 100644 --- a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-list-new-tenant-requests.js +++ b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-list-new-tenant-requests.js @@ -10,16 +10,22 @@ entry(Vue => { new Vue({ render(h) { return h(MainLayout, [ - h(ListTenantRequestsContainer) + h(ListTenantRequestsContainer, { + props: { + tokenData: this.tokenData + } + }) ]); }, data() { return { - experimentId: null + experimentId: null, + tokenData: null }; }, beforeMount() { console.log("Entry for list-admin-new-tenant-request is executed") + this.tokenData = this.$el.dataset.token; } }).$mount("#admin-list-requests"); }); diff --git a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-request-new-tenant.js b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-request-new-tenant.js new file mode 100644 index 00000000..40950fd1 --- /dev/null +++ b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-request-new-tenant.js @@ -0,0 +1,33 @@ +import { entry } from "../../index"; +import RequestNewTenantContainer from "./RequestNewTenantContainer"; +import MainLayout from "../../components/MainLayout"; +import VueJwtDecode from 'vue-jwt-decode' + +// Expect a template with id "edit-experiment" and experiment-id data attribute +// +//
+ +entry(Vue => { + new Vue({ + render(h) { + return h(MainLayout, [ + h(RequestNewTenantContainer, { + props : { + requesterEmail : this.decodedEmail + } + }) + ]); + }, + data() { + return { + experimentId: null, + decodedEmail: null + }; + }, + beforeMount() { + let token = this.$el.dataset.token; + + this.decodedEmail = VueJwtDecode.decode(token).email; + } + }).$mount("#admin-request-new-tenant"); +}); diff --git a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-view-tenant-request.js b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-view-tenant-request.js index aa242498..f85041db 100644 --- a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-view-tenant-request.js +++ b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/entry-admin-view-tenant-request.js @@ -1,6 +1,11 @@ import { entry } from "../../index"; import ViewTenantRequestContainer from "./ViewTenantRequestContainer"; import MainLayout from "../../components/MainLayout"; +import axios from 'axios'; +import VueJwtDecode from 'vue-jwt-decode' +import {CLIENT_ID, CLIENT_SECRET} from '../config/config'; + +// import store from '../../store'; // Expect a template with id "edit-experiment" and experiment-id data attribute // @@ -12,20 +17,36 @@ entry(Vue => { return h(MainLayout, [ h(ViewTenantRequestContainer, { props: { - tenantRequestId: this.tenantRequestId + tenantRequest: this.tenant, + tokenData: this.token } }) ]); }, data() { return { - tenantRequestId: null + tenant: null, + token : null }; }, beforeMount() { - this.tenantRequestId = JSON.parse(this.$el.dataset.tenantRequestId); - console.log("Entry adming view request is executed"); - console.log(this.$el.dataset) + this.tenantRequestId = this.$el.dataset.tenantClientId; + let token = this.$el.dataset.token; + this.token = token; + let encodedString = btoa(CLIENT_ID+":"+CLIENT_SECRET); + + axios.get(`https://custos.scigap.org/apiserver/tenant-management/v1.0.0/oauth2/tenant?client_id=${this.tenantRequestId}`, { + headers: { + 'Authorization': `Bearer ${encodedString}` + } + }) + .then(res => { + this.tenant = res.data; + var d = new Date(0); + d.setUTCSeconds(this.tenant.client_id_issued_at); + this.tenant.client_id_issued_at = d; + const tenantRequest = res.data; + }) } }).$mount("#admin-view-request"); }); diff --git a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/utils/urls.js b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/utils/urls.js index c096ad18..7c8a5f62 100644 --- a/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/utils/urls.js +++ b/custos_portal/custos_portal/static/common/js/apps/custos_portal_admin/utils/urls.js @@ -3,7 +3,7 @@ export default { viewAdminTenantRequest(tenantRequest) { return ( "/admin/request/" + - encodeURIComponent(tenantRequest.requestId) + + encodeURIComponent(tenantRequest.client_id) + "/" ); }, @@ -15,7 +15,7 @@ export default { adminEditTenantRequest(tenantRequest) { return ( "/admin/edit-tenant-request/" + - encodeURIComponent(tenantRequest.request_id) + + encodeURIComponent(tenantRequest.client_id) + "/" ); }, diff --git a/custos_portal/custos_portal/static/common/js/apps/workspace/ListTenantRequestsContainer.vue b/custos_portal/custos_portal/static/common/js/apps/workspace/ListTenantRequestsContainer.vue index 67a827ff..2d909063 100644 --- a/custos_portal/custos_portal/static/common/js/apps/workspace/ListTenantRequestsContainer.vue +++ b/custos_portal/custos_portal/static/common/js/apps/workspace/ListTenantRequestsContainer.vue @@ -2,44 +2,127 @@
-

Existing Tenants Request

+

Existing Tenants Request

-
-
-
-
- - +
+
+ + + + + + Search + + +
+
+
+ - - - - + + - - - + + + + + + + +
Request IdClient NameCreation TimeStatusClient IDClient Name
+ {{tR.client_id}} + {{tR.client_name}}
+
+
+
+
Requested
+
Active
+
Deactivated
+
+
+ + + + + + + + + + - + + + + +
Client IDClient NameStatus
- {{tR.requestId}} + {{tR.client_id}} {{tR.clientName}}{{tR.client_name}}{{tR.tenant_status}}
+
+
+ + {{requested_pageNumber}} + + +
+
+
+ + + + + + + + + + + + + + +
Client IDClient NameStatus
- {{ tR.creationTime }} + {{tR.client_id}} {{tR.client_name}}{{tR.tenant_status}}
+
+
+ + +
+
+
+ + + + + + + + + + + + - -
Client IDClient NameStatus
- {{tR.status}} + {{tR.client_id}} + N/A {{tR.client_name}}{{tR.tenant_status}}
+ + +
+
+ + {{deactivated_pageNumber}} + +
+
@@ -48,36 +131,252 @@ import {now} from "moment"; import urls from "./utils/urls"; + import axios from 'axios'; + import {CLIENT_ID, CLIENT_SECRET} from '../config/config'; + import VueJwtDecode from 'vue-jwt-decode' export default { - + props: { + tokenData: { + type: String + } + }, data() { return { - tenantRequests: [] + requested: [], + active: [], + deactivated: [], + value: 1, + searchID: '', + searchList: [], + searchInd: false, + perPage: 10, + active_page: 1, + active_pages: [], + active_display: [], + requested_page: 1, + requested_pages: [], + requested_display: [], + deactivated_page: 1, + deactivated_pages: [], + deactivated_display: [] + } + }, + computed: { + rows() { + return this.searchList.length; } }, beforeMount() { - this.tenantRequests.push({ - requestId: '234234324', - clientName: 'scigap', - creationTime: now(), - status: 'Active' - }); - this.tenantRequests.push({ - requestId: '54645645', - clientName: 'scigap', - creationTime: now(), - status: 'Active' + let token = this.tokenData; + + let encodedString = btoa(CLIENT_ID+":"+CLIENT_SECRET); + let decodedEmail = VueJwtDecode.decode(token).email; + + axios.get(`https://custos.scigap.org/apiserver/tenant-management/v1.0.0/tenants?offset=0&status=ACTIVE&requester_email=${decodedEmail}`, { + headers: { + 'Authorization': `Bearer ${encodedString}` + } }) + .then(response => { + const {tenant} = response.data; + + this.active = tenant.filter(t => { + if(t.tenant_status === 'ACTIVE') + return true; + }) + + this.requested = tenant.filter(t => { + if(t.tenant_status === 'REQUESTED') + return true; + }) + + this.deactivated = tenant.filter(t => { + if(t.tenant_status === 'DEACTIVATED') + return true; + }) + }) + .then(response1 => { + this.paginateRequested(1); + }) + .then(response2 => { + this.paginateActive(1); + }) + .then(response3 => { + this.paginateDeactivated(1); + }) + }, methods: { viewLink(tenantRequest) { - console.log("Executed view link",tenantRequest) return urls.navigateToViewRequest(tenantRequest) + }, + onClickHandler(step) + { + this.value = step; + }, + searchHandler() { + this.searchInd = true; + + let encodedString = btoa(CLIENT_ID+":"+CLIENT_SECRET); + let decodedEmail = VueJwtDecode.decode(this.tokenData).email; + + axios.get(`https://custos.scigap.org/apiserver/tenant-management/v1.0.0/tenants?offset=0&status=ACTIVE&requester_email=${decodedEmail}`, { + headers: { + 'Authorization': `Bearer ${encodedString}` + } + }) + .then(response => { + const {tenant} = response.data; + + this.searchList = tenant.filter(t => { + if(t.client_id === this.searchID) + return true; + }); + }) + }, + paginateActive(active_page) { + this.active_page = active_page; + let page = active_page; + let perPage = this.perPage; + let from = (page * perPage) - perPage; + let to = page * perPage; + this.active_display = this.active.slice(from, to); + }, + paginateRequested(active_page) { + this.requested_page = active_page; + let page = active_page; + let perPage = this.perPage; + let from = (page * perPage) - perPage; + let to = page * perPage; + this.requested_display = this.requested.slice(from, to); + }, + paginateDeactivated(active_page) { + this.deactivated_page = active_page; + let page = active_page; + let perPage = this.perPage; + let from = (page * perPage) - perPage; + let to = page * perPage; + this.deactivated_display = this.deactivated.slice(from, to); + } + }, + watch: { + requested() { + let numberOfPages = Math.ceil(this.requested.length/this.perPage); + for(let i=1; i<=numberOfPages; i++) + this.requested_pages.push(i); + }, + active() { + let numberOfPages = Math.ceil(this.active.length/ this.perPage); + this.active_pages = []; + for(let i=1; i<=numberOfPages; i++) + this.active_pages.push(i); + }, + deactivated() { + let numberOfPages = Math.ceil(this.deactivated.length/this.perPage); + for(let i=1; i<=numberOfPages; i++) + this.deactivated_pages.push(i); } } }; - + \ No newline at end of file diff --git a/custos_portal/custos_portal/static/common/js/apps/workspace/RequestNewTenantContainer.vue b/custos_portal/custos_portal/static/common/js/apps/workspace/RequestNewTenantContainer.vue index 795ca4a0..66d3d948 100755 --- a/custos_portal/custos_portal/static/common/js/apps/workspace/RequestNewTenantContainer.vue +++ b/custos_portal/custos_portal/static/common/js/apps/workspace/RequestNewTenantContainer.vue @@ -2,21 +2,26 @@
-

New Tenant Request Form

+

New Tenant Request Form

-
- - - - - +
+
+
User Info
+
Gateway Admin details
+
Gateway details
+
Client details
+
+
+ + v-model="requesterEmail" + readonly> - + - - - - - +
+
+ - - - + + + + + + + +
+
+ - - -
+
- + - - Submit + +
+ +

New Tenant is created

+
+
+ Request Tenant
- - - - -
- - Previous - - Next - -
Current Tab: {{ tabIndex+1 }} of 3
+
+
+
+
+
+

Please create a new tenant to view ClientID and Client Secret

+
+
+
+
+
+
+

Tenant Request Details

+
+
+
+
+
+
+ + + + + + + + + + + +
Client ID +
{{this.clientID}}
+
Client Secret +
{{this.clientSecret}}
+
+
+
+
+
+
+
+
+ + Previous + Next + +
-
+
\ No newline at end of file + + + \ No newline at end of file diff --git a/custos_portal/custos_portal/static/common/js/apps/workspace/ViewTenantRequestContainer.vue b/custos_portal/custos_portal/static/common/js/apps/workspace/ViewTenantRequestContainer.vue index 68f30d5b..072ef833 100644 --- a/custos_portal/custos_portal/static/common/js/apps/workspace/ViewTenantRequestContainer.vue +++ b/custos_portal/custos_portal/static/common/js/apps/workspace/ViewTenantRequestContainer.vue @@ -2,7 +2,7 @@
-

Tenant Request Details

+

Tenant Request Details

@@ -11,74 +11,67 @@
- - + + + + + - + - + - + - - + + - - + + - + - + - + - + - - - - - - - - - - - +
Request IdClient ID -
{{tenantRequestId}}
+
{{tenantRequest.client_id}}
Client Name -
{{request.client_name}}
+
{{tenantRequest.client_name}}
Issued At{{tenantRequest.client_id_issued_at}}
Requester Email{{request.requester_email}}{{tenantRequest.requester_email}}
Admin Username{{request.admin_username}}{{tenantRequest.admin_username}}
Admin Name{{request.admin_first_name}} {{ " " }} {{request.admin_last_name}}{{tenantRequest.admin_first_name}} {{ " " }} {{tenantRequest.admin_last_name}}
Primary contact{{request.primary_contact}}Primary Contact{{tenantRequest.contacts[0]}}
Secondary contact{{request.secondary_contact}}Secondary Contact{{tenantRequest.contacts[1]}}
Redirect URI Name{{request.redirect_uris}} + + + {{uri}} + +
+
Scope{{request.scope}}{{tenantRequest.scope}}
Domain{{request.domain}}{{tenantRequest.domain}}
Client URI{{request.client_uri}}{{tenantRequest.client_uri}}
Comment{{request.comment}}
Custos Key{{custosKey}} - - -
Custos Secret{{custosSecret}} - - - {{tenantRequest.comment}}
@@ -90,39 +83,29 @@ \ No newline at end of file + + + \ No newline at end of file diff --git a/custos_portal/custos_portal/static/common/js/apps/workspace/entry-list-new-tenant-requests.js b/custos_portal/custos_portal/static/common/js/apps/workspace/entry-list-new-tenant-requests.js index eaa85c40..1d91171a 100644 --- a/custos_portal/custos_portal/static/common/js/apps/workspace/entry-list-new-tenant-requests.js +++ b/custos_portal/custos_portal/static/common/js/apps/workspace/entry-list-new-tenant-requests.js @@ -10,16 +10,22 @@ entry(Vue => { new Vue({ render(h) { return h(MainLayout, [ - h(ListTenantRequestsContainer) + h(ListTenantRequestsContainer, { + props: { + tokenData: this.token + } + }) ]); }, data() { return { - experimentId: null + experimentId: null, + token: null }; }, beforeMount() { - console.log("Entry for list-new-tenant-request is executed") + console.log("Entry for list-new-tenant-request is executed"); + this.token = this.$el.dataset.token; } }).$mount("#list-requests"); }); diff --git a/custos_portal/custos_portal/static/common/js/apps/workspace/entry-request-new-tenant.js b/custos_portal/custos_portal/static/common/js/apps/workspace/entry-request-new-tenant.js index 9d369c21..5ae9eb7e 100755 --- a/custos_portal/custos_portal/static/common/js/apps/workspace/entry-request-new-tenant.js +++ b/custos_portal/custos_portal/static/common/js/apps/workspace/entry-request-new-tenant.js @@ -1,6 +1,7 @@ import { entry } from "../../index"; import RequestNewTenantContainer from "./RequestNewTenantContainer"; import MainLayout from "../../components/MainLayout"; +import VueJwtDecode from 'vue-jwt-decode' // Expect a template with id "edit-experiment" and experiment-id data attribute // @@ -10,16 +11,23 @@ entry(Vue => { new Vue({ render(h) { return h(MainLayout, [ - h(RequestNewTenantContainer) + h(RequestNewTenantContainer, { + props : { + requesterEmail : this.decodedEmail + } + }) ]); }, data() { return { - experimentId: null + experimentId: null, + decodedEmail: null }; }, beforeMount() { - console.log("Entry is executed") + let token = this.$el.dataset.token; + + this.decodedEmail = VueJwtDecode.decode(token).email; } }).$mount("#request-new-tenant"); }); diff --git a/custos_portal/custos_portal/static/common/js/apps/workspace/entry-view-tenant-request.js b/custos_portal/custos_portal/static/common/js/apps/workspace/entry-view-tenant-request.js index 11ae71d7..db8b36cc 100644 --- a/custos_portal/custos_portal/static/common/js/apps/workspace/entry-view-tenant-request.js +++ b/custos_portal/custos_portal/static/common/js/apps/workspace/entry-view-tenant-request.js @@ -1,6 +1,9 @@ import { entry } from "../../index"; import ViewTenantRequestContainer from "./ViewTenantRequestContainer"; import MainLayout from "../../components/MainLayout"; +import axios from 'axios'; +import VueJwtDecode from 'vue-jwt-decode' +import {CLIENT_ID, CLIENT_SECRET} from '../config/config'; // Expect a template with id "edit-experiment" and experiment-id data attribute // @@ -12,20 +15,40 @@ entry(Vue => { return h(MainLayout, [ h(ViewTenantRequestContainer, { props: { - tenantRequestId: this.tenantRequestId + tenantRequest: this.tenant, + tokenData: this.token } }) ]); }, data() { return { - tenantRequestId: null + tenant: null, + token: null }; }, beforeMount() { - this.tenantRequestId = JSON.parse(this.$el.dataset.tenantRequestId); - console.log("Entry is executed"); - console.log(this.$el.dataset) + this.tenantRequestId = this.$el.dataset.tenantRequestId; + this.tenantClientId = this.$el.dataset.tenantClientId; + let token = this.$el.dataset.token; + + let decodedEmail = VueJwtDecode.decode(token).email; + let encodedString = btoa(CLIENT_ID+":"+CLIENT_SECRET); + + axios.get(`https://custos.scigap.org/apiserver/tenant-management/v1.0.0/oauth2/tenant?client_id=${this.tenantClientId}`, { + headers: { + 'Authorization': `Bearer ${encodedString}` + } + }) + .then(res => { + this.tenant = res.data; + + var d = new Date(0); + d.setUTCSeconds(this.tenant.client_id_issued_at); + this.tenant.client_id_issued_at = d; + const tenantRequest = res.data; + }) + } }).$mount("#view-request"); }); diff --git a/custos_portal/custos_portal/static/common/js/apps/workspace/utils/urls.js b/custos_portal/custos_portal/static/common/js/apps/workspace/utils/urls.js index ef4061e2..8e76d660 100644 --- a/custos_portal/custos_portal/static/common/js/apps/workspace/utils/urls.js +++ b/custos_portal/custos_portal/static/common/js/apps/workspace/utils/urls.js @@ -3,7 +3,7 @@ export default { viewTenantRequest(tenantRequest) { return ( "/workspace/request/" + - encodeURIComponent(tenantRequest.requestId) + + encodeURIComponent(tenantRequest.client_id) + "/" ); }, diff --git a/custos_portal/custos_portal/static/common/js/store/index.js b/custos_portal/custos_portal/static/common/js/store/index.js new file mode 100644 index 00000000..80cbead7 --- /dev/null +++ b/custos_portal/custos_portal/static/common/js/store/index.js @@ -0,0 +1,10 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; + +Vue.use(Vuex); + +export default new Vuex.Store({ + modules: { + tenant + } +}) \ No newline at end of file diff --git a/custos_portal/custos_portal/static/common/js/store/modules/store.js b/custos_portal/custos_portal/static/common/js/store/modules/store.js new file mode 100644 index 00000000..a6e4db78 --- /dev/null +++ b/custos_portal/custos_portal/static/common/js/store/modules/store.js @@ -0,0 +1,32 @@ +import axios from 'axios'; + +export const state = { + tenant: { + tenant_id: '', + tenant_status: '', + admin_email: '', + admin_first_name: '', + admin_last_name: '', + admin_password: '', + admin_username: '', + application_type: '', + client_id: '', + client_name: '', + client_uri: '', + comment: '', + contacts: '', + domain: '', + logo_url: '', + parent_tenant_id: '', + redirect_uris: '', + scope: '' + } +}; + +export const getters = { + getTenant = (state) => state.tenant +}; + +export const actions = {}; + +export const mutations = {}; \ No newline at end of file diff --git a/custos_portal/custos_portal/static/common/package-lock.json b/custos_portal/custos_portal/static/common/package-lock.json index fc49d8d8..251e3291 100755 --- a/custos_portal/custos_portal/static/common/package-lock.json +++ b/custos_portal/custos_portal/static/common/package-lock.json @@ -2033,6 +2033,37 @@ "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", "dev": true }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -11929,6 +11960,14 @@ "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", "dev": true }, + "vue-jwt-decode": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/vue-jwt-decode/-/vue-jwt-decode-0.1.0.tgz", + "integrity": "sha512-4iP0NzYHkAF7G13tYPc/nudk4oNpB8GCVZupc7lekxXok1XKEgefNaGTpDT14g7RKe5H9GaMphPduDj4UVfZwQ==", + "requires": { + "vue": "^2.3.3" + } + }, "vue-loader": { "version": "15.9.0", "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.0.tgz", @@ -11973,6 +12012,11 @@ "resolved": "https://registry.npmjs.org/vuelidate/-/vuelidate-0.7.5.tgz", "integrity": "sha512-GAAG8QAFVp7BFeQlNaThpTbimq3+HypBPNwdkCkHZZeVaD5zmXXfhp357dcUJXHXTZjSln0PvP6wiwLZXkFTwg==" }, + "vuex": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.5.1.tgz", + "integrity": "sha512-w7oJzmHQs0FM9LXodfskhw9wgKBiaB+totOdb8sNzbTB2KDCEEwEs29NzBZFh/lmEK1t5tDmM1vtsO7ubG1DFw==" + }, "watchpack": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", diff --git a/custos_portal/custos_portal/static/common/package.json b/custos_portal/custos_portal/static/common/package.json index b16b8fba..f85b6eac 100755 --- a/custos_portal/custos_portal/static/common/package.json +++ b/custos_portal/custos_portal/static/common/package.json @@ -15,6 +15,7 @@ }, "dependencies": { "@fortawesome/fontawesome-free": "^5.6.3", + "axios": "^0.19.2", "bootstrap": "^4.3.1", "bootstrap-vue": "2.0.0-rc.26", "clipboard": "^2.0.4", @@ -23,7 +24,9 @@ "popper.js": "^1.14.6", "terser": "^4.1.2", "vue": "^2.5.22", - "vuelidate": "0.7.5" + "vue-jwt-decode": "^0.1.0", + "vuelidate": "0.7.5", + "vuex": "^3.5.1" }, "devDependencies": { "@vue/cli-plugin-babel": "^3.1.1", diff --git a/custos_portal/custos_portal/static/common/scss/main.scss b/custos_portal/custos_portal/static/common/scss/main.scss index 008a79a8..b6f685a1 100755 --- a/custos_portal/custos_portal/static/common/scss/main.scss +++ b/custos_portal/custos_portal/static/common/scss/main.scss @@ -48,7 +48,7 @@ body { } .c-nav { - background-color: #444; + background-color: #b4b3b3; min-width: 70px; min-height: 60px; padding: 1rem 0; @@ -56,7 +56,7 @@ body { display: flex; &__item { - color: #ccc; + color: #eeeeee; font-size: 1.5rem; display: block; text-align: center; @@ -65,15 +65,15 @@ body { &:hover, &:focus { - color: #ffffff; + color: #444444; } &:active { - color: #bbb; + color: #444444; } &.is-active { - color: #ffffff; + color: #444444; } } } diff --git a/custos_portal/custos_portal/static/common/vue.config.js b/custos_portal/custos_portal/static/common/vue.config.js index 21a668de..94486720 100755 --- a/custos_portal/custos_portal/static/common/vue.config.js +++ b/custos_portal/custos_portal/static/common/vue.config.js @@ -11,7 +11,8 @@ module.exports = { 'view-request': "./js/apps/workspace/entry-view-tenant-request", 'admin-view-request': "./js/apps/custos_portal_admin/entry-admin-view-tenant-request", 'admin-edit-request': "./js/apps/custos_portal_admin/entry-admin-edit-tenant-request", - 'admin-list-requests': "./js/apps/custos_portal_admin/entry-admin-list-new-tenant-requests" + 'admin-list-requests': "./js/apps/custos_portal_admin/entry-admin-list-new-tenant-requests", + 'admin-request-new-tenant': "./js/apps/custos_portal_admin/entry-admin-request-new-tenant" }, css: { loaderOptions: { diff --git a/custos_portal/custos_portal/static/images/auth.jpg b/custos_portal/custos_portal/static/images/auth.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dd2206e324d117723623c1c97297ad153e116347 GIT binary patch literal 25081 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 literal 0 HcmV?d00001 diff --git a/custos_portal/custos_portal/static/images/custos-logo_custos-logo-color-v2.png b/custos_portal/custos_portal/static/images/custos-logo_custos-logo-color-v2.png new file mode 100644 index 0000000000000000000000000000000000000000..644886de9db254208df2958de1ad4a577717087c GIT binary patch literal 2860 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 KMNUMnLSTY-bxIll literal 0 HcmV?d00001 diff --git a/custos_portal/custos_portal/static/images/custos-logo_custos-logomark-color.png b/custos_portal/custos_portal/static/images/custos-logo_custos-logomark-color.png new file mode 100644 index 0000000000000000000000000000000000000000..c1f1d8f79c311853bf6c500ab0d63abef5bb2c5a GIT binary patch literal 738 zcmV<80v-K{P)%xKL7v%lu1NERCt{2+|5;kKoo}I4~_-cfp%a@h#lC0x=R_B;7)d0f*lw; z&Fo-i*S(Zq$B0B|e1K<>kaxQ%cN6DG|f?T$* zJZtPG9hglJ)%?R4gD}4^kwBO~n8+Z^4~!EK79YkL2#W{f6olEsI0s>NFo}RLeVD{R zm>x``AS|yBpvaCzw_0Qs$Xlu?s9~zRQ(!5K^9bNeaC_$E?GDdGaTetZfO*O|dFST| zr>6`-IcB4uc7&X&X${zsK1HgM@HCMYmRDS17XCUodcv^8w%*i}FHXTLgIra1Y>k z9}FDg5TtrK@DTidRzXhqavvBt!7%}0ePIw0#}tGOfq^kj6c9EP1_n4$L0DGa)oSHCI`jGoSubzzjOT_pNz{DDOgJ0; ze)&!~E3ICYCY+x(FV_=J-S%rz UxNZEQUjP6A07*qoM6N<$f*WoxrvLx| literal 0 HcmV?d00001 diff --git a/custos_portal/custos_portal/static/images/custos-logo_custos-logomark-dark.png b/custos_portal/custos_portal/static/images/custos-logo_custos-logomark-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..057b9712543ef253483e313d1e44b920a894f349 GIT binary patch literal 742 zcmV%xKL7v%m`OxIRCt{2+}lxGF%Smee;MAPgQNrK0H=eL;1VbyC8Pt=2`+&W zD8W>)85yl(E;$@ady{?s89n-3zF}-hyNH+>qlSpq09MSr)_#SH5lspR5j_KV0Px-7 z9+wsuwMzX9`32yc^}U9G@dS~ihKT@?q=bnCk)(kkqH6&60M?Npl5m&K7o*3nYuFIym#;DVS?HBi)Gq!cEr1EUlVN>tBngf#!#}b5(g~@>90n!8$h2sg* z4C9Ft0n!CyjS~sd4P%894Wa_0j*|dn57S$_R-FX)q)yBV$RmKe-s@=;^+R#AK_pt; z4(>QsAQH_s5EmS45Q%nwj2Vs>h{U3CNEOE$L}JxZ)r}JcBC%{WYr=^Jky!WO&Bnc!xlx$k+KBqMP zTf=HCij6+LEb6rs#YV=NUFB>kXpM+-blJDH+BXVLa~-^=6q*^QyD^{{CMk|ur$pC> z6XB?~j;O!{7VftbN4CrS`dlr8C4ahY_k8!3bG4; Yzjkb%O1& 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 literal 0 HcmV?d00001 diff --git a/custos_portal/custos_portal/templates/base.html b/custos_portal/custos_portal/templates/base.html index d07d9852..30911cb6 100644 --- a/custos_portal/custos_portal/templates/base.html +++ b/custos_portal/custos_portal/templates/base.html @@ -145,7 +145,7 @@

{% block header %} - + {% endblock %} diff --git a/custos_portal/custos_portal/templates/custos_portal/home.html b/custos_portal/custos_portal/templates/custos_portal/home.html index a22b3d87..75fc1aff 100644 --- a/custos_portal/custos_portal/templates/custos_portal/home.html +++ b/custos_portal/custos_portal/templates/custos_portal/home.html @@ -1,16 +1,66 @@ {% extends 'base.html' %} - +{% load static %} {% block content %} + +
-
-

Welcome!

-

This is the Django based web portal for Custos.

- {% if not user.is_authenticated %} -

Login »

-

Register

- {% endif %} +
+
+
+

Welcome!

+

This is the Django based web portal for Custos.

+ {% if not user.is_authenticated %} +

Login »

+

Register

+ {% endif %} +
+
+ {% if not user.is_authenticated %} + + {% endif %} +
+
{% if user.is_authenticated %}
diff --git a/custos_portal/custos_portal/templates/custos_portal_auth/forgot_password.html b/custos_portal/custos_portal/templates/custos_portal_auth/forgot_password.html index d40d14ff..b0656f17 100644 --- a/custos_portal/custos_portal/templates/custos_portal_auth/forgot_password.html +++ b/custos_portal/custos_portal/templates/custos_portal_auth/forgot_password.html @@ -5,7 +5,7 @@
-
+
diff --git a/custos_portal/custos_portal/templates/custos_portal_auth/form_create_account.html b/custos_portal/custos_portal/templates/custos_portal_auth/form_create_account.html new file mode 100644 index 00000000..2e85d10d --- /dev/null +++ b/custos_portal/custos_portal/templates/custos_portal_auth/form_create_account.html @@ -0,0 +1,44 @@ +{% extends 'base.html' %} +{% load static %} +{% block content %} + + + +
+
+

Sign Up

+
+
+ {% if options.external %} + {% include "./partials/externals_login_form.html" %} + {% endif %} +
+
+ +
+
+
+
+{% endblock content %} diff --git a/custos_portal/custos_portal/templates/custos_portal_auth/login.html b/custos_portal/custos_portal/templates/custos_portal_auth/login.html index 9c4d9782..f6b0b757 100644 --- a/custos_portal/custos_portal/templates/custos_portal_auth/login.html +++ b/custos_portal/custos_portal/templates/custos_portal_auth/login.html @@ -1,16 +1,43 @@ {% extends 'base.html' %} - +{% load static %} {% block content %} -
-
- {% if options.external %} - {% include "./partials/externals_login_form.html" %} - {% endif %} + - {% if options.password %} - {% include "./partials/username_password_login_form.html" %} - {% endif %} +
+
+

Sign In

+
+
+ +
+
+ {% if options.external %} + {% include "./partials/externals_login_form.html" %} + {% endif %} + + {% if options.password %} + {% include "./partials/username_password_login_form.html" %} + {% endif %} +
+
{% endblock content %} diff --git a/custos_portal/custos_portal/templates/custos_portal_auth/partials/externals_login_form.html b/custos_portal/custos_portal/templates/custos_portal_auth/partials/externals_login_form.html index 7ea8ceb3..82eaadd6 100644 --- a/custos_portal/custos_portal/templates/custos_portal_auth/partials/externals_login_form.html +++ b/custos_portal/custos_portal/templates/custos_portal_auth/partials/externals_login_form.html @@ -1,20 +1,59 @@ -
-
-
-
-
{{ title|default:"Log in with your existing organizational login" }}
- {% for external in options.external %} - - Sign in with {{ external.name }} - - {% endfor %} -
-
-
+{% load static %} + + + +
+
{{ title|default:"Log in with your existing organizational login" }}
+ {% for external in options.external %} + + Sign in with {{ external.name }} + + {% endfor %}
diff --git a/custos_portal/custos_portal/templates/custos_portal_auth/partials/form.html b/custos_portal/custos_portal/templates/custos_portal_auth/partials/form.html index ce558f75..03a05c8b 100644 --- a/custos_portal/custos_portal/templates/custos_portal_auth/partials/form.html +++ b/custos_portal/custos_portal/templates/custos_portal_auth/partials/form.html @@ -1,3 +1,19 @@ +
{% include "./non_field_errors.html" %} @@ -7,7 +23,7 @@ {% include './form_field.html' %} {% endfor %} -
diff --git a/custos_portal/custos_portal/templates/custos_portal_auth/partials/username_password_login_form.html b/custos_portal/custos_portal/templates/custos_portal_auth/partials/username_password_login_form.html index 9b4ceef7..d0d88f21 100644 --- a/custos_portal/custos_portal/templates/custos_portal_auth/partials/username_password_login_form.html +++ b/custos_portal/custos_portal/templates/custos_portal_auth/partials/username_password_login_form.html @@ -1,31 +1,69 @@ -
-
-
-
-
Log in with {{ options.password.name|default:"a username and password" }}
- {% include "./messages.html" %} -
- {% csrf_token %} -
- - -
-
- - - Forgot your password? -
- {% if next %} - - {% endif %} - {% if login_type and login_type == 'password' %} - - {% endif %} - -
-
+ + + +
+
Log in with {{ options.password.name|default:"a username and password" }}
+ {% include "./messages.html" %} +
+
+ {% csrf_token %} +
+ +
-
+
+ + + Forgot your password? +
+ {% if next %} + + {% endif %} + {% if login_type and login_type == 'password' %} + + {% endif %} + +
+ diff --git a/custos_portal/custos_portal/templates/workspace/list_requests.html b/custos_portal/custos_portal/templates/workspace/list_requests.html index 3019d78f..cf9a31bb 100644 --- a/custos_portal/custos_portal/templates/workspace/list_requests.html +++ b/custos_portal/custos_portal/templates/workspace/list_requests.html @@ -3,6 +3,6 @@ {% block content %} -
+
{% endblock content %} \ No newline at end of file diff --git a/custos_portal/custos_portal/templates/workspace/request_new_tenant.html b/custos_portal/custos_portal/templates/workspace/request_new_tenant.html index 55de6e56..bbe84cf7 100644 --- a/custos_portal/custos_portal/templates/workspace/request_new_tenant.html +++ b/custos_portal/custos_portal/templates/workspace/request_new_tenant.html @@ -3,6 +3,6 @@ {% block content %} -
+
{% endblock content %} diff --git a/custos_portal/custos_portal/templates/workspace/view_tenant_request.html b/custos_portal/custos_portal/templates/workspace/view_tenant_request.html index 4b331165..a181305c 100644 --- a/custos_portal/custos_portal/templates/workspace/view_tenant_request.html +++ b/custos_portal/custos_portal/templates/workspace/view_tenant_request.html @@ -3,7 +3,7 @@ {% block content %} -
+
{% endblock content %} \ No newline at end of file