public static IHttpResponse ListFlows( [OptionalQueryParameter] string flow, [OptionalQueryParameter] string collections, [OptionalQueryParameter] bool?preferJson, //Security security, IInvokeApplication invokeApplication, HttpApplication httpApp, IHttpRequest request, IProvideUrl url, ContentTypeResponse <string []> onSuccess, NotFoundResponse onNotFound) { var lookups = httpApp .GetResources() .ToArray(); var manifest = new EastFive.Api.Resources.Manifest(lookups, httpApp); var flows = manifest.Routes .SelectMany(route => route.Methods) .SelectMany(method => method.MethodPoco .GetAttributesInterface <IDefineFlow>(multiple: true) .Select(attr => (method, attr))) .GroupBy(methodAndFlow => methodAndFlow.attr.FlowName) .Where(grp => grp.Key.HasBlackSpace()) .Select(grp => grp.Key) .ToArray(); return(onSuccess(flows)); }
public static Task <IHttpResponse> CreateAsync( [Property(Name = Resources.ProcessStageType.IdPropertyName)] Guid processStageTypeId, [Property(Name = Resources.ProcessStageType.OwnerPropertyName)] Guid ownerId, [Property(Name = Resources.ProcessStageType.GroupPropertyName)] Guid processStageGroupId, [Property(Name = Resources.ProcessStageType.TitlePropertyName)] string title, [Property(Name = Resources.ProcessStageType.ResourceTypePropertyName)] Type resourceType, [Property(Name = Resources.ProcessStageType.ResourceKeysPropertyName)] string[] resourceKeys, [Property(Name = Resources.ProcessStageType.ResourceTypesPropertyName)] Type[] resourceTypes, EastFive.Api.Security security, IHttpRequest request, IProvideUrl url, CreatedResponse onCreated, CreatedBodyResponse <ProcessStageType> onCreatedAndModified, AlreadyExistsResponse onAlreadyExists, AlreadyExistsReferencedResponse onRelationshipAlreadyExists, ReferencedDocumentNotFoundResponse onReferenceNotFound, UnauthorizedResponse onUnauthorized, GeneralConflictResponse onFailure) { var resourceList = resourceKeys.Zip(resourceTypes, (k, v) => k.PairWithValue(v)).ToArray(); return(ProcessStageTypes.CreateAsync(processStageTypeId, ownerId, processStageGroupId, title, resourceType, resourceList, security, () => onCreated(), () => onAlreadyExists(), () => onReferenceNotFound(), (brokenId) => onReferenceNotFound(), (why) => onFailure(why))); }
public static IHttpResponse Options(IHttpRequest request, IProvideUrl url, ContentResponse onOption) { var stage = // new Resources.ProcessStageType //{ // Id = Guid.NewGuid(), // Group = ProcessStagesGroups.group1Id, // Title = "Buyer Confirm", // ResourceType = "order", // ResourceKeys = new string[] { "ship_to" }, // ResourceTypes = new string[] { "fulfillment" }, //}; new Resources.ProcessStageType { Id = Guid.NewGuid(), Group = ProcessStagesGroups.group2Id, Title = "Seller Confirm", ResourceType = "order", ResourceKeys = new string[] { "ship_from" }, ResourceTypes = new string[] { "fulfillment" }, }; return(onOption(stage)); }
public static Task <IHttpResponse> CreateAsync( [Property(Name = ProcessStep.IdPropertyName)] Guid processId, [PropertyOptional(Name = ProcessStep.PreviousPropertyName)] Guid?previousStepId, [Property(Name = ProcessStep.ResourcePropertyName)] Guid resourceId, [Property(Name = ProcessStep.StagePropertyName)] Guid processStageId, [Property(Name = ProcessStep.CreatedOnPropertyName)] DateTime createdOn, [PropertyOptional(Name = ProcessStep.ConfirmedByPropertyName)] Guid?confirmedById, [PropertyOptional(Name = ProcessStep.ConfirmedWhenPropertyName)] DateTime?confirmedWhen, [PropertyOptional(Name = ProcessStep.ResourceKeysPropertyName)] string[] resourceKeys, [PropertyOptional(Name = ProcessStep.ResourcesPropertyName)] Guid[] resources, EastFive.Api.Security security, IProvideUrl url, CreatedResponse onCreated, AlreadyExistsResponse onAlreadyExists, ReferencedDocumentDoesNotExistsResponse <Resources.ProcessStage> onStageNotFound, UnauthorizedResponse onUnauthorized, GeneralConflictResponse onFailure) { return(EastFive.Azure.Processes.CreateAsync(processId, processStageId, resourceId, createdOn, resourceKeys.NullToEmpty().Zip(resources.NullToEmpty(), (k, id) => k.PairWithValue(id)).ToArray(), previousStepId, confirmedWhen, confirmedById, security, () => onCreated(), () => onAlreadyExists(), () => onStageNotFound(), (why) => onFailure(why))); }
internal static Resources.ProcessStageType GetResource( EastFive.Azure.ProcessStageType processStageType, IProvideUrl urlHelper) { return(new Resources.ProcessStageType { Id = urlHelper.GetWebId <EastFive.Api.Azure.Resources.ProcessStageType>(processStageType.processStageTypeId), Group = urlHelper.GetWebId <EastFive.Api.Azure.Resources.ProcessStageGroup>(processStageType.processStageGroupId), Title = processStageType.title, ResourceType = processStageType.resourceType.GetCustomAttribute <EastFive.Api.HttpResourceAttribute, string>( attr => attr.ResourceName, () => processStageType.resourceType.AssemblyQualifiedName), ResourceTypes = processStageType.resourceKeys .SelectValues( type => processStageType.resourceType.GetCustomAttribute <EastFive.Api.HttpResourceAttribute, string>( attr => attr.ResourceName, () => processStageType.resourceType.AssemblyQualifiedName)) .ToArray(), ResourceKeys = processStageType.resourceKeys .SelectKeys() .ToArray(), }); }
internal static Resources.ProcessResourceView GetResource( EastFive.Azure.ProcessResourceView view, AzureApplication application, IProvideUrl url) { return(new Resources.ProcessResourceView { Id = url.GetWebId <ProcessResourceView>(view.processViewId), //Actor = application.GetActorLink(view.actorId, url), //Resource = application.GetResourceLink(view.resourceType, view.resourceId, url), ResourceType = application.GetResourceMime(view.resourceType), CurrentProcessStep = url.GetWebId <ProcessStep>(view.currentProcessStepId), Titles = view.titles, Completions = view.completions, Invalidations = view.invalidations, ResourcesDisplayed = view.displayResources, ResourcesProvided = view.resourcesProvided .Select( resourceProvided => new Resources.ProcessResourceView.ConfirmableResource { Key = resourceProvided.key, //Resource = application.GetResourceLink(resourceProvided.type, resourceProvided.resourceId, url), Type = application.GetResourceMime(resourceProvided.type), }) .ToArray(), NextStages = view.nextStages .Select(nextStageId => url.GetWebId <Resources.ProcessStage>(nextStageId.processStageId)) .ToArray(), Editable = view.editable, Completable = view.completable, }); }
public static WebId GetWebId(this IProvideUrl url, Type controllerType, string urnNamespace, string routeName = "DefaultApi") { var controllerName = controllerType.Name.TrimEnd("Controller", (trimmedName) => trimmedName, (originalName) => originalName); if (controllerType.ContainsCustomAttribute <FunctionViewControllerAttribute>()) { var fvcAttr = controllerType.GetCustomAttribute <FunctionViewControllerAttribute>(); if (fvcAttr.Route.HasBlackSpace()) { controllerName = fvcAttr.Route; } } var location = url.Link(routeName, controllerName); return(new WebId { Key = string.Empty, UUID = Guid.Empty, URN = controllerType.GetUrn(urnNamespace), Source = location, }); }
public static Task <IHttpResponse> UpdateProcessStepAsync( [QueryParameter(Name = ProcessStep.IdPropertyName, CheckFileName = true)] Guid processId, [PropertyOptional(Name = ProcessStep.ConfirmedByPropertyName)] Guid?confirmedById, [PropertyOptional(Name = ProcessStep.ConfirmedWhenPropertyName)] DateTime?confirmedWhen, [PropertyOptional(Name = ProcessStep.ResourceKeysPropertyName)] string[] resourceKeys, [PropertyOptional(Name = ProcessStep.ResourcesPropertyName)] Guid[] resources, EastFive.Api.Security security, IProvideUrl url, NoContentResponse onUpdated, NotFoundResponse onNotFound, UnauthorizedResponse onUnauthorized, GeneralConflictResponse onFailure) { return(EastFive.Azure.Processes.UpdateAsync(processId, confirmedById, confirmedWhen, resourceKeys.NullToEmpty().Zip(resources.NullToEmpty(), (k, id) => k.PairWithValue(id)).ToArray(), security, () => onUpdated(), () => onNotFound(), () => onUnauthorized(), (why) => onFailure(why))); //return Connectors.UpdateConnectorAsync(id, // Flow, security.performingAsActorId, security.claims, // () => onUpdated(), // () => onNotFound(), // (why) => onFailure(why)); }
public static IHttpResponse FindAsync( //Security security, HttpApplication application, IHttpRequest request, IProvideUrl url, ContentTypeResponse <WebIdManifest> onFound, ContentTypeResponse <Api.Resources.Manifest> onContent, ViewFileResponse <Api.Resources.Manifest> onHtml) { if (request.GetAcceptTypes().Where(accept => accept.MediaType.ToLower().Contains("html")).Any()) { return(HtmlContent(application, request, url, onHtml)); } LocateControllers(); var endpoints = Manifest.lookup .Select( type => { var endpoint = url.GetWebId(type, "x-com.orderowl:ordering"); return(endpoint); }) .ToArray(); var manifest = new WebIdManifest() { Id = Guid.NewGuid(), Endpoints = endpoints, }; return(onFound(manifest)); }
public static IHttpResponse Options(IHttpRequest request, IProvideUrl url, AzureApplication application, ContentResponse onOption) { return(onOption( GetResource( new EastFive.Azure.Process() { processStageId = Guid.NewGuid(), createdOn = DateTime.UtcNow, processId = Guid.NewGuid(), resourceId = Guid.NewGuid(), resourceType = typeof(EastFive.Azure.ProcessStage), confirmedBy = Guid.NewGuid(), confirmedWhen = DateTime.UtcNow, previousStep = Guid.NewGuid(), resources = Enumerable .Range(0, 3) .Select( i => new EastFive.Azure.Process.ProcessStageResource() { key = $"key{i}", resourceId = Guid.NewGuid(), type = typeof(EastFive.Azure.Process), }) .ToArray(), }, application, url))); }
internal static Resources.ProcessStage GetResource(EastFive.Azure.ProcessStage processStage, IProvideUrl url) { return(new Resources.ProcessStage { Id = url.GetWebId <ProcessStage>(processStage.processStageId), Owner = Library.configurationManager.GetActorLink(processStage.ownerId, url), Title = processStage.title, Type = url.GetWebId <ProcessStageType>(processStage.processStageTypeId), Confirmable = processStage.confirmableIds .Select( confirmableKvp => new Resources.ProcessStage.ConfirmableResource { Positions = confirmableKvp.Key .Select(actorId => Library.configurationManager.GetActorLink(actorId, url)) .ToArray(), ProcessStageNext = url.GetWebId <ProcessStage>(confirmableKvp.Value), }) .ToArray(), Editable = processStage.editableIds .Select(actorId => Library.configurationManager.GetActorLink(actorId, url)) .ToArray(), Completable = processStage.completableIds .Select(actorId => Library.configurationManager.GetActorLink(actorId, url)) .ToArray(), Viewable = processStage.viewableIds .Select(actorId => Library.configurationManager.GetActorLink(actorId, url)) .ToArray(), }); }
public static TResult ParseXlsx <TResource, TResult>(this HttpRequestMessage request, IProvideUrl urlHelper, Stream xlsx, Func <TResource, KeyValuePair <string, string>[], Task <HttpResponseMessage> > executePost, Func <TResource, KeyValuePair <string, string>[], Task <HttpResponseMessage> > executePut, Func <HttpResponseMessage, TResult> onComplete) where TResource : IReferenceable { return(OpenXmlWorkbook.Read(xlsx, (workbook) => { return workbook.ReadCustomValues( (customValues) => { var rowsFromAllSheets = workbook.ReadSheets() .SelectMany( sheet => { var rows = sheet .ReadRows() .ToArray(); if (!rows.Any()) { return rows; } return rows.Skip(1); }).ToArray(); return request.ParseXlsxBackground(urlHelper, customValues, rowsFromAllSheets, executePost, executePut, onComplete); }); })); }
public static async Task <IHttpResponse> Get( [OptionalQueryParameter(Name = ProvideLoginMock.extraParamState)] IRefOptional <Authorization> authorizationRef, [QueryParameter(Name = ProvideLoginMock.extraParamToken)] string token, IAzureApplication application, IProvideUrl urlHelper, IHttpRequest request, RedirectResponse redirectResponse, ServiceUnavailableResponse onNoServiceResponse, BadRequestResponse onBadCredentials, GeneralConflictResponse onFailure) { var authentication = EastFive.Azure.Auth.Method.ByMethodName( ProvideLoginMock.IntegrationName, application); var parameters = new Dictionary <string, string>() { { ProvideLoginMock.extraParamToken, token }, }; if (authorizationRef.HasValue) { parameters.Add(ProvideLoginMock.extraParamState, authorizationRef.id.ToString()); } return(await Redirection.ProcessRequestAsync(authentication, parameters, application, request, urlHelper, (redirect) => { var response = redirectResponse(redirect); return response; }, (why) => onBadCredentials().AddReason($"Bad credentials:{why}"), (why) => onNoServiceResponse().AddReason(why), (why) => onFailure(why))); }
public static async Task <IHttpResponse> PostAsync( [Property(Name = id_token)] string idToken, [Property(Name = state)] IRef <Authorization> authorization, IAzureApplication application, IProvideUrl urlHelper, IHttpRequest request, IInvokeApplication endpoints, RedirectResponse onRedirectResponse, ServiceUnavailableResponse onNoServiceResponse, BadRequestResponse onBadCredentials, GeneralConflictResponse onFailure) { var parameters = new Dictionary <string, string> { { id_token, idToken }, { state, authorization.id.ToString("N") }, }; var method = EastFive.Azure.Auth.Method.ByMethodName( AzureADB2CProvider.IntegrationName, application); return(await EastFive.Azure.Auth.Redirection.ProcessRequestAsync(method, parameters, application, request, endpoints, urlHelper, (redirect, accountIdMaybe) => onRedirectResponse(redirect), (why) => onBadCredentials().AddReason($"Bad credentials:{why}"), (why) => onNoServiceResponse().AddReason(why), (why) => onFailure(why))); }
public static IHttpResponse FindAsync( //Security security, HttpApplication application, IHttpRequest request, IProvideUrl url, NoContentResponse onSuccess, ViewFileResponse <Api.Resources.Manifest> onHtml) { return(onSuccess()); }
public static Uri GetLocation <TResource>(this IProvideUrl url, Expression <Action <TResource> >[] parameters, IApiApplication application, string routeName = "DefaultApi") { var baseUrl = url.GetLocation(typeof(TResource), routeName); return(baseUrl.SetParameters(parameters, application, routeName: routeName)); }
public static Task <IHttpResponse> FindAllAsync( EastFive.Api.Security security, IProvideUrl url, MultipartAcceptArrayResponse onMultipart, UnauthorizedResponse onUnauthorized) { return(ProcessStageTypes.FindAllAsync(security, types => onMultipart(types.Select(type => GetResource(type, url))), () => onUnauthorized())); }
public static IHttpResponse ManifestContent( HttpApplication httpApp, System.Net.Http.HttpRequestMessage request, IProvideUrl url, ContentTypeResponse <Api.Resources.Manifest> onContent) { var lookups = httpApp.GetResources(); var manifest = new EastFive.Api.Resources.Manifest(lookups, httpApp); return(onContent(manifest)); }
public static IHttpResponse HtmlContent( HttpApplication httpApp, IHttpRequest request, IProvideUrl url, ViewFileResponse <Api.Resources.Manifest> onHtml) { var lookups = httpApp.GetResources(); var manifest = new EastFive.Api.Resources.Manifest(lookups, httpApp); return(onHtml("Manifest/Manifest.cshtml", manifest)); }
public static WebId GetWebId <TController>(this IProvideUrl url, Guid?idMaybe, string routeName = "DefaultApi") { if (!idMaybe.HasValue) { return(default(WebId)); } return(url.GetWebId <TController>(idMaybe.Value, routeName)); }
public static Uri GetLocation <TController>(this IProvideUrl url, Guid?idMaybe, string routeName = default(string)) { if (idMaybe.HasValue) { return(url.GetLocation <TController>(idMaybe.Value, routeName)); } return(default(Uri)); }
public static Uri GetLocation <TResource>(this IProvideUrl url, Expression <Action <TResource> > param1, IApiApplication application, string routeName = "DefaultApi") { return(url.GetLocation( new Expression <Action <TResource> >[] { param1 }, application, routeName)); }
public static Uri GetLocation <TController>(this IProvideUrl url, string action, string routeName = "DefaultApi") { var controllerName = typeof(TController).Name.TrimEnd("Controller", (trimmedName) => trimmedName, (originalName) => originalName); var location = url.Link(routeName, controllerName: controllerName, action: action); return(location); }
public static async Task <IHttpResponse> DeleteAsync( [UpdateId(Name = AuthorizationIdPropertyName)] IRef <Authorization> authorizationRef, IProvideUrl urlHelper, AzureApplication application, NoContentResponse onLogoutComplete, AcceptedBodyResponse onExternalSessionActive, NotFoundResponse onNotFound, GeneralFailureResponse onFailure) { return(await authorizationRef.StorageUpdateAsync( async (authorizationToDelete, updateAsync) => { authorizationToDelete.deleted = DateTime.UtcNow; if (!authorizationToDelete.authorized) { return onLogoutComplete().AddReason("Deleted"); } var locationLogout = await await Auth.Method.ById(authorizationToDelete.Method, application, (authentication) => { return authentication.GetLogoutUrlAsync( application, urlHelper, authorizationRef.id); }, () => default(Uri).AsTask()); authorizationToDelete.LocationLogout = locationLogout; await updateAsync(authorizationToDelete); bool NoRedirectRequired() { if (locationLogout.IsDefaultOrNull()) { return true; } if (!locationLogout.IsAbsoluteUri) { return true; } if (locationLogout.AbsoluteUri.IsNullOrWhiteSpace()) { return true; } return false; } if (NoRedirectRequired()) { return onLogoutComplete().AddReason("Logout Complete"); } return onExternalSessionActive(authorizationToDelete, "application/json") .AddReason($"External session removal required:{locationLogout.AbsoluteUri}"); }, () => onNotFound())); }
public static Task <IHttpResponse> FindByResourceAsync( [QueryParameter] Guid resourceId, EastFive.Api.Security security, IProvideUrl url, MultipartAcceptArrayResponse onMultipart, ReferencedDocumentNotFoundResponse onResourceNotFound, UnauthorizedResponse onUnauthorized) { return(EastFive.Azure.ProcessStages.FindByResourceAsync(resourceId, security, (processStages) => onMultipart(processStages.Select(ps => GetResource(ps, url))), () => onResourceNotFound(), () => onUnauthorized())); }
public static IHttpResponse Options(AzureApplication application, IProvideUrl url, ContentResponse onOption) { return(onOption( GetResource( new EastFive.Azure.ProcessResourceView() { processViewId = Guid.NewGuid(), actorId = Guid.NewGuid(), resourceId = Guid.NewGuid(), resourceType = typeof(EastFive.Azure.Process), currentProcessStepId = Guid.NewGuid(), titles = new string[] { "Step 1", "Step 2", "Step 1", "Step 3" }, completions = new DateTime?[] { DateTime.UtcNow - TimeSpan.FromDays(4.0), default(DateTime?), DateTime.UtcNow - TimeSpan.FromDays(2.0), DateTime.UtcNow - TimeSpan.FromDays(1.0), }, invalidations = new DateTime?[] { default(DateTime?), DateTime.UtcNow - TimeSpan.FromDays(3.0), default(DateTime?), default(DateTime?), }, displayResources = new string[] { "process", "process" }, resourcesProvided = new EastFive.Azure.Process.ProcessStageResource[] { new EastFive.Azure.Process.ProcessStageResource { }, new EastFive.Azure.Process.ProcessStageResource { }, }, nextStages = new EastFive.Azure.ProcessStage[] { new EastFive.Azure.ProcessStage { processStageId = Guid.NewGuid(), } }, editable = true, completable = true, }, application, url))); }
public static async Task <IHttpResponse> Post( [PropertyOptional(Name = StatePropertyName)] string state, [PropertyOptional(Name = CodePropertyName)] string code, [PropertyOptional(Name = TokenPropertyName)] string token, [PropertyOptional(Name = UserPropertyName)] string user, IAzureApplication application, IHttpRequest request, IProvideUrl urlHelper, IInvokeApplication endpoints, RedirectResponse onRedirectResponse, BadRequestResponse onBadCredentials, HtmlResponse onCouldNotConnect, HtmlResponse onGeneralFailure) { var method = EastFive.Azure.Auth.Method.ByMethodName( AppleProvider.IntegrationName, application); var requestParams = new Dictionary <string, string>(); if (state.HasBlackSpace()) { requestParams.Add(AppleProvider.responseParamState, state); } if (code.HasBlackSpace()) { requestParams.Add(AppleProvider.responseParamCode, code); } if (token.HasBlackSpace()) { requestParams.Add(AppleProvider.responseParamIdToken, token); } if (user.HasBlackSpace()) { requestParams.Add(AppleProvider.responseParamUser, user); } return(await ProcessRequestAsync(method, requestParams, application, request, endpoints, urlHelper, (redirect, accountIdMaybe) => { return onRedirectResponse(redirect); }, (why) => onBadCredentials().AddReason(why), (why) => { return onCouldNotConnect(why); }, (why) => { return onGeneralFailure(why); })); }
private static TResult ParseXlsxBackground <TResource, TResult>(this HttpRequestMessage request, IProvideUrl urlHelper, KeyValuePair <string, string>[] customValues, string[][] rows, Func <TResource, KeyValuePair <string, string>[], Task <HttpResponseMessage> > executePost, Func <TResource, KeyValuePair <string, string>[], Task <HttpResponseMessage> > executePut, Func <HttpResponseMessage, TResult> onComplete) where TResource : IReferenceable { throw new NotImplementedException(); //var response = request.CreateResponsesBackground(urlHelper, // (updateProgress) => // { // var propertyOrder = typeof(TResource) // .GetProperties() // .OrderBy(propInfo => // propInfo.GetCustomAttribute( // (SheetColumnAttribute sheetColumn) => sheetColumn.GetSortValue(propInfo), // () => propInfo.Name)); // return rows // .Select( // async (row) => // { // var resource = propertyOrder // .Aggregate(Activator.CreateInstance<TResource>(), // (aggr, property, index) => // { // var value = row.Length > index ? // row[index] : default(string); // TryCastFromXlsSerialization(property, value, // (valueCasted) => // { // property.SetValue(aggr, valueCasted); // return true; // }, // () => false); // return aggr; // }); // if (resource.Id.IsEmpty()) // { // resource.Id = Guid.NewGuid(); // var postResponse = await executePost(resource, customValues); // return updateProgress(postResponse); // } // var putResponse = await executePut(resource, customValues); // return updateProgress(putResponse); // }) // .WhenAllAsync(10); // }, // rows.Length); //return onComplete(response); }
public static Task <IHttpResponse> FindByIdAsync( [QueryParameter(CheckFileName = true, Name = ProcessStep.IdPropertyName)] Guid id, AzureApplication httpApplication, EastFive.Api.Security security, IProvideUrl url, ContentResponse onFound, NotFoundResponse onNotFound, UnauthorizedResponse onUnauthorized) { return(EastFive.Azure.Processes.FindByIdAsync(id, security, (process) => onFound(GetResource(process, httpApplication, url)), () => onNotFound(), () => onUnauthorized())); }
public static async Task <IHttpResponse> GetAsync( //[WorkflowNewId] //[WorkflowVariable( // Workflows.PasswordLoginCreateAccount.Variables.State, // AuthorizationPropertyName)] [OptionalQueryParameter(Name = AuthorizationPropertyName)] IRefOptional <Authorization> authorizationRefOptional, [WorkflowParameter( Value = "d989b604-1e25-4d77-b79e-fe1c7d36f833", Description = "Unique and static to each client (i.e. iOS or Web)")] [QueryParameter(Name = ClientPropertyName)] IRef <Client> clientRef, [WorkflowNewId(Description = "No idea what this does.")] [OptionalQueryParameter(Name = ValidationPropertyName)] string validation, IAuthApplication application, IProvideUrl urlHelper, //ContentTypeResponse<Authentication> onFound, [WorkflowVariable( Workflows.PasswordLoginCreateAccount.Variables.Authorization, Authentication.AuthenticationPropertyName)] [WorkflowVariableRedirectUrl( VariableName = Workflows.PasswordLoginCreateAccount.Variables.AuthorizationRedirect)] RedirectResponse onFound, ReferencedDocumentNotFoundResponse <Client> onInvalidClient) { return(await await clientRef.StorageGetAsync( (client) => { var authentication = new Authentication { authenticationRef = SecureGuid.Generate().AsRef <Authentication>(), authorizationMaybe = authorizationRefOptional, client = clientRef, }; return authentication.StorageCreateAsync( (entity) => { var location = urlHelper.GetLocation <Authentication>( auth => auth.authenticationRef.AssignQueryValue(authentication.authenticationRef), application); return onFound(location); }); }, () => onInvalidClient().AsTask())); }