public async Task <TResult> CreateAuthenticatedAsync <TResult>(Guid integrationId, Guid authenticationId, string methodName, IDictionary <string, string> paramSet, Func <TResult> onSuccess, Func <TResult> onAlreadyExists) { var rollback = new RollbackAsync <TResult>(); var docByMethod = new AccessDocument { LookupId = integrationId, Method = methodName, }; rollback.AddTaskCreate(authenticationId, methodName, docByMethod, onAlreadyExists, this.repository); var integrationDoc = new AuthenticationRequestDocument { LinkedAuthenticationId = authenticationId, Method = methodName, Action = Enum.GetName(typeof(AuthenticationActions), AuthenticationActions.access) }; integrationDoc.SetExtraParams(paramSet); rollback.AddTaskCreate(integrationId, integrationDoc, onAlreadyExists, this.repository); return(await rollback.ExecuteAsync(onSuccess)); }
internal async Task <TResult> CreateCredentialMappingAsync <TResult>(Guid credentialMappingId, CredentialValidationMethodTypes method, string subjectId, Guid actorId, Func <TResult> onSuccess, Func <TResult> onAlreadyExists, Func <TResult> onTokenAlreadyInUse) { var rollback = new RollbackAsync <TResult>(); var methodName = Enum.GetName(typeof(CredentialValidationMethodTypes), method); var credentialMappingDoc = new Documents.CredentialMappingDocument() { Method = methodName, Subject = subjectId, ActorId = actorId, }; rollback.AddTaskCreate(credentialMappingId, credentialMappingDoc, onAlreadyExists, this.repository); var lookupDocument = new Azure.Documents.CredentialMappingLookupDocument() { CredentialMappingId = credentialMappingId, Method = methodName, Subject = subjectId, }; rollback.AddTaskCreate(subjectId, methodName, lookupDocument, onTokenAlreadyInUse, this.repository); rollback.AddTaskCreateOrUpdate(actorId, (Documents.ActorMappingsDocument authDoc) => authDoc.AddInviteId(credentialMappingId), (authDoc) => authDoc.RemoveInviteId(credentialMappingId), onAlreadyExists, // This should fail on the action above as well this.repository); return(await rollback.ExecuteAsync(onSuccess)); }
public async Task <TResult> CreateUnauthenticatedAsync <TResult>(Guid integrationId, Guid accountId, string methodName, Func <TResult> onSuccess, Func <TResult> onAlreadyExists) { var rollback = new RollbackAsync <TResult>(); var docByMethod = new AccessDocument { LookupId = integrationId, Method = methodName, }; rollback.AddTaskCreate(accountId, methodName, docByMethod, onAlreadyExists, this.repository); var docById = new AccessDocument { LookupId = accountId, Method = methodName, }; rollback.AddTaskCreate(integrationId, docById, onAlreadyExists, this.repository); return(await rollback.ExecuteAsync(onSuccess)); }
public async Task <TResult> CreatePasswordCredentialAsync <TResult>(Guid passwordCredentialId, Guid actorId, Guid loginId, DateTime?emailLastSent, Func <TResult> onSuccess, Func <TResult> onAlreadyExists, Func <TResult> onRelationshipAlreadyExists, Func <TResult> onLoginAlreadyUsed) { var rollback = new RollbackAsync <TResult>(); var lookupDoc = new Documents.LoginActorLookupDocument { ActorId = actorId, }; rollback.AddTaskCreate(loginId, lookupDoc, onLoginAlreadyUsed, this.repository); rollback.AddTaskCreateOrUpdate(actorId, (Documents.ActorMappingsDocument actorDoc) => actorDoc.AddPasswordCredential(passwordCredentialId), actorDoc => actorDoc.RemovePasswordCredential(passwordCredentialId), onRelationshipAlreadyExists, this.repository); var passwordCredentialDoc = new Documents.PasswordCredentialDocument { LoginId = loginId, EmailLastSent = emailLastSent, }; rollback.AddTaskCreate(passwordCredentialId, passwordCredentialDoc, onAlreadyExists, this.repository); return(await rollback.ExecuteAsync(onSuccess)); }
internal async Task <TResult> MarkInviteRedeemedAsync <TResult>(Guid inviteToken, Guid loginId, Func <Guid, TResult> onFound, Func <TResult> onNotFound, Func <Guid, TResult> onAlreadyRedeemed, Func <TResult> onAlreadyInUse, Func <TResult> onAlreadyConnected) { var lookupResults = await await repository.FindByIdAsync(inviteToken, async (Documents.InviteTokenDocument tokenDocument) => { var rollback = new RollbackAsync <TResult>(); rollback.AddTaskUpdate(tokenDocument.InviteId, (Documents.InviteDocument inviteDoc) => { inviteDoc.LoginId = loginId; }, (inviteDoc) => { inviteDoc.LoginId = default(Guid?); }, onNotFound, this.repository); var loginLookup = new Documents.LoginActorLookupDocument() { ActorId = tokenDocument.ActorId, }; rollback.AddTaskCreate(loginId, loginLookup, onAlreadyInUse, this.repository); return(await rollback.ExecuteAsync(() => onFound(tokenDocument.ActorId))); }, () => onNotFound().ToTask()); return(lookupResults); }
public static async Task <TRollback> ExecuteDeleteJoinAsync <TRollback, TDocument>(this RollbackAsync <Guid?, TRollback> rollback, Func <TRollback> onSuccess, AzureStorageRepository repo) where TDocument : class, ITableEntity { var result = await await rollback.ExecuteAsync <Task <TRollback> >( async (joinIds) => { var joinId = joinIds.First(joinIdCandidate => joinIdCandidate.HasValue); if (!joinId.HasValue) { return(onSuccess()); } return(await repo.DeleteIfAsync <TDocument, TRollback>(joinId.Value, async(doc, delete) => { await delete(); return onSuccess(); }, () => { // TODO: Log data inconsistency return onSuccess(); })); }, (failureResult) => failureResult.ToTask()); return(result); }
internal static Task <TResult> CreateAsync <TResult>(Guid processStageId, Guid actorId, Guid processStageTypeId, string title, KeyValuePair <Guid[], Guid>[] confirmableActorIds, Guid[] editableActorIds, Guid[] viewableActorIds, Func <TResult> onSuccess, Func <TResult> onAlreadyExists) { return(AzureStorageRepository.Connection( azureStorageRepository => { var rollback = new RollbackAsync <TResult>(); var procStageDoc = new ProcessStageDocument() { Owner = actorId, ProcessStageType = processStageTypeId, Title = title, }; procStageDoc.SetConfirmables(confirmableActorIds); procStageDoc.SetEditables(editableActorIds); procStageDoc.SetViewables(viewableActorIds); rollback.AddTaskCreate(processStageId, procStageDoc, onAlreadyExists, azureStorageRepository); rollback.AddTaskCreateOrUpdate <TResult, Documents.ProcessStageActorLookupDocument>(actorId, (created, lookupDoc) => lookupDoc.AddLookupDocumentId(processStageId), lookupDoc => lookupDoc.RemoveLookupDocumentId(processStageId), azureStorageRepository); return rollback.ExecuteAsync(onSuccess); })); }
public async Task <TResult> CreateAsync <TResult>(Guid integrationId, Guid accountId, CredentialValidationMethodTypes method, IDictionary <string, string> paramSet, Func <TResult> onSuccess, Func <TResult> onAlreadyExists) { var methodName = Enum.GetName(typeof(CredentialValidationMethodTypes), method); var docByMethod = new AccessDocument { LookupId = integrationId, Method = methodName, }; docByMethod.SetExtraParams(paramSet); var docById = new AccessDocument { LookupId = accountId, Method = methodName, }; docById.SetExtraParams(paramSet); var rollback = new RollbackAsync <TResult>(); rollback.AddTaskCreate(accountId, methodName, docByMethod, onAlreadyExists, this.repository); rollback.AddTaskCreate(integrationId, docById, onAlreadyExists, this.repository); return(await rollback.ExecuteAsync(onSuccess)); }
public async Task <TResult> CreateAsync <TResult>( Guid id, Guid actorId, string name, Func <TResult> onSuccess, Func <TResult> onAlreadyExists, Func <TResult> onActorNotFound) { var rollback = new RollbackAsync <TResult>(); var document = new Documents.RoleDocument() { Name = name, ActorId = actorId, }; rollback.AddTaskCreate(id, document, onAlreadyExists, this.azureStorageRepository); rollback.AddTaskCreateOrUpdate(actorId, (Documents.ActorMappingsDocument actorDoc) => { actorDoc.AddRole(id); return(true); }, (actorDoc) => actorDoc.RemoveRole(id), onActorNotFound, this.azureStorageRepository); return(await rollback.ExecuteAsync(onSuccess)); }
public static Task <TResult> Transaction <TResult>(Func <RollbackAsync <TResult>, AzureStorageRepository, Func <TResult> > onConnected) { return(AzureStorageRepository.Connection( connection => { var rollback = new RollbackAsync <TResult>(); var onSuccess = onConnected(rollback, connection); return rollback.ExecuteAsync(onSuccess); })); }
public async Task <TResult> CreateOrUpdateAsync <TResult>(Guid actorId, Guid claimId, string type, string value, Func <TResult> onSuccess, Func <TResult> onFailure, Func <TResult> onActorNotFound) { return(await await repository.FindLinkedDocumentsAsync <ActorMappingsDocument, ClaimDocument, Task <TResult> >(actorId, (ActorMappingsDocument actorMappingsDocument) => actorMappingsDocument.Claims.ToGuidsFromByteArray(), async (ActorMappingsDocument actorMappingsDocument, ClaimDocument[] claimDocuments) => { var claimDocs = claimDocuments.Where( doc => string.Compare(doc.Type, type, StringComparison.OrdinalIgnoreCase) == 0) .ToArray(); if (claimDocs.Length >= 1) { var claimDoc = claimDocs[0]; return await repository.UpdateAsync <ClaimDocument, TResult>(claimDoc.ClaimId, async(currentDoc, saveAsync) => { currentDoc.Value = value; await saveAsync(currentDoc); return onSuccess(); }, () => onFailure()); } var rollback = new RollbackAsync <TResult>(); var newClaimDoc = new ClaimDocument() { ClaimId = claimId, Issuer = actorId.ToString("N"), //TODO - Is this is the correct issuer data??? Type = type, Value = value }; rollback.AddTaskCreate(claimId, newClaimDoc, onFailure, repository); rollback.AddTaskUpdate(actorId, (ActorMappingsDocument actorMapDocument) => actorMapDocument.AddClaim(claimId), (actorMapDocument) => actorMapDocument.RemoveClaim(claimId), onActorNotFound, repository); return await rollback.ExecuteAsync(onSuccess); }, () => onActorNotFound().ToTask())); }
internal async Task <TResult> CreateCredentialMappingAsync <TResult>(Guid credentialMappingId, Guid loginId, Guid actorId, string email, Guid token, DateTime lastSent, bool isToken, bool overrideLoginId, Func <TResult> onSuccess, Func <TResult> onAlreadyExists, Func <TResult> onTokenAlreadyInUse, Func <TResult> onLoginAlreadyInUse) { var rollback = new RollbackAsync <TResult>(); var inviteDocument = new Documents.InviteDocument() { ActorId = actorId, Email = email, IsToken = isToken, LastSent = lastSent, Token = token, LoginId = loginId, }; rollback.AddTaskCreate(credentialMappingId, inviteDocument, onAlreadyExists, this.repository); var inviteTokenDocument = new Documents.InviteTokenDocument() { ActorId = actorId, InviteId = credentialMappingId, }; rollback.AddTaskCreate(token, inviteTokenDocument, onTokenAlreadyInUse, this.repository); if (overrideLoginId) { var oldActorId = default(Guid); rollback.AddTaskCreateOrUpdate(loginId, (Documents.LoginActorLookupDocument loginActorDocument) => { oldActorId = loginActorDocument.ActorId; loginActorDocument.ActorId = actorId; return(true); }, (loginActorDocument) => { loginActorDocument.ActorId = oldActorId; return(true); }, () => { throw new Exception("Login override failed"); }, // Should never happend because always return true on mutate this.repository); } else { var loginActorDocument = new Documents.LoginActorLookupDocument() { ActorId = actorId, }; rollback.AddTaskCreate(loginId, loginActorDocument, onLoginAlreadyInUse, this.repository); } rollback.AddTaskCreateOrUpdate(actorId, (Documents.ActorMappingsDocument authDoc) => authDoc.AddInviteId(credentialMappingId), (authDoc) => authDoc.RemoveInviteId(credentialMappingId), onAlreadyExists, // This should fail on the action above as well this.repository); return(await rollback.ExecuteAsync(onSuccess)); }
public static async Task <TResult> AddJoinAsync <TJoin, TDocJoin, TDoc1, TDoc2, TResult>(this AzureStorageRepository repo, Guid id, Guid id1, Guid id2, TDocJoin document, Func <TDoc1, TJoin[]> getJoins1, Func <TDoc2, TJoin[]> getJoins2, Func <TJoin, Guid> id1FromJoin, Func <TJoin, Guid> id2FromJoin, Action <TDoc1> mutateUpdate1, Action <TDoc1> mutateRollback1, Action <TDoc2> mutateUpdate2, Action <TDoc2> mutateRollback2, Func <TResult> onSuccess, Func <TResult> joinIdAlreadyExist, Func <TJoin, TResult> joinAlreadyExist, Func <TResult> doc1DoesNotExist, Func <TResult> doc2DoesNotExist) where TDocJoin : class, ITableEntity where TDoc1 : class, ITableEntity where TDoc2 : class, ITableEntity { var parallel = new RollbackAsync <TResult>(); var duplicateJoin1 = default(TJoin); parallel.AddTaskUpdate <Guid, TResult, TDoc1>(id1, (doc, successSave, successNoSave, reject) => { var matches = getJoins1(doc).Where(join => id2FromJoin(join) == id2).ToArray(); if (matches.Length > 0) { duplicateJoin1 = matches[0]; return(reject()); } mutateUpdate1(doc); return(successSave(id1)); }, (id1Again, doc) => { mutateRollback1(doc); return(true); }, () => joinAlreadyExist(duplicateJoin1), doc1DoesNotExist, repo); var duplicateJoin2 = default(TJoin); parallel.AddTaskUpdate <Guid, TResult, TDoc2>(id2, (doc, successSave, successNoSave, reject) => { var matches = getJoins2(doc).Where(join => id1FromJoin(join) == id1).ToArray(); if (matches.Length > 0) { duplicateJoin2 = matches[0]; return(reject()); } mutateUpdate2(doc); return(successSave(id2)); }, (id1Again, doc) => { mutateRollback2(doc); return(true); }, () => joinAlreadyExist(duplicateJoin2), doc2DoesNotExist, repo); //parallel.AddTaskUpdate(id2, // mutateUpdate2, // mutateRollback2, // doc2DoesNotExist, // repo); parallel.AddTaskCreate(id, document, () => joinIdAlreadyExist(), repo); var result = await parallel.ExecuteAsync( () => onSuccess(), (failureResult) => failureResult); return(result); }
public static async Task <TRollback> ExecuteAsync <TRollback>(this RollbackAsync <TRollback> rollback, Func <TRollback> onSuccess) { return(await rollback.ExecuteAsync(onSuccess, r => r)); }
internal static Task <TResult> CreateAsync <TResult>(Guid processId, Guid processStageId, Guid actorId, Guid resourceId, Type resourceType, DateTime createdOn, Process.ProcessStageResource[] resources, Guid?previousStepId, DateTime?confirmedWhen, Guid?confirmedBy, Guid [] lookupActorIds, Func <TResult> onSuccess, Func <TResult> onAlreadyExists) { return(AzureStorageRepository.Connection( azureStorageRepository => { var rollback = new RollbackAsync <TResult>(); var resourceTypeString = resourceType.AssemblyQualifiedName; var processDocument = new ProcessDocument() { ProcessStage = processStageId, Resource = resourceId, ResourceType = resourceTypeString, CreatedOn = createdOn, Owner = actorId, ConfirmedBy = confirmedBy, PreviousStep = previousStepId, ConfirmedWhen = confirmedWhen, }; processDocument.SetResources(resources); rollback.AddTaskCreate(processId, processDocument, onAlreadyExists, azureStorageRepository); foreach (var lookupActorId in lookupActorIds.Distinct()) { rollback.AddTaskCreateOrUpdate <TResult, Documents.ProcessStepActorLookupDocument>(lookupActorId, resourceTypeString, (created, lookupDoc) => lookupDoc.AddLookupDocumentId(processId), actorDoc => actorDoc.RemoveLookupDocumentId(processId), azureStorageRepository); } rollback.AddTaskCreateOrUpdate <TResult, Documents.ProcessStepResourceLookupDocument>(resourceId, resourceTypeString, (created, lookupDoc) => lookupDoc.AddLookupDocumentId(processId), actorDoc => actorDoc.RemoveLookupDocumentId(processId), azureStorageRepository); bool[] updates = resources .Select( resource => { if (!resource.resourceId.HasValue) { return true; } rollback.AddTaskCreateOrUpdate <TResult, Documents.ProcessStepResourceKeyLookupDocument>( resource.resourceId.Value, resource.type.AssemblyQualifiedName, (created, lookupDoc) => lookupDoc.AddLookupDocumentId(processId), lookupDoc => lookupDoc.RemoveLookupDocumentId(processId), azureStorageRepository); return true; }) .ToArray(); return rollback.ExecuteAsync(onSuccess); })); }