Restricting Approver to Revert Workflow

Upkar
New Contributor II

Hi All!

 

We had gotten an ad hoc request to give certain access and restrictions to Preparer Users and Approver Users. Where the Preparer can complete workflow and revert workflow and the Approver can only certify in the Workflow profile. We have been able to successfully achieve restriction on completing workflow for the Approver but not able to restrict them from stopping the Revert workflow. Even after placing conditions to stop the revert workflow the certify is also getting restricted for the approver.
below is the code without any restrictions for Revert workflow for now.  if anyone has resolution for this it will be greatly appreciated. 

Upkar_0-1678946008035.png

 

2 REPLIES 2

JackLacava
Community Manager
Community Manager

Hey Upkar,

I can't help but thinking, however, that this should be achieved with a clean separation of duties, i.e. having a WF profile that is just "Certify" and is only accessible to Approvers, but anyway...

You didn't post where you're triggering your check, but the following technique might work. Instead of working on accessing the Certify step, you let them see the screen but then don't allow them to change state with a DataQualityEventHandler.

 

Case Is = BREventOperationType.DataQuality.Certify.StartSetCertifyState
     If si.UserName.XFEqualsIgnoreCase("admin") Then       ' replace this with your checks
          Dim info As CertifyProcessInfo = args.inputs(0)  ' cast input object
          ' SignOffState is the state we're moving towards, in this case we're certifying
          If info.SignOffState.Equals(CertSignOffStates.ProfileCertified) Then 
              Throw New XFUserMsgException(si, "General", "general param1", "Message")
          End If
     end if

 

Otherwise, the general technique in a Workflow Handler relies on looking up the status of tasks or the overall status of the step. You can explore what is available by casting the object and looking at its properties.

Dim wfinfo As WorkflowInfo = args.inputs(0)
' overall status (i.e. "green bar")
brapi.ErrorLog.LogMessage(si, wfinfo.GetOverallStatus().ToString)
' individual step status, you can have multiple ones e.g. Load and Process
brapi.ErrorLog.LogMessage(si, wfinfo.CurrentStep.Status.ToString)

Upkar
New Contributor II

Hi Jack! 

Thank you for your inputs! 
My Team and I were able to get a breakthrough (I hope), we created event handlers for Forms and Workflow. for now, it's working out as we want it, need to further test it. Below is the code we have in place, please let us know what you think and if we can improve on it. 

Form Event handler- 

Imports System.Collections.Generic
Imports System.Data
Imports System.Data.Common
Imports System.Globalization
Imports System.IO
Imports System.Linq
Imports System.Windows.Forms
Imports Microsoft.VisualBasic
Imports OneStream.Finance.Database
Imports OneStream.Finance.Engine
Imports OneStream.Shared.Common
Imports OneStream.Shared.Database
Imports OneStream.Shared.Engine
Imports OneStream.Shared.Wcf
Imports OneStream.Stage.Database
Imports OneStream.Stage.Engine

Namespace OneStream.BusinessRule.FormsEventHandler.FormsEventHandler
	Public Class MainClass
		Public Function Main(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As Object, ByVal args As FormsEventHandlerArgs) As Object
			Try
				Dim returnValue As Object = args.DefaultReturnValue
				args.UseReturnValueFromBusinessRule = False
				args.Cancel = False				

                Select Case args.OperationName
					Case Is = BREventOperationType.Forms.CompleteForm
						Dim cubeName = brapi.Workflow.Metadata.GetProfile(si, si.WorkflowClusterPk).CubeName
						If (cubeName = "CCR") Then
							If Not BRApi.Security.Authorization.IsUserInGroup(si, "WF_CCR_All_Approver") Then
						    ' Do nothing
							
							Else
								If BRApi.Security.Authorization.IsUserInGroup(si, "WF_CCR_All_Approver") And Not BRApi.Security.Authorization.IsUserInGroup(si, "Administrators") And Not BRApi.Security.Authorization.IsUserInGroup(si, "WF_CCR_All_Preparer")Then
									If (args.IsBeforeEvent = False) Then	
										Throw (New XFUserMsgException(si, Nothing, Nothing, "Security Access Error. Only preparer can execute the current workflow step"))
									End If
								End If
							End If
						End If
					
					Case Is = BREventOperationType.Forms.RevertForm
						Dim cubeName = brapi.Workflow.Metadata.GetProfile(si, si.WorkflowClusterPk).CubeName
							If (cubeName = "CCR") Then
								If Not BRApi.Security.Authorization.IsUserInGroup(si, "WF_CCR_All_Approver")  Then
							    ' Do nothing
								
								Else
									If BRApi.Security.Authorization.IsUserInGroup(si, "WF_CCR_All_Approver") And Not BRApi.Security.Authorization.IsUserInGroup(si, "Administrators") And Not BRApi.Security.Authorization.IsUserInGroup(si, "WF_CCR_All_Preparer") Then
										If (args.IsBeforeEvent = False) Then
											Throw (New XFUserMsgException(si, Nothing, Nothing, "Security Access Error. Only preparer can execute the current workflow step"))
										End If
									End If
								End If
							End If
							
					Case Is = BREventOperationType.Forms.SaveForm
						Dim cubeName = brapi.Workflow.Metadata.GetProfile(si, si.WorkflowClusterPk).CubeName
						If (cubeName = "CCR") Then
							If Not BRApi.Security.Authorization.IsUserInGroup(si, "WF_CCR_All_Approver")  Then
						    ' Do nothing
							
							Else
								If BRApi.Security.Authorization.IsUserInGroup(si, "WF_CCR_All_Approver") And Not BRApi.Security.Authorization.IsUserInGroup(si, "Administrators") And Not BRApi.Security.Authorization.IsUserInGroup(si, "WF_CCR_All_Preparer") Then
									If (args.IsBeforeEvent) Then
										Throw (New XFUserMsgException(si, Nothing, Nothing, "Security Access Error. Only preparer can execute the current workflow step."))
									End If
								End If
							End If
						End If
						
					Case Is = BREventOperationType.Forms.StartUpdateFormWorkflow
						Dim cubeName = brapi.Workflow.Metadata.GetProfile(si, si.WorkflowClusterPk).CubeName
						If (cubeName = "CCR") Then
							If Not BRApi.Security.Authorization.IsUserInGroup(si, "WF_CCR_All_Approver")  Then
						    ' Do nothing
							
							Else
								If BRApi.Security.Authorization.IsUserInGroup(si, "WF_CCR_All_Approver") And Not BRApi.Security.Authorization.IsUserInGroup(si, "Administrators") And Not BRApi.Security.Authorization.IsUserInGroup(si, "WF_CCR_All_Preparer") Then
									If (args.IsBeforeEvent=False) Then
										Throw (New XFUserMsgException(si, Nothing, Nothing, "Security Access Error. Only preparer can execute the current workflow step."))
									End If
								End If
							End If
						End If	
				End Select
				Return returnValue
			Catch ex As Exception
				Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
			End Try
		End Function
	End Class
End Namespace



workflow Event handler - 

Imports System.Data
Imports System.Data.Common
Imports System.IO
Imports System.Collections.Generic
Imports System.Globalization
Imports System.Linq
Imports Microsoft.VisualBasic
Imports System.Windows.Forms
Imports OneStream.Shared.Common
Imports OneStream.Shared.Wcf
Imports OneStream.Shared.Engine
Imports OneStream.Shared.Database
Imports OneStream.Stage.Engine
Imports OneStream.Stage.Database
Imports OneStream.Finance.Engine
Imports OneStream.Finance.Database

Namespace OneStream.BusinessRule.WorkflowEventHandler.WorkflowEventHandler
	Public Class MainClass
		Public Function Main(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As Object, ByVal args As WorkflowEventHandlerArgs) As Object
			Try
				Dim returnValue As Object = args.DefaultReturnValue
				args.UseReturnValueFromBusinessRule = False
				args.Cancel = False
				
				Select Case args.OperationName
					Case Is = BREventOperationType.Workflow.UpdateWorkflowStatus
				
					If (args.IsBeforeEvent) Then
						
						Dim cubeName = brapi.Workflow.Metadata.GetProfile(si, si.WorkflowClusterPk).CubeName
						Dim wfName = BRApi.Workflow.Metadata.GetProfile(si, si.WorkflowClusterPk).Name
						Dim wftype = BRApi.Workflow.Metadata.GetProfile(si, si.WorkflowClusterPk).Type.ToString

						If (cubeName = "CCR" )Then
							If Not wftype = "BaseInput" Then
								If BRApi.Security.Authorization.IsUserInGroup(si, "WF_CCR_All_Approver") And  Not BRApi.Security.Authorization.IsUserInGroup(si, "Administrators") And Not BRApi.Security.Authorization.IsUserInGroup(si, "WF_CCR_All_Preparer")  Then								
									'' APPROVER SHOUDLD CERITFY	
						   			Dim NextIncompleteTaskname As String = BRApi.Workflow.Status.GetWorkflowStatus(si, si.WorkflowClusterPk, True).NextStep.Name.ToString			
									If Not NextIncompleteTaskname.Equals("Certify Workflow Unit") Then	
										Throw (New XFUserMsgException(si, Nothing, Nothing, "Security Access Error. Only preparer can execute the current workflow step."))
									End If	
								End If
							End If
						End If
					End If
				End Select

				Return returnValue
			Catch ex As Exception
				Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
			End Try
		End Function
	End Class
End Namespace