def are_all_render_results_fresh(self): """Query whether all live WfModules are rendered.""" from .WfModule import WfModule for wf_module in WfModule.live_in_workflow(self): if wf_module.cached_render_result is None: return False return True
def get_workflow_as_delta_and_needs_render(self): """ Return (apply-delta dict, needs_render), or raise Workflow.DoesNotExist needs_render is a (workflow_id, delta_id) pair. """ with Workflow.authorized_lookup_and_cooperative_lock( 'read', self.scope['user'], self.scope['session'], pk=self.workflow_id) as workflow: request = RequestWrapper(self.scope['user'], self.scope['session']) ret = { 'updateWorkflow': (WorkflowSerializer(workflow, context={ 'request': request }).data), } tabs = list(workflow.live_tabs) ret['updateTabs'] = dict( (tab.slug, TabSerializer(tab).data) for tab in tabs) wf_modules = list(WfModule.live_in_workflow(workflow.id)) ret['updateWfModules'] = dict( (str(wfm.id), WfModuleSerializer(wfm).data) for wfm in wf_modules) if workflow.are_all_render_results_fresh(): needs_render = None else: needs_render = (workflow.id, workflow.last_delta_id) return (ret, needs_render)
def wrapper(request: HttpRequest, workflow_id: int, wf_module_slug: str, *args, **kwargs): auth_header = request.headers.get("Authorization", "") auth_header_match = AuthTokenHeaderRegex.match(auth_header) if not auth_header_match: return ErrorResponse(403, "authorization-bearer-token-not-provided") bearer_token = auth_header_match.group(1) try: with Workflow.lookup_and_cooperative_lock( id=workflow_id) as workflow: try: wf_module = WfModule.live_in_workflow(workflow).get( slug=wf_module_slug) except WfModule.DoesNotExist: return ErrorResponse(404, "step-not-found") api_token = wf_module.file_upload_api_token if not api_token: return ErrorResponse(403, "step-has-no-api-token") bearer_token_hash = hashlib.sha256( bearer_token.encode("utf-8")).digest() api_token_hash = hashlib.sha256( api_token.encode("utf-8")).digest() if bearer_token_hash != api_token_hash or bearer_token != api_token: return ErrorResponse(403, "authorization-bearer-token-invalid") return f(request, wf_module, *args, **kwargs) except Workflow.DoesNotExist: return ErrorResponse(404, "workflow-not-found")
def _write_wf_module_position(workflow: Workflow, wf_module_id: int) -> None: """Write position in DB, or raise (Workflow|Tab|WfModule).DoesNotExist.""" with workflow.cooperative_lock(): # raises Workflow.DoesNotExist # Raises WfModule.DoesNotExist, e.g. if tab.is_deleted wf_module = WfModule.live_in_workflow(workflow).get(pk=wf_module_id) tab = wf_module.tab tab.selected_wf_module_position = wf_module.order tab.save(update_fields=['selected_wf_module_position']) workflow.selected_tab_position = tab.position workflow.save(update_fields=['selected_tab_position'])
def wrapper(request: HttpRequest, workflow_id: int, wf_module_slug: str, *args, **kwargs): auth_header = request.headers.get("Authorization", "") auth_header_match = AuthTokenHeaderRegex.match(auth_header) if not auth_header_match: return ErrorResponse(403, "authorization-bearer-token-not-provided") bearer_token = auth_header_match.group(1) try: with Workflow.lookup_and_cooperative_lock( id=workflow_id) as workflow_lock: workflow = workflow_lock.workflow try: wf_module = WfModule.live_in_workflow(workflow).get( slug=wf_module_slug) except WfModule.DoesNotExist: return ErrorResponse(404, "step-not-found") module_version = wf_module.module_version if module_version is None: return ErrorResponse(400, "step-module-deleted") try: file_param_id_name = next( iter(pf.id_name for pf in module_version.param_fields if pf.type == "file")) except StopIteration: return ErrorResponse(400, "step-has-no-file-param") api_token = wf_module.file_upload_api_token if not api_token: return ErrorResponse(403, "step-has-no-api-token") bearer_token_hash = hashlib.sha256( bearer_token.encode("utf-8")).digest() api_token_hash = hashlib.sha256( api_token.encode("utf-8")).digest() if bearer_token_hash != api_token_hash or bearer_token != api_token: return ErrorResponse(403, "authorization-bearer-token-invalid") return f( request, workflow_lock, wf_module, file_param_id_name, *args, **kwargs, ) except Workflow.DoesNotExist: return ErrorResponse(404, "workflow-not-found")
def make_init_state(request, workflow=None, modules=None): """ Build a dict to embed as JSON in `window.initState` in HTML. Raise Http404 if the workflow disappeared. """ ret = {} if workflow: try: with workflow.cooperative_lock(): # raise DoesNotExist on race ret['workflowId'] = workflow.id ret['workflow'] = WorkflowSerializer(workflow, context={ 'request': request }).data tabs = list(workflow.live_tabs) ret['tabs'] = dict( (str(tab.slug), TabSerializer(tab).data) for tab in tabs) wf_modules = list(WfModule.live_in_workflow(workflow)) ret['wfModules'] = { str(wfm.id): WfModuleSerializer(wfm).data for wfm in wf_modules } except Workflow.DoesNotExist: raise Http404('Workflow was recently deleted') ret['uploadConfig'] = { 'bucket': minio.UserFilesBucket, 'accessKey': settings.MINIO_ACCESS_KEY, # never _SECRET_KEY 'server': settings.MINIO_EXTERNAL_URL } ret['user_files_bucket'] = minio.UserFilesBucket if modules: modules_data_list = ModuleSerializer(modules, many=True).data ret['modules'] = dict([(str(m['id_name']), m) for m in modules_data_list]) if request.user.is_authenticated: ret['loggedInUser'] = UserSerializer(request.user).data return ret
def make_init_state(request, workflow=None, modules=None): """ Build a dict to embed as JSON in `window.initState` in HTML. Raise Http404 if the workflow disappeared. Side-effect: update workflow.last_viewed_at. """ ret = {} if workflow: try: with workflow.cooperative_lock(): # raise DoesNotExist on race ret['workflowId'] = workflow.id ret['workflow'] = WorkflowSerializer(workflow, context={ 'request': request }).data tabs = list(workflow.live_tabs) ret['tabs'] = dict( (str(tab.slug), TabSerializer(tab).data) for tab in tabs) wf_modules = list(WfModule.live_in_workflow(workflow)) ret['wfModules'] = { str(wfm.id): WfModuleSerializer(wfm).data for wfm in wf_modules } workflow.last_viewed_at = timezone.now() workflow.save(update_fields=['last_viewed_at']) except Workflow.DoesNotExist: raise Http404('Workflow was recently deleted') if modules: modules_data_list = ModuleSerializer(modules, many=True).data ret['modules'] = dict([(str(m['id_name']), m) for m in modules_data_list]) if request.user.is_authenticated: ret['loggedInUser'] = UserSerializer(request.user).data return ret
def _workflow_has_notifications(workflow): """Detect whether a workflow sends email on changes.""" return WfModule.live_in_workflow(workflow) \ .filter(notifications=True).exists()
def _load_wf_module(workflow: Workflow, wf_module_id: int) -> WfModule: """Returns a WfModule or raises HandlerError.""" try: return WfModule.live_in_workflow(workflow).get(id=wf_module_id) except WfModule.DoesNotExist: raise HandlerError('DoesNotExist: WfModule not found')