protected override async Task ConfirmPermissions(IEnumerable <BCAuthorizePermission> permissions, CancellationToken cancellationToken) { foreach (var grp in permissions.GroupBy(p => p.ConsentId)) { var accountAccessConsent = await _accountAccessConsentRepository.Get(grp.Key, cancellationToken); accountAccessConsent.Confirm(grp.Select(p => p.PermissionId)); await _accountAccessConsentRepository.Update(accountAccessConsent, cancellationToken); } await _accountAccessConsentRepository.SaveChanges(cancellationToken); }
public async Task <GetAccountsResult> Handle(GetAccountsQuery request, CancellationToken cancellationToken) { var jwsPayload = await Extract(request.AccessToken); if (jwsPayload == null) { _logger.LogError("access token is invalid"); throw new OAuthException(ErrorCodes.INVALID_TOKEN, OAuth.ErrorMessages.BAD_TOKEN); } var token = await _tokenQueryRepository.Get(request.AccessToken, cancellationToken); if (token == null) { _logger.LogError("cannot get accounts because access token has been rejected"); throw new OAuthException(ErrorCodes.INVALID_TOKEN, ErrorMessages.ACCESS_TOKEN_REJECTED); } var consentId = jwsPayload[_options.OpenBankingApiConsentClaimName].ToString(); var consent = await _accountAccessConsentRepository.Get(consentId, cancellationToken); if (!consent.Permissions.Contains(AccountAccessConsentPermission.ReadAccountsBasic) && !consent.Permissions.Contains(AccountAccessConsentPermission.ReadAccountsDetail)) { _logger.LogError("no permissions to read accounts"); throw new OAuthException(ErrorCodes.INVALID_REQUEST, Global.NoPermissionToReadAccounts); } var result = await _accountRepository.Get(consent.AccountIds, cancellationToken); return(GetAccountsResult.ToResult(result, consent.Permissions, request.Issuer, 1)); }
public async Task Handle(AccountAccessConsentConfirmedEvent evt, CancellationToken cancellationToken) { var result = await _accountAccessConsentRepository.Get(evt.AggregateId, cancellationToken); result.Handle(evt); await _accountAccessConsentRepository.Update(result, cancellationToken); await _accountAccessConsentRepository.SaveChanges(cancellationToken); }
private void RedirectToConsentView(HandlerContext context, bool ignoreDefaultRedirection = true) { var scopes = context.Request.RequestData.GetScopesFromAuthorizationRequest(); var claims = context.Request.RequestData.GetClaimsFromAuthorizationRequest(); var claim = claims.FirstOrDefault(_ => _.Name == _options.OpenBankingApiConsentClaimName); if (claim == null) { base.RedirectToConsentView(context); return; } if (scopes.Contains(_options.AccountsScope)) { var consentId = claim.Values.First(); var accountAccessConsent = _accountAccessConsentRepository.Get(claim.Values.First(), CancellationToken.None).Result; if (accountAccessConsent == null) { _logger.LogError($"Account Access Consent '{consentId}' doesn't exist"); throw new OAuthException(ErrorCodes.INVALID_REQUEST, string.Format(Global.UnknownAccountAccessConsent, consentId)); } if (accountAccessConsent.ClientId != context.Client.ClientId) { _logger.LogError($"Client is different"); throw new OAuthException(ErrorCodes.INVALID_REQUEST, Global.ClientDifferent); } if (accountAccessConsent.Status == AccountAccessConsentStatus.AwaitingAuthorisation) { throw new OAuthUserConsentRequiredException("OpenBankingApiAccountConsent", "Index"); } if (accountAccessConsent.Status == AccountAccessConsentStatus.Rejected) { _logger.LogError($"Account Access Consent '{consentId}' has already been rejected"); throw new OAuthException(ErrorCodes.INVALID_REQUEST, Global.AccountAccessConsentRejected); } if (accountAccessConsent.Status == AccountAccessConsentStatus.Revoked) { _logger.LogError($"Account Access Consent '{consentId}' has already been revoked"); throw new OAuthException(ErrorCodes.INVALID_REQUEST, Global.AccountAccessConsentRevoked); } return; } var s = string.Join(",", scopes); _logger.LogError($"consent screen cannot be displayed for the scopes '{s}'"); throw new OAuthException(ErrorCodes.INVALID_REQUEST, string.Format(Global.ConsentScreenCannotBeDisplayed, s)); }
public async Task <IActionResult> Index(string returnUrl, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(returnUrl)) { return(RedirectToAction("Index", "Errors", new { code = "invalid_request", ReturnUrl = $"{Request.Path}{Request.QueryString}" })); } try { var unprotectedUrl = _dataProtector.Unprotect(returnUrl); var query = unprotectedUrl.GetQueries().ToJObj(); var clientId = query.GetClientIdFromAuthorizationRequest(); var oauthClient = await _oauthClientRepository.FindOAuthClientById(clientId, cancellationToken); query = await _extractRequestHelper.Extract(Request.GetAbsoluteUriWithVirtualPath(), query, oauthClient); var claims = query.GetClaimsFromAuthorizationRequest(); var claimName = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier); var consentId = claims.Single(c => c.Name == _openbankingApiOptions.OpenBankingApiConsentClaimName).Values.First(); var defaultLanguage = CultureInfo.DefaultThreadCurrentUICulture != null ? CultureInfo.DefaultThreadCurrentUICulture.Name : _oauthHostOptions.DefaultCulture; var claimDescriptions = new List <string>(); if (claims != null && claims.Any()) { claimDescriptions = claims.Select(c => c.Name).ToList(); } var consent = await _accountAccessConsentRepository.Get(consentId, cancellationToken); if (consent == null) { _logger.LogError($"Account Access Consent '{consentId}' doesn't exist"); throw new OAuthException(ErrorCodes.INVALID_REQUEST, string.Format(Global.UnknownAccountAccessConsent, consentId)); } var accounts = await _accountRepository.GetBySubject(claimName.Value, cancellationToken); return(View(new OpenBankingApiAccountConsentIndexViewModel( returnUrl, oauthClient.ClientNames.GetTranslation(defaultLanguage, oauthClient.ClientId), accounts.Select(a => new OpenBankingApiAccountViewModel { Id = a.AggregateId, AccountSubType = a.AccountSubType.Name, CashAccounts = a.Accounts.Select(ac => new OpenBankingApiCashAccountViewModel { Identification = ac.Identification, SecondaryIdentification = ac.SecondaryIdentification }) }).ToList(), new OpenBankingApiConsentAccountViewModel { Id = consent.AggregateId, ExpirationDateTime = consent.ExpirationDateTime, Permissions = consent.Permissions.Select(p => p.Name) }))); } catch (CryptographicException) { return(RedirectToAction("Index", "Errors", new { code = "invalid_request", ReturnUrl = $"{Request.Path}{Request.QueryString}" })); } }