protected override async Task <TerminateProcessResponse> OnTerminateByProcessNoStatusingAsync(int processId, ops.Person terminatingUser, CancellationToken cancellationToken, IDictionary <object, object> context) { try { NetworkIdentification1 terminateUser = new NetworkIdentification1 { Domain = terminatingUser.Network.Domain, NetworkId = terminatingUser.Network.Username }; Binding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport) { SendTimeout = new TimeSpan(0, 5, 0), ReceiveTimeout = new TimeSpan(0, 5, 0) }; ChannelFactory <RoutingSoap> factory = new ChannelFactory <RoutingSoap>(binding, new EndpointAddress(_client.BaseAddress)); RoutingSoap serviceProxy = factory.CreateChannel(); TerminationResponse result = await serviceProxy.TerminateByProcessNoStatusingAsync(processId, terminateUser); factory.Close(); TerminateProcessResponse terminateProcessResponse = new TerminateProcessResponse() { ProcessId = processId, ResultId = result.ResultId, Status = result.Status.ToUpper() }; return(terminateProcessResponse); } catch (Exception exception) { _logger.LogError($"A web service error occurred while terminating the process with id: {processId}. Reason: {exception}"); throw; } }
/// <summary> /// Asynchronously terminates the routing of an instantiated process /// </summary> /// <param name="processId">The unique identifier of the item that will be terminated.</param> /// <param name="terminateNoStatusing">The flag that idicates whether the remote web service will be called and whether or not email will be sent.</param> /// <param name="terminatingUser">The person that is perfoming and action (should be a super user on the process).</param> /// <param name="cancellationToken">The optional token to monitor for cancellation requests.</param> /// <param name="context">The optional execution context that applies to this operation.</param> /// <returns>An integer that contains the new process id.</returns> public async Task <TerminateProcessResponse> TerminateProcessAsync(int processId, bool terminateNoStatusing, Person terminatingUser, CancellationToken cancellationToken, IDictionary <object, object> context) { if (terminatingUser == null) { throw new ArgumentNullException(nameof(terminatingUser)); } try { Process process = (await _processStore.GetAsync(new List <int> { processId, }, 0, 10)).FirstOrDefault(); if (process.ProcessState == "TERMINATED" || process.ProcessState == "APPROVED") { throw new InvalidOperationException($"Invalid request to terminate Process {process.ProcessId} that is already in {process.ProcessState} state!"); } //IList<string> approvedChangeAccounts = await _securityStore.GetAuthorizedAccountsAsync(process, cancellationToken, context); // Verify if the requested account (user or msa account) is authorized to perform this action. string userId = terminatingUser?.Network?.Username; bool isAuthAccount = false; // If the network id is in the authorized change accounts we are done, nothing else matters if (userId != null) { isAuthAccount = await _securityStore.IsAuthorizedChangeAccountAsync(process.ProcessDefinitionId, userId, cancellationToken, context); } // if they are not an authorized change account they need to be a super user bool isSuperUser = false; bool isApprovalsAdmin = false; if (!isAuthAccount) { if (string.IsNullOrEmpty(userId) || (!string.IsNullOrEmpty(userId) && !isAuthAccount)) { userId = terminatingUser.Id ?? terminatingUser.EmployeeId; } isSuperUser = await _securityStore.IsSuperUserAsync(processId, userId, cancellationToken, context); if (!isSuperUser) { isApprovalsAdmin = await _securityStore.IsApprovalsAdminAsync(userId, cancellationToken, context); } } if (isSuperUser || isAuthAccount || isApprovalsAdmin) { TerminateProcessResponse terminateProcessResponse = new TerminateProcessResponse(); string status = $"{process.DocumentTypeName}'- {process.DocumentId}': TERMINATED by: {userId}"; process = await _processStore.TerminateAsync(processId, userId, status, !terminateNoStatusing); if (process.ProcessState != ProcessState.Terminated.Name) { throw new InvalidOperationException($"Unable to terminate Process Instance {processId} by user {userId}"); } terminateProcessResponse.State = process?.ProcessState; terminateProcessResponse.Status = process?.ProcessStatus; terminateProcessResponse.ProcessId = (int)process?.ProcessId; return(terminateProcessResponse); } else { throw new UnauthorizedAccessException($"You do not have sufficient privileges to terminate the process with id {processId}"); } } catch (Exception exception) { _logger.LogError($"Unable to terminate process. Reason: {exception}"); throw; } }
public async Task TerminateProcessAsync_ReturnsResponse_GivenChangeAccount() { int testId = 5; IList <int> testList = new List <int>() { testId, }; // The store needs to return an item that we can use against the logic List <Process> returnList = new List <Process>(); returnList.Add(new Process() { ProcessId = testId, ProcessDefinitionId = testId, ProcessState = "PENDING", Activities = new Dictionary <int, Activity>() { { 1, new Activity() { ActivityId = 1, ActivityState = "PENDING", Actors = new Dictionary <int, Actor>() { { 1, new Actor() { ActorHanfordId = "Valid Id" } } } } } } }); PagedResult <Process> result = new PagedResult <Process>(It.IsAny <int>(), It.IsAny <int>(), It.IsAny <int>(), returnList); _mockProcessStore // arrange .Setup(store => store.GetAsync(It.Is <IList <int> >(s => s[0] == testId), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>(), It.IsAny <IDictionary <object, object> >())) .ReturnsAsync(result); _mockSecurityStore // arrange .Setup(store => store.GetAuthorizedAccountsAsync(It.IsAny <Process>(), It.IsAny <CancellationToken>(), It.IsAny <IDictionary <object, object> >())) .ReturnsAsync(new List <string>() { "Auth Id" }); _mockSecurityStore // arrange .Setup(store => store.IsSuperUserAsync(It.Is <int>(p => p == testId), It.Is <string>(u => u == "Auth Id"), It.IsAny <CancellationToken>(), It.IsAny <IDictionary <object, object> >())) .ReturnsAsync(false); _mockSecurityStore // arrange .Setup(store => store.IsAuthorizedChangeAccountAsync(It.Is <int>(p => p == testId), It.Is <string>(u => u == "Auth Id"), It.IsAny <CancellationToken>(), It.IsAny <IDictionary <object, object> >())) .ReturnsAsync(true); TerminateProcessResponse processResponse = new TerminateProcessResponse() { State = "Terminated", ProcessId = testId }; _mockProcessStore // arrange .Setup(store => store.TerminateAsync(It.Is <int>(s => s == testId), It.Is <string>(u => u == "Auth Id"), It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <CancellationToken>(), It.IsAny <IDictionary <object, object> >())) .ReturnsAsync(new Process() { ProcessId = testId, ProcessState = ProcessState.Terminated.Name }); //_mockApprovalsLegacyStore // arrange // .Setup(store => store.TerminateProcessAsync(It.Is<int>(s => s == testId), It.IsAny<Person>(), It.IsAny<CancellationToken>(), It.IsAny<IDictionary<object, object>>())) // .ReturnsAsync(processResponse); Person person = new Person() { Id = "Auth Id", Network = new NetworkIdentifier() { Username = "******", Id = "Auth Id" } }; //try //{ var facade = InstanceProcessFacade(_mockProcessStore, _mockApprovalsLegacyStore, _mockSecurityStore); var actual = await facade.TerminateProcessAsync(testId, It.IsAny <bool>(), person, It.IsAny <CancellationToken>(), It.IsAny <IDictionary <object, object> >()); Assert.IsInstanceOfType(actual, typeof(TerminateProcessResponse)); //} //catch (Exception ex) //{ // Assert.Fail(); //} // this is the correct behavior for this test }