diff --git a/theia/api/admin.py b/theia/api/admin.py index 4fd5490..d7c8980 100644 --- a/theia/api/admin.py +++ b/theia/api/admin.py @@ -1,3 +1,12 @@ from django.contrib import admin # noqa: F401 # Register your models here. + +from .models import * + +admin.site.register(Project) +admin.site.register(Pipeline) +admin.site.register(PipelineStage) +admin.site.register(JobBundle) +admin.site.register(RequestedScene) +admin.site.register(ImageryRequest) diff --git a/theia/api/models/imagery_request.py b/theia/api/models/imagery_request.py index 01ccd7d..416d0b4 100644 --- a/theia/api/models/imagery_request.py +++ b/theia/api/models/imagery_request.py @@ -12,28 +12,32 @@ class ImageryRequest(models.Model): dataset_name = models.CharField(max_length=64, null=False) max_cloud_cover = models.IntegerField(null=True) - begin_date = models.DateTimeField(null=True) - end_date = models.DateTimeField(null=True) + begin_date = models.DateTimeField(null=True, blank=True) + end_date = models.DateTimeField(null=True, blank=True) max_results = models.IntegerField(null=True) wgs_row = models.IntegerField(null=True) wgs_path = models.IntegerField(null=True) - kml_polygon = models.TextField(null=True) - bounding_left = models.FloatField(null=True) - bounding_right = models.FloatField(null=True) - bounding_top = models.FloatField(null=True) - bounding_bottom = models.FloatField(null=True) + kml_polygon = models.TextField(null=True, blank=True) + bounding_left = models.FloatField(null=True, blank=True) + bounding_right = models.FloatField(null=True, blank=True) + bounding_top = models.FloatField(null=True, blank=True) + bounding_bottom = models.FloatField(null=True, blank=True) - user_id = models.IntegerField(null=True) - status = models.IntegerField(db_index=True, default=0) + user_id = models.IntegerField(null=True, blank=True) + status = models.IntegerField(db_index=True, default=0, blank=True) - created_at = models.DateTimeField(null=False, auto_now_add=True, db_index=True) + created_at = models.DateTimeField(null=False, auto_now_add=True, db_index=True, blank=True) project = models.ForeignKey(Project, related_name='imagery_requests', on_delete=models.CASCADE) pipeline = models.ForeignKey(Pipeline, related_name='imagery_requests', on_delete=models.CASCADE) + bearer_token = models.CharField(max_length=2048, default="tist") + refresh_token = models.CharField(max_length=512, default="TAST") + bearer_expiry = models.CharField(max_length=128, default="TESTO") + def __str__(self): when = self.created_at or datetime.utcnow() return '[ImageryRequest project %d at %s]' % (self.project_id, when.strftime('%F')) diff --git a/theia/api/models/pipeline_stage.py b/theia/api/models/pipeline_stage.py index f0fa232..3dcb485 100644 --- a/theia/api/models/pipeline_stage.py +++ b/theia/api/models/pipeline_stage.py @@ -5,10 +5,10 @@ class PipelineStage(models.Model): sort_order = models.IntegerField(null=False) - output_format = models.CharField(max_length=8, null=True) + output_format = models.CharField(max_length=8, null=True, blank=True) operation = models.CharField(max_length=64, null=False) select_images = ArrayField(models.CharField(max_length=64, null=False), null=True) - config = JSONField() + config = JSONField(blank=True) pipeline = models.ForeignKey(Pipeline, related_name='pipeline_stages', on_delete=models.CASCADE) class Meta: diff --git a/theia/api/views/home.py b/theia/api/views/home.py index 18661e9..4446ab3 100644 --- a/theia/api/views/home.py +++ b/theia/api/views/home.py @@ -1,10 +1,17 @@ +from datetime import datetime, timedelta from django.contrib.auth.decorators import login_required from django.shortcuts import render - @login_required def home(request): social_user = request.user.social_auth.get(provider="panoptes") + + request.session['bearer_token'] = social_user.extra_data['access_token'] + request.session['refresh_token'] = social_user.extra_data['refresh_token'] + + bearer_expiry = str(datetime.now() + timedelta(seconds=social_user.extra_data['expires_in'])) + request.session['bearer_expiry'] = bearer_expiry + context = { "projects": social_user.extra_data['projects'] } diff --git a/theia/api/views/imagery_request_view_set.py b/theia/api/views/imagery_request_view_set.py index 9a4c585..537c457 100644 --- a/theia/api/views/imagery_request_view_set.py +++ b/theia/api/views/imagery_request_view_set.py @@ -1,8 +1,24 @@ from theia.api.models import ImageryRequest from rest_framework import viewsets +from rest_framework.response import Response +from rest_framework import status + from theia.api.serializers import ImageryRequestSerializer class ImageryRequestViewSet(viewsets.ModelViewSet): queryset = ImageryRequest.objects.all() serializer_class = ImageryRequestSerializer + + def create(self, request, *args, **kwargs): + copy = request.data.copy() + copy['bearer_token'] = request.session['bearer_token'] + copy['refresh_token'] = request.session['refresh_token'] + copy['bearer_expiry'] = request.session['bearer_expiry'] + + serializer = self.get_serializer(data=copy) + serializer.is_valid(raise_exception=True) + self.perform_create(serializer) + + headers = self.get_success_headers(serializer.data) + return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) \ No newline at end of file diff --git a/theia/operations/panoptes_operations/upload_subject.py b/theia/operations/panoptes_operations/upload_subject.py index d990396..43a68a0 100644 --- a/theia/operations/panoptes_operations/upload_subject.py +++ b/theia/operations/panoptes_operations/upload_subject.py @@ -12,20 +12,25 @@ def apply(self, filenames): else: scope = self.pipeline - self._connect() - - target_set = self._get_subject_set(scope, self.project.id, scope.name_subject_set()) - for filename in filenames: - new_subject = self._create_subject(self.project.id, filename) - target_set.add(new_subject) - - def _connect(self): - Panoptes.connect( - endpoint=PanoptesUtils.base_url(), - client_id=PanoptesUtils.client_id(), - client_secret=PanoptesUtils.client_secret() + self.authenticated_panoptes = Panoptes( + endpoint=PanoptesUtils.base_url(), + client_id=PanoptesUtils.client_id(), + client_secret=PanoptesUtils.client_secret() ) + self.authenticated_panoptes.bearer_token = self.imagery_request.bearer_token + self.authenticated_panoptes.logged_in = True + self.authenticated_panoptes.refresh_token = self.imagery_request.refresh_token + bearer_expiry = datetime.strptime(self.imagery_request.bearer_expiry, "%Y-%m-%d %H:%M:%S.%f") + self.authenticated_panoptes.bearer_expires = (bearer_expiry) + + with self.authenticated_panoptes: + target_set = self._get_subject_set(scope, self.project.id, scope.name_subject_set()) + + for filename in filenames: + new_subject = self._create_subject(self.project.id, filename) + target_set.add(new_subject) + def _get_subject_set(self, scope, project_id, set_name): subject_set = None if not scope.subject_set_id: diff --git a/theia/settings.py b/theia/settings.py index cede01c..f6d22eb 100644 --- a/theia/settings.py +++ b/theia/settings.py @@ -180,5 +180,5 @@ LOGIN_REDIRECT_URL = 'home' LOGOUT_REDIRECT_URL = 'home' -SOCIAL_AUTH_PANOPTES_KEY = os.getenv('PANOPTES_CLIENT_ID') -SOCIAL_AUTH_PANOPTES_SECRET = os.getenv('PANOPTES_CLIENT_SECRET') +SOCIAL_AUTH_PANOPTES_KEY = os.getenv('PANOPTES_PROD_CLIENT_ID') +SOCIAL_AUTH_PANOPTES_SECRET = os.getenv('PANOPTES_PROD_CLIENT_SECRET') diff --git a/theia/utils/panoptes_oauth2.py b/theia/utils/panoptes_oauth2.py index 737be2c..62dadfd 100644 --- a/theia/utils/panoptes_oauth2.py +++ b/theia/utils/panoptes_oauth2.py @@ -22,13 +22,21 @@ class PanoptesOAuth2(BaseOAuth2): ] def get_user_details(self, response): - with Panoptes() as p: - p.bearer_token = response['access_token'] - p.logged_in = True - p.refresh_token = response['refresh_token'] - p.bearer_expires = (datetime.now() + timedelta(seconds=response['expires_in'])) + authenticated_panoptes = Panoptes( + endpoint=PanoptesUtils.base_url(), + client_id=PanoptesUtils.client_id(), + client_secret=PanoptesUtils.client_secret() + ) - user = p.get('/me')[0]['users'][0] + authenticated_panoptes.bearer_token = response['access_token'] + authenticated_panoptes.logged_in = True + authenticated_panoptes.refresh_token = response['refresh_token'] + + bearer_expiry = datetime.now() + timedelta(seconds=response['expires_in']) + authenticated_panoptes.bearer_expires = (bearer_expiry) + + with authenticated_panoptes: + user = authenticated_panoptes.get('/me')[0]['users'][0] ids = ['admin user'] if not user['admin']: @@ -38,7 +46,7 @@ def get_user_details(self, response): 'username': user['login'], 'email': user['email'], 'is_superuser': user['admin'], - 'projects': ids, + 'projects': ids } def get_user_id(self, details, response): diff --git a/theia/utils/panoptes_utils.py b/theia/utils/panoptes_utils.py index 48430e2..2460741 100644 --- a/theia/utils/panoptes_utils.py +++ b/theia/utils/panoptes_utils.py @@ -5,11 +5,11 @@ class PanoptesUtils: @classmethod def client_id(cls): - return os.getenv('PANOPTES_CLIENT_ID') + return os.getenv('PANOPTES_PROD_CLIENT_ID') @classmethod def client_secret(cls): - return os.getenv('PANOPTES_CLIENT_SECRET') + return os.getenv('PANOPTES_PROD_CLIENT_SECRET') @classmethod def url(cls, path): @@ -17,4 +17,4 @@ def url(cls, path): @classmethod def base_url(cls): - return os.getenv('PANOPTES_URL', 'https://panoptes.zooniverse.org/') + return os.getenv('PANOPTES_PROD_URL')