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);
        }
Example #2
0
        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));
        }
Example #5
0
        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}" }));
            }
        }