def remove_workflow_from_session(request: HttpRequest): """Remove the workflowid, name and number of fows from the session.""" wid = request.session.pop('ontask_workflow_id', None) # If removing workflow from session, mark it as available for sharing if wid: Workflow.unlock_workflow_by_id(wid) request.session.pop('ontask_workflow_name', None) request.session.pop('ontask_workflow_rows', None) request.session.save()
def sqlconnection_admin_index(request): """ Page to show and handle the SQL connections :param request: Request :return: Render the appropriate page. """ wid = request.session.pop('ontask_workflow_id', None) # If removing workflow from session, mark it as available for sharing if wid: Workflow.unlock_workflow_by_id(wid) request.session.pop('ontask_workflow_name', None) return render( request, 'dataops/sql_connections_admin.html', { 'table': SQLConnectionTableAdmin(SQLConnection.objects.all().values( 'id', 'name', 'description_txt'), orderable=False) })
def access_workflow( request, wid: Optional[int], select_related: Optional[Union[str, List]] = None, prefetch_related: Optional[Union[str, List]] = None, ) -> Optional[Workflow]: """Verify that the workflow stored in the request can be accessed. :param request: HTTP request object :param wid: ID of the workflow that is being requested :param select_related: Field to add as select_related query filter :param prefetch_related: Field to add as prefetch_related query filter :return: Workflow object or raise exception with message """ # Lock the workflow object while deciding if it is accessible or not to # avoid race conditions. sid = request.session.get('ontask_workflow_id') if wid is None and sid is None: # No key was given and none was found in the session (anomaly) return None if wid is None: # No WID provided, but the session contains one, carry on # with this one wid = sid elif sid != wid: Workflow.unlock_workflow_by_id(sid) with cache.lock('ONTASK_WORKFLOW_{0}'.format(wid)): # Step 1: Get the workflow that is being accessed workflow = Workflow.objects.filter(id=wid).filter( Q(user=request.user) | Q(shared__id=request.user.id), ) if not workflow: return None # Apply select and prefetch if given if select_related: if isinstance(select_related, list): workflow = workflow.select_related(*select_related) else: workflow = workflow.select_related(select_related) if prefetch_related: if isinstance(prefetch_related, list): workflow = workflow.prefetch_related(*prefetch_related) else: workflow = workflow.prefetch_related(prefetch_related) # Now get the unique element from the query set workflow = workflow.first() # Step 2: If the workflow is locked by this user session, return # correct result (the session_key may be None if using the API) if request.session.session_key == workflow.session_key: # Update nrows. Asynch execution of plugin may have modified it store_workflow_nrows_in_session(request, workflow) return workflow # Step 3: If the workflow is unlocked, LOCK and return if not workflow.session_key: # Workflow is unlocked. Proceed to lock return wf_lock_and_update(request, workflow, create_session=True) # Step 4: The workflow is locked by a session different from this one. # See if the session locking it is still valid session = Session.objects.filter( session_key=workflow.session_key, ).first() if not session: # The session stored as locking the # workflow is no longer in the session table, so the user can # access the workflow return wf_lock_and_update(request, workflow, create_session=True) # Get the owner of the session locking the workflow user_id = session.get_decoded().get('_auth_user_id') if not user_id: # Session has no user_id, so proceed to lock the workflow return wf_lock_and_update(request, workflow) owner = get_user_model().objects.get(id=user_id) # Step 5: The workflow is locked by a session that is valid. See # if the session locking happens to be from the same user (a # previous session that has not been properly closed, or an API # call from the same user) if owner == request.user: return wf_lock_and_update(request, workflow) # Step 6: The workflow is locked by an existing session. See if the # session is valid if session.expire_date >= timezone.now(): raise OnTaskException( _('The workflow is being modified by user {0}').format( owner.email), ) # The workflow is locked by a session that has expired. Take the # workflow and lock it with the current session. return wf_lock_and_update(request, workflow)