Exemple #1
0
 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
Exemple #2
0
    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)
Exemple #3
0
    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")
Exemple #4
0
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'])
Exemple #5
0
    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")
Exemple #6
0
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()
Exemple #9
0
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')