diff --git a/appstore/api/v1/views.py b/appstore/api/v1/views.py index 428ccb9d..8a3adcba 100644 --- a/appstore/api/v1/views.py +++ b/appstore/api/v1/views.py @@ -225,19 +225,20 @@ def to_bytes(memory): # TODO fetch by user instead of iterating all? # sanitize input to avoid injection. -def get_social_tokens(username): +def get_social_tokens(request): + username = request.user social_token_model_objects = ( ContentType.objects.get(model="socialtoken").model_class().objects.all() ) - access_token = None + access_token = request.COOKIES.get("sessionid") refresh_token = None - for obj in social_token_model_objects: - if obj.account.user.username == username: - access_token = obj.token - refresh_token = obj.token_secret if obj.token_secret else None - break - else: - continue + # for obj in social_token_model_objects: + # if obj.account.user.username == username: + # access_token = obj.token + # refresh_token = obj.token_secret if obj.token_secret else None + # break + # else: + # continue # with DRF and the user interaction in social auth we need username to be a string # when it is passed to `tycho.start` otherwise it will be a `User` object and there # will be a serialization failure from this line of code: @@ -454,12 +455,12 @@ def get_serializer_class(self): return InstanceSerializer @functools.lru_cache(maxsize=16, typed=False) - def get_principal(self, user): + def get_principal(self, request): """ Retrieve principal information from Tycho based on the request user. """ - tokens = get_social_tokens(user) + tokens = get_social_tokens(request) principal = Principal(*tokens) return principal @@ -498,7 +499,7 @@ def list(self, request): """ active = self.get_queryset() - principal = self.get_principal(request.user) + principal = self.get_principal(request) username = principal.username host = get_host(request) instances = [] @@ -551,7 +552,7 @@ def create(self, request): logging.debug(f"resource_request: {resource_request}") irods_enabled = os.environ.get("IROD_HOST",'').strip() # TODO update social query to fetch user. - tokens = get_social_tokens(request.user) + tokens = get_social_tokens(request) #Need to set an environment variable for the IRODS UID if irods_enabled != '': nfs_id = get_nfs_uid(request.user) @@ -588,8 +589,12 @@ def create(self, request): if validation_response is not None: return validation_response + env = {} + if settings.GRADER_API_URL is not None: + env["GRADER_API_URL"] = settings.GRADER_API_URL + host = get_host(request) - system = tycho.start(principal, app_id, resource_request.resources, host) + system = tycho.start(principal, app_id, resource_request.resources, host, env) s = InstanceSpec( @@ -629,7 +634,7 @@ def retrieve(self, request, sid=None): """ Provide active instance details. """ - principal = self.get_principal(request.user) + principal = self.get_principal(request) username = principal.username host = get_host(request) instance = None @@ -646,7 +651,7 @@ def retrieve(self, request, sid=None): @action(detail=True, methods=['get']) def is_ready(self, request, sid=None): - principal = self.get_principal(request.user) + principal = self.get_principal(request) username = principal.username host = get_host(request) instance = None @@ -691,7 +696,7 @@ def partial_update(self, request, sid=None): data = serializer.validated_data data.update({"tycho-guid": sid}) - principal = self.get_principal(request.user) + principal = self.get_principal(request) username = principal.username host = get_host(request) instance = self.get_instance(sid,username,host) diff --git a/appstore/appstore/settings/base.py b/appstore/appstore/settings/base.py index 53d4e4d3..48931e2b 100644 --- a/appstore/appstore/settings/base.py +++ b/appstore/appstore/settings/base.py @@ -131,6 +131,8 @@ "allauth.account.middleware.AccountMiddleware" ] +GRADER_API_URL = os.environ.get("GRADER_API_URL", None) + SESSION_IDLE_TIMEOUT = int(os.environ.get("DJANGO_SESSION_IDLE_TIMEOUT", 300)) EXPORTABLE_ENV = os.environ.get("EXPORTABLE_ENV",None) if EXPORTABLE_ENV != None: EXPORTABLE_ENV = EXPORTABLE_ENV.split(':') diff --git a/appstore/tycho/context.py b/appstore/tycho/context.py index 41c863a8..bfb132ea 100644 --- a/appstore/tycho/context.py +++ b/appstore/tycho/context.py @@ -5,6 +5,7 @@ import uuid import yaml import copy +from typing import TypedDict, Optional from deepmerge import Merger from requests_cache import CachedSession from string import Template @@ -283,7 +284,7 @@ def delete (self, request): def update(self, request): return self.client.patch(request) - def start (self, principal, app_id, resource_request, host): + def start (self, principal, app_id, resource_request, host, extra_container_env={}): """ Get application metadata, docker-compose structure, settings, and compose API request. """ logger.info(f"\nprincipal: {principal}\napp_id: {app_id}\n" f"resource_request: {resource_request}\nhost: {host}") @@ -301,7 +302,13 @@ def start (self, principal, app_id, resource_request, host): """ Use a pre-existing k8s service account """ service_account = self.apps[app_id]['serviceAccount'] if 'serviceAccount' in self.apps[app_id].keys() else None """ Add entity's auth information """ - principal_params = {"username": principal.username, "access_token": principal.access_token, "refresh_token": principal.refresh_token, "host": host} + principal_params = { + "username": principal.username, + "access_token": principal.access_token, + "refresh_token": principal.refresh_token, + "host": host, + "extra_container_env": extra_container_env + } principal_params_json = json.dumps(principal_params, indent=4) """ Security Context that are set for the app """ spec["security_context"] = self.apps[app_id]["securityContext"] if 'securityContext' in self.apps[app_id].keys() else {} diff --git a/appstore/tycho/model.py b/appstore/tycho/model.py index dc1df562..bdd80f79 100644 --- a/appstore/tycho/model.py +++ b/appstore/tycho/model.py @@ -207,7 +207,9 @@ def __init__(self, config, name, principal, service_account, conn_string, proxy_ username_remove_us = self.username.replace("_", "-") username_remove_dot = username_remove_us.replace(".", "-") self.username_all_hyphens = username_remove_dot + self.access_token = principal.get("access_token") self.host = principal.get("host") + self.extra_container_env = principal.get("extra_container_env", {}) self.annotations = {} self.namespace = "default" self.serviceaccount = service_account diff --git a/appstore/tycho/template/pod.yaml b/appstore/tycho/template/pod.yaml index d54e8f3f..408a1ded 100644 --- a/appstore/tycho/template/pod.yaml +++ b/appstore/tycho/template/pod.yaml @@ -109,6 +109,12 @@ spec: value: {{ system.username }} - name: USER value: {{ system.username }} + - name: ACCESS_TOKEN + value: {{ system.access_token }} + {% for key, value in system.extra_container_env.items() %} + - name: {{ key }} + value: {{ value }} + {%endfor %} {% if system.amb %} - name: NB_PREFIX value: /private/{{system.system_name}}/{{system.username}}/{{system.identifier}} @@ -143,9 +149,11 @@ spec: {% endif %} {% endif %} {% if system.system_env %} - {% for env in system.system_env %} - - name: {{ env }} - value: {{ system.system_env[env]}} + {% for key, value in system.system_env.items() %} + {% if value is string or value is number or value is boolean %} + - name: {{ key }} + value: {{ value }} + {% endif %} {% endfor %} {% endif %} {% if container.expose|length > 0 %}