protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput <JwtContainer> input, CacheItem relatedItem) { var userData = _jwtService.GetDataFromJwt <UserIdentitiesData>(input.Data.Jwt).Data; relatedItem.AuthCookieType = CookieType.Passcode; await _savePartialConnectionCommand.ExecuteAsync(userData, relatedItem); await _userHandlerAdapter.UpgradeConnectionAsync(userData.PublicKey, new OwnIdConnection { AuthType = ConnectionAuthType.Passcode, PublicKey = userData.PublicKey, RecoveryData = userData.RecoveryData, RecoveryToken = relatedItem.RecoveryToken }); var composeInfo = new BaseJwtComposeInfo(input) { Behavior = GetNextBehaviorFunc(input, relatedItem) }; var jwt = JwtComposer.GenerateFinalStepJwt(composeInfo); return(new StateResult(jwt, _cookieService.CreateAuthCookies(relatedItem))); }
protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput <JwtContainer> input, CacheItem relatedItem) { var userData = _jwtService.GetDataFromJwt <UserIdentitiesData>(input.Data.Jwt).Data; // Process registration if (relatedItem.ChallengeType == ChallengeType.Register) { return(await FinishAuthProcessAsync(userData, relatedItem, input)); } // Check if user settings override global one var settings = await _userHandlerAdapter.GetUserSettingsAsync(userData.PublicKey); if ( _configuration.TFAEnabled == false && settings?.EnforceTFA == true && userData.AuthType == ConnectionAuthType.Basic) { return(await SwitchConnectionAuthTypeAsync(relatedItem, input, userData.SupportsFido2, userData.PublicKey)); } return(await FinishAuthProcessAsync(userData, relatedItem, input)); }
protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput <StartRequest> input, CacheItem relatedItem) { var wasContinued = CheckIfContinued(input, relatedItem); var composeInfo = new BaseJwtComposeInfo(input) { Behavior = GetNextBehaviorFunc(input, relatedItem), IncludeRequester = true }; var jwt = JwtComposer.GenerateBaseStepJwt(composeInfo, IdentitiesProvider.GenerateUserId()); if (!wasContinued) { await StartFlowCommand.ExecuteAsync(new StartFlowCommand.Input { Context = input.Context, ResponseJwt = jwt, CredIdCookieValue = input.Data.CredId, EncryptionTokenCookieValue = input.Data.EncryptionToken, RecoveryTokenCookieValue = input.Data.RecoveryToken, RequestToken = input.RequestToken }); } return(new JwtContainer { Jwt = jwt }); }
protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput <string> input, CacheItem relatedItem) { relatedItem = await _fido2LinkCommand.ExecuteAsync(input.Data, relatedItem); return(GenerateResult(input, relatedItem)); }
protected override void Validate(TransitionInput<JwtContainer> input, CacheItem relatedItem) { if (!relatedItem.IsValidForLink) throw new CommandValidationException( "Cache item should be not Finished with Link challenge type. " + $"Actual Status={relatedItem.Status.ToString()} ChallengeType={relatedItem.ChallengeType}"); }
protected override async Task ExecuteAsync(HttpContext httpContext) { var input = new TransitionInput(RequestIdentity, GetRequestCulture(httpContext), ClientDate); var result = await _flowRunner.RunAsync(input, StepType.InternalConnectionRecovery); await JsonAsync(httpContext, result, StatusCodes.Status200OK); }
protected override void Validate(TransitionInput <string> input, CacheItem relatedItem) { base.Validate(input, relatedItem); if (string.IsNullOrEmpty(relatedItem.DID)) { throw new CommandValidationException("No user DID was found for recovery"); } }
protected override void Validate(TransitionInput <JwtContainer> input, CacheItem relatedItem) { if (!relatedItem.IsValidForAuthorize) { throw new CommandValidationException( "Cache item should be not be Finished with PARTIAL Login or Register challenge type. " + $"Actual Status={relatedItem.Status.ToString()} ChallengeType={relatedItem.ChallengeType.ToString()}"); } }
private FrontendBehavior NavigateToEnterPasscode(TransitionInput <AcceptStartRequest> input, CacheItem relatedItem) { return(new(StepType.EnterPasscode, relatedItem.ChallengeType, GetNextBehaviorFunc(input, relatedItem)) { AlternativeBehavior = new FrontendBehavior(StepType.ResetPasscode, relatedItem.ChallengeType, new CallAction(UrlProvider.GetResetPasscodeUrl(relatedItem.Context), HttpMethod.Delete.ToString())) });
private async Task <FrontendBehavior> NavigateToPasswordlessPageAsync(TransitionInput <AcceptStartRequest> input, CacheItem relatedItem) { await _verifyFido2CredentialIdCommand.ExecuteAsync(relatedItem); var fido2Url = UrlProvider.GetFido2Url(relatedItem.Context, relatedItem.RequestToken, input.CultureInfo?.Name); return(FrontendBehavior.CreateRedirect(fido2Url)); }
protected override async Task ExecuteAsync(HttpContext httpContext) { var request = await OwnIdSerializer.DeserializeAsync <UserIdentification>(httpContext.Request.Body); var commandInput = new TransitionInput <UserIdentification>(RequestIdentity, GetRequestCulture(httpContext), request, ClientDate); var result = await _flowRunner.RunAsync(commandInput, StepType.CheckUserExistence); await JsonAsync(httpContext, result, StatusCodes.Status200OK); }
private FrontendBehavior OnSuccess(TransitionInput <string> _, CacheItem item) { var challengeType = item.ChallengeType; if (item.ChallengeType == ChallengeType.Register && item.InitialChallengeType == ChallengeType.Login) { challengeType = ChallengeType.LinkOnLogin; } return(FrontendBehavior.CreateSuccessFinish(challengeType)); }
protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput <AcceptStartRequest> input, CacheItem relatedItem) { // TODO: rework preventing fido2 to use recovery link second time if (!input.Data.SupportsFido2 || string.IsNullOrEmpty(input.Data.ExtAuthPayload) || string.IsNullOrEmpty(relatedItem.DID)) { relatedItem = await _recoverAccountCommand.ExecuteAsync(relatedItem); } return(await base.ExecuteInternalAsync(input, relatedItem)); }
protected override async Task ExecuteAsync(HttpContext httpContext) { var request = await OwnIdSerializer.DeserializeAsync <AcceptStartRequest>(httpContext.Request.Body); var input = new TransitionInput <AcceptStartRequest>(RequestIdentity, GetRequestCulture(httpContext), request, ClientDate); var result = await _flowRunner.RunAsync(input, StepType.AcceptStart); await JsonAsync(httpContext, result, StatusCodes.Status200OK); }
protected override void Validate(TransitionInput <StartRequest> input, CacheItem relatedItem) { var wasContinued = CheckIfContinued(input, relatedItem); if (wasContinued && relatedItem.RequestToken != input.RequestToken && relatedItem.ResponseToken != input.ResponseToken) { throw new CommandValidationException( $"Can not continue flow with bypass. Wrong request token actual '{input.RequestToken}' expected '{relatedItem.RequestToken}' or response token actual '{input.ResponseToken}' expected '{relatedItem.ResponseToken}'"); } }
protected override void Validate(TransitionInput <AcceptStartRequest> input, CacheItem relatedItem) { base.Validate(input, relatedItem); if (!relatedItem.IsValidForRecover) { throw new CommandValidationException( "Cache item should be not Finished with Recover challenge type. " + $"Actual Status={relatedItem.Status.ToString()} ChallengeType={relatedItem.ChallengeType}"); } }
private FrontendBehavior GetOnStartAcceptBehavior(TransitionInput <AcceptStartRequest> input, CacheItem cacheItem) { // Recover connection if there is no such but recovery token is available if (!input.Data.AuthType.HasValue && !string.IsNullOrEmpty(cacheItem.RecoveryToken)) { return(GetReferenceToExistingStep(StepType.InternalConnectionRecovery, cacheItem.Context, cacheItem.ChallengeType)); } return(GetOnRecoveryConnectionPassedBehavior(cacheItem)); }
protected StateResult GenerateResult(TransitionInput <string> input, CacheItem relatedItem) { var composeInfo = new BaseJwtComposeInfo(input) { Behavior = GetNextBehaviorFunc(input, relatedItem), }; var jwt = JwtComposer.GenerateBaseStepJwt(composeInfo, relatedItem.DID); //TODO: add remove other cookies return(new StateResult(jwt, _cookieService.CreateAuthCookies(relatedItem))); }
protected override async Task ExecuteAsync(HttpContext httpContext) { var jwtContainer = await GetRequestJwtContainerAsync(httpContext); var commandInput = new TransitionInput <JwtContainer>(RequestIdentity, GetRequestCulture(httpContext), jwtContainer, ClientDate); var result = await _flowRunner.RunAsync(commandInput, StepType.UpgradeToPasscode); await JsonAsync(httpContext, result, StatusCodes.Status200OK); }
private FrontendBehavior OnSuccess <T>(TransitionInput <T> _, CacheItem item) { var challengeType = item.ChallengeType; if (item.ChallengeType == ChallengeType.Register && item.InitialChallengeType == ChallengeType.Login && !CoreConfiguration.LoginOnlyEnabled) { challengeType = ChallengeType.LinkOnLogin; } return(FrontendBehavior.CreateSuccessFinish(challengeType)); }
protected override async Task<ITransitionResult> ExecuteInternalAsync(TransitionInput<JwtContainer> input, CacheItem relatedItem) { relatedItem = await _linkAccountCommand.ExecuteAsync(input.Data, relatedItem); var composeInfo = new BaseJwtComposeInfo(input) { Behavior = GetNextBehaviorFunc(input, relatedItem), }; // TODO: change to generic step generation var jwt = JwtComposer.GenerateFinalStepJwt(composeInfo); return new StateResult(jwt, _cookieService.CreateAuthCookies(relatedItem)); }
protected override void Validate(TransitionInput <JwtContainer> input, CacheItem relatedItem) { if (!relatedItem.IsValidForRecover) { throw new CommandValidationException( "Cache item should be not Finished with Recover challenge type. " + $"Actual Status={relatedItem.Status.ToString()} ChallengeType={relatedItem.ChallengeType}"); } if (string.IsNullOrEmpty(relatedItem.DID)) { throw new CommandValidationException("User DID was not recovered with RecoverAccountCommand"); } }
private async Task <ITransitionResult> FinishAuthProcessAsync(UserIdentitiesData userData, CacheItem relatedItem, TransitionInput <JwtContainer> input) { await _savePartialConnectionCommand.ExecuteAsync(userData, relatedItem); var composeInfo = new BaseJwtComposeInfo(input) { Behavior = FrontendBehavior.CreateSuccessFinish(relatedItem.ChallengeType) }; var jwt = JwtComposer.GenerateFinalStepJwt(composeInfo); return(new StateResult(jwt, _cookieService.CreateAuthCookies(relatedItem))); }
protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput <JwtContainer> input, CacheItem relatedItem) { var userData = _jwtService.GetDataFromJwt <UserIdentitiesData>(input.Data.Jwt).Data; await _savePartialConnectionCommand.ExecuteAsync(userData, relatedItem); var composeInfo = new BaseJwtComposeInfo(input) { Behavior = GetNextBehaviorFunc(input, relatedItem), }; var jwt = JwtComposer.GenerateFinalStepJwt(composeInfo); return(new StateResult(jwt, _cookieService.CreateAuthCookies(relatedItem))); }
internal static JsonObject Generate(TransitionInput transitionInput, ServerInfo serverInfo) { var jsonObject = new JsonObject(); if (serverInfo.BuildNumber >= ServerVersionConstants.BuildNumberJira5) { var id = new JsonObject { { "id", transitionInput.Id.ToString() } }; jsonObject.Add("transition", id.ToJson()); } else { jsonObject.Add("transition", transitionInput.Id.ToString()); } if (transitionInput.Comment != null) { var comment = CommentJsonGenerator.Generate(transitionInput.Comment, serverInfo).ToJson(); if (serverInfo.BuildNumber >= ServerVersionConstants.BuildNumberJira5) { var jsonComment = new JsonArrayObjects { new JsonObject { { "add", comment } } }; var jsonUpdate = new JsonObject { { "comment", jsonComment.ToJson() } }; jsonObject.Add("update", jsonUpdate.ToJson()); } else { jsonObject.Add("comment", comment); } } if (transitionInput.Fields != null && transitionInput.Fields.Any()) { var list = transitionInput.Fields.Where(f => f.Value != null).ToDictionary(f => f.Id, f => ComplexIssueInputFieldValueJsonGenerator.GenerateFieldValueForJson(f.Value)); jsonObject.Add("fields", list.ToJson()); } return(jsonObject); }
protected FrontendBehavior TryAddFido2DisclaimerToBehavior(TransitionInput <AcceptStartRequest> input, CacheItem relatedItem, FrontendBehavior expectedBehavior) { if (CoreConfiguration.TFAEnabled && CoreConfiguration.Fido2FallbackBehavior == Fido2FallbackBehavior.Basic && !input.Data.SupportsFido2 && relatedItem.ChallengeType != ChallengeType.Login) { return new FrontendBehavior(StepType.Fido2Disclaimer, relatedItem.ChallengeType, expectedBehavior) { AlternativeBehavior = GetReferenceToExistingStep(StepType.Stopped, relatedItem.Context, relatedItem.ChallengeType) } } ; return(expectedBehavior); } }
protected override void Validate(TransitionInput <StartRequest> input, CacheItem relatedItem) { base.Validate(input, relatedItem); var wasContinued = CheckIfContinued(input, relatedItem); if (!wasContinued && relatedItem.Status != CacheItemStatus.Initiated && relatedItem.Status != CacheItemStatus.Started) { throw new CommandValidationException( $"Wrong status '{relatedItem.Status.ToString()}' for cache item with context '{input.Context}' to set PIN"); } if (!wasContinued && relatedItem.ConcurrentId != null) { throw new CommandValidationException($"Context '{input.Context}' is already modified with PIN"); } }
protected override void Validate(TransitionInput <string> input, CacheItem relatedItem) { if (relatedItem.FlowType != FlowType.Fido2Login && relatedItem.FlowType != FlowType.Fido2Register && relatedItem.FlowType != FlowType.Fido2LinkWithPin && relatedItem.FlowType != FlowType.Fido2RecoverWithPin && relatedItem.FlowType != FlowType.PartialAuthorize) { throw new CommandValidationException( $"Can not set Fido2 information for the flow not related to Fido2. Current flow: {relatedItem.FlowType} Context: '{relatedItem.Context}'"); } if (relatedItem.Status != CacheItemStatus.Initiated && relatedItem.Status != CacheItemStatus.Started && relatedItem.Status != CacheItemStatus.Approved) { throw new CommandValidationException( $"Incorrect status={relatedItem.Status.ToString()} for setting public key for context '{relatedItem.Context}'"); } }
private async Task <ITransitionResult> SwitchConnectionAuthTypeAsync(CacheItem relatedItem, TransitionInput <JwtContainer> input, bool supportsFido2, string publicKey) { relatedItem.NewAuthType = supportsFido2 && _configuration.Fido2.IsEnabled ? ConnectionAuthType.Fido2 : ConnectionAuthType.Passcode; var composeInfo = new BaseJwtComposeInfo(input) { EncKey = relatedItem.EncKey, EncVector = relatedItem.EncVector }; switch (relatedItem.NewAuthType) { case ConnectionAuthType.Passcode: composeInfo.Behavior = new FrontendBehavior(StepType.EnterPasscode, relatedItem.ChallengeType, GetNextBehaviorFunc(input, relatedItem)) { AlternativeBehavior = new FrontendBehavior(StepType.ResetPasscode, relatedItem.ChallengeType, new CallAction(UrlProvider.GetResetPasscodeUrl(relatedItem.Context), HttpMethod.Delete.ToString())) }; break; case ConnectionAuthType.Fido2: { await _cacheItemRepository.UpdateAsync(relatedItem.Context, item => item.OldPublicKey = publicKey); var fido2Url = UrlProvider.GetFido2Url(relatedItem.Context, relatedItem.RequestToken, input.CultureInfo?.Name); composeInfo.Behavior = FrontendBehavior.CreateRedirect(fido2Url); break; } default: throw new ArgumentOutOfRangeException(); } var jwt = JwtComposer.GenerateBaseStepJwt(composeInfo); return(new StateResult(jwt, _cookieService.CreateAuthCookies(relatedItem))); }
protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput <UserIdentification> input, CacheItem relatedItem) { var result = await _checkUserExistenceCommand.ExecuteAsync(input.Data); if (result) { throw new OwnIdException(ErrorType.UserAlreadyExists); } var composeInfo = new BaseJwtComposeInfo(input) { Behavior = GetNextBehaviorFunc(input, relatedItem) }; var jwt = JwtComposer.GenerateBaseStepJwt(composeInfo); return(new JwtContainer(jwt)); }