Esempio n. 1
0
        private async Task <ApiResponseType> PostDomesticPayment <ApiRequestType, ApiResponseType>(
            ApiRequestType payment,
            ApiProfile apiProfile,
            SoftwareStatementProfile softwareStatementProfile,
            BankClientProfile bankClientProfile,
            TokenEndpointResponse tokenEndpointResponse)
            where ApiRequestType : class
            where ApiResponseType : class
        {
            string     payloadJson = JsonConvert.SerializeObject(payment);
            UriBuilder ub          = new UriBuilder(new Uri(apiProfile.BaseUrl + "/domestic-payments"));

            List <HttpHeader> headers = CreateRequestHeaders(
                softwareStatement: softwareStatementProfile,
                payment: payment,
                client: bankClientProfile,
                tokenEndpointResponse: tokenEndpointResponse);

            return(await new HttpRequestBuilder()
                   .SetMethod(HttpMethod.Post)
                   .SetUri(ub.Uri)
                   .SetHeaders(headers)
                   .SetContentType("application/json")
                   .SetContent(payloadJson)
                   .Create()
                   .RequestJsonAsync <ApiResponseType>(client: _apiClient, requestContentIsJson: true));
        }
Esempio n. 2
0
        public static ApiProfile BakeOverloads([NotNull] ApiProfile profile)
        {
            var pipeline = new OverloaderPipeline();

            var functionsThatNeedOverloads = profile.NativeSignatures.Where(f => pipeline.HasApplicableStage(f));
            var newOverloads = pipeline.ConsumeSignatures(functionsThatNeedOverloads).ToList();

            // Discard duplicate overloads
            var optimizedOverloads = new List <FunctionSignature>(profile.Overloads);

            foreach (var extensionGroup in newOverloads.GroupBy(f => f.Extension))
            {
                var uniqueOverloads = new List <FunctionSignature>();
                foreach (var function in extensionGroup)
                {
                    if (uniqueOverloads.Any(f => f.HasSameSignatureAs(function)))
                    {
                        continue;
                    }

                    uniqueOverloads.Add(function);
                }

                optimizedOverloads.AddRange(uniqueOverloads);
            }

            return(new ApiProfileBuilder(profile).WithOverloads(optimizedOverloads).Build());
        }
Esempio n. 3
0
        /// <summary>
        /// Writes the given profile to a directory.
        /// </summary>
        /// <param name="generatorSettings">The generator settings to use for the profile writer.</param>
        /// <param name="profile">The profile to write.</param>
        /// <param name="docs">The profile's documentation.</param>
        /// <param name="nc">The name container for this profile.</param>
        public static void Write
        (
            IGeneratorSettings generatorSettings,
            ApiProfile profile,
            ProfileDocumentation docs,
            NameContainer nc
        )
        {
            var rootFolder    = Path.Combine(Program.Arguments.OutputPath, generatorSettings.OutputSubfolder);
            var rootNamespace = generatorSettings.Namespace;

            if (!Directory.Exists(rootFolder))
            {
                Directory.CreateDirectory(rootFolder);
            }

            if (!Directory.Exists(Path.Combine(rootFolder, rootNamespace)))
            {
                Directory.CreateDirectory(Path.Combine(rootFolder, rootNamespace));
            }

            if (!Directory.Exists(Path.Combine(rootFolder, ExtensionsFolder)))
            {
                Directory.CreateDirectory(Path.Combine(rootFolder, ExtensionsFolder));
            }

            foreach (var project in GetProjects(profile))
            {
                WriteProject(project, generatorSettings, nc, docs);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BindingWriter"/> class.
        /// </summary>
        /// <param name="generatorSettings">The generator settings.</param>
        /// <param name="profile">The profile.</param>
        /// <param name="documentation">The documentation for the profile.</param>
        public BindingWriter
        (
            [NotNull] IGeneratorSettings generatorSettings,
            [NotNull] ApiProfile profile,
            [NotNull] ProfileDocumentation documentation
        )
        {
            _generatorSettings = generatorSettings ?? throw new ArgumentNullException(nameof(generatorSettings));
            _profile           = profile ?? throw new ArgumentNullException(nameof(profile));
            _documentation     = documentation ?? throw new ArgumentNullException(nameof(documentation));

            var allFunctions      = profile.NativeSignatures.Concat(profile.Overloads).ToList();
            var enumerationUsages = new Dictionary <EnumerationSignature, IReadOnlyList <FunctionSignature> >();

            foreach (var e in profile.Enumerations)
            {
                // Initialize the dictionary
                var functionsUsingThisEnum = allFunctions
                                             .Where(f => f.Parameters.Any(p => p.Type.Name == e.Name))
                                             .ToList();

                enumerationUsages.Add(e, functionsUsingThisEnum);
            }

            _enumerationUsages = enumerationUsages;

            _entrypointSlots = profile.NativeSignatures
                               .Select((ns, i) => (ns.NativeEntrypoint, i))
                               .ToDictionary(t1 => t1.Item1, t2 => t2.Item2);

            _identifierTranslator = new NativeIdentifierTranslator();
        }
Esempio n. 5
0
        private static IEnumerable <TokenSignature> ResolveReuseEnumerationToken
        (
            [NotNull] string reusedEnumeration,
            [NotNull] ApiProfile coalescedProfile,
            [NotNull] ApiProfileOverride coalescedOverrides
        )
        {
            var profileEnum = coalescedProfile.Enumerations.FirstOrDefault(e => e.Name == reusedEnumeration);

            if (!(profileEnum is null))
            {
                return(profileEnum.Tokens);
            }

            var overrideEnum = coalescedOverrides.AddedEnumerations.FirstOrDefault(e => e.Name == reusedEnumeration);

            if (overrideEnum is null)
            {
                throw new InvalidDataException("Enumeration reuse directive could not be resolved.");
            }

            var results = overrideEnum.DirectTokens;

            foreach (var recursiveReuse in overrideEnum.ReuseEnumerations)
            {
                results = results.Concat
                          (
                    ResolveReuseEnumerationToken(recursiveReuse.Enumeration, coalescedProfile, coalescedOverrides)
                          ).ToList();
            }

            return(results);
        }
Esempio n. 6
0
 public Profile(IndiebackendAPI api, ApiProfile profile, Player player)
 {
     _api         = api;
     _playerToken = player.Token;
     Owner        = player;
     UpdateFromApiResult(profile);
 }
Esempio n. 7
0
        public async Task <Profile> Refresh()
        {
            ApiProfile res = await _api.Profiles.Get(Id, _playerToken);

            UpdateFromApiResult(res, Token);
            return(this);
        }
        public async Task CreateAsync(AuthorisationCallbackDataPublic redirectData)
        {
            redirectData.ArgNotNull(nameof(redirectData));

            // Load relevant data objects
            DomesticConsent consent =
                (await _domesticConsentRepo.GetAsync(dc => dc.State == redirectData.Response.State))
                .FirstOrDefault() ?? throw new KeyNotFoundException(
                          $"Consent with redirect state '{redirectData.Response.State}' not found.");
            ApiProfile apiProfile = await _apiProfileRepo.GetAsync(consent.ApiProfileId) ??
                                    throw new KeyNotFoundException("API profile cannot be found.");

            BankClientProfile bankClientProfile =
                await _openBankingClientRepo.GetAsync(apiProfile.BankClientProfileId) ??
                throw new KeyNotFoundException("Bank client profile cannot be found.");

            SoftwareStatementProfile softwareStatementProfile =
                _softwareStatementProfileService.GetSoftwareStatementProfile(
                    bankClientProfile.SoftwareStatementProfileId);

            // Obtain token for consent
            string redirectUrl = softwareStatementProfile.DefaultFragmentRedirectUrl;
            TokenEndpointResponse tokenEndpointResponse =
                await PostAuthCodeGrant(
                    authCode : redirectData.Response.Code,
                    redirectUrl : redirectUrl,
                    client : bankClientProfile);

            // Update consent with token
            consent.TokenEndpointResponse = tokenEndpointResponse;
            await _dbContextService.SaveChangesAsync();
        }
Esempio n. 9
0
        public async Task <PaymentInitiationApiProfileResponse> CreateAsync(PaymentInitiationApiProfilePublic apiProfile)
        {
            // Check for existing API profile.
            // ApiProfile existingProfile = await _apiProfileRepo
            //     .GetAsync(apiProfile.Id);
            // if (!(existingProfile is null))
            // {
            //     throw new Exception("There is already a API Profile with specified ID.");
            // }

            // Create and store persistent object
            ApiProfile persistentApiProfile = new ApiProfile(
                id: apiProfile.Id,
                bankClientProfileId: apiProfile.BankClientProfileId,
                apiVersion: apiProfile.ApiVersion,
                baseUrl: apiProfile.BaseUrl);
            await _apiProfileRepo.UpsertAsync(persistentApiProfile);

            await _dbContextService.SaveChangesAsync();

            // Return response object
            return(new PaymentInitiationApiProfileResponse(
                       id: persistentApiProfile.Id,
                       bankClientProfileId: persistentApiProfile.BankClientProfileId,
                       apiVersion: persistentApiProfile.ApiVersion,
                       baseUrl: persistentApiProfile.BaseUrl));
        }
Esempio n. 10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ApiProfileBuilder"/> class.
 /// </summary>
 /// <param name="profile">The profile.</param>
 public ApiProfileBuilder([NotNull] ApiProfile profile)
 {
     _newName             = profile.Name;
     _newVersions         = profile.Versions;
     _newNativeSignatures = profile.NativeSignatures;
     _newOverloads        = profile.Overloads;
     _newEnumerations     = profile.Enumerations;
 }
Esempio n. 11
0
 /// <summary>
 /// Splits a profile into a group of projects, each containing the interfaces and enums specific to that
 /// extension or profile.
 /// </summary>
 /// <param name="profile">The profile to split.</param>
 /// <returns>A collection of projects.</returns>
 private static IEnumerable <Project> GetProjects(ApiProfile profile)
 {
     return(GetWithoutEnums(profile.NativeSignatures)
            .Select
            (
                x => new Project(
                    x.Item1,
                    x.Item2,
                    x.Item1 == "Core" ? profile.Enumerations : new EnumerationSignature[0],
                    x.Item3.ToList())
            ));
 }
Esempio n. 12
0
 private void UpdateFromApiResult(ApiProfile profile, string token = null)
 {
     Id          = profile.Id;
     AppId       = profile.AppId;
     Name        = profile.Name;
     OwnerId     = profile.OwnerId;
     DisplayName = profile.DisplayName;
     AvatarUrl   = profile.AvatarUrl;
     CreatedAt   = profile.CreatedAt;
     UpdatedAt   = profile.UpdatedAt;
     Token       = token ?? Token;
     Groups      = new Groups(_api, this);
 }
Esempio n. 13
0
        public static ApiProfile BuildApiProfile()
        {
            var profile = new ApiProfile()
            {
                BaseUrl       = Environment.GetEnvironmentVariable("COVENANT_BASE_URL") ?? "https://127.0.0.1:7443",
                CovenantToken = Environment.GetEnvironmentVariable("COVENANT_TOKEN") ?? "",
                UserName      = Environment.GetEnvironmentVariable("COVENANT_USERNAME") ?? "",
                Password      = Environment.GetEnvironmentVariable("COVENANT_PASSWORD") ?? "",
                IgnoreSSL     = Environment.GetEnvironmentVariable("COVENANT_IGNORE_SSL") == "1" ? true : false
            };

            return(profile);
        }
Esempio n. 14
0
        private static void MergeDuplicateEnumerations(ApiProfile translatedProfile)
        {
            foreach (var e in translatedProfile.Enumerations)
            {
                var l = new List <KeyValuePair <string, TokenSignature> >();
                foreach (var t in e.Tokens)
                {
                    if (l.Any(x => x.Key == t.Name) && l.First(x => x.Key == t.Name).Value.Value == t.Value)
                    {
                        continue;
                    }

                    l.Add(new KeyValuePair <string, TokenSignature>(t.Name, t));
                }

                e.Tokens = l.Select(x => x.Value).ToList();
            }
        }
        private ApiProfile ApplyOverridesToProfile([NotNull] ApiProfile coalescedProfile, [NotNull] ApiProfileOverride coalescedOverrides)
        {
            var newEnums = coalescedOverrides.AddedEnumerations
                           .Select
                           (
                overrideEnum =>
                new EnumerationSignature(overrideEnum.Name, overrideEnum.DirectTokens)
                           )
                           .Concat(coalescedProfile.Enumerations)
                           .ToList();

            var newFunctions = coalescedProfile.NativeSignatures.ToList();

            foreach (var functionReplacement in coalescedOverrides.ReplacedFunctions)
            {
                var baseFunctions = FindBaseFunctions(newFunctions, functionReplacement);
                foreach (var baseFunction in baseFunctions)
                {
                    var overriddenFunction = CreateOverriddenFunction(baseFunction, functionReplacement);

                    newFunctions.Remove(baseFunction);
                    newFunctions.Add(overriddenFunction);
                }
            }

            var newOverloads = new List <FunctionSignature>(coalescedProfile.Overloads);

            foreach (var functionOverload in coalescedOverrides.FunctionOverloads)
            {
                var baseFunctions = FindBaseFunctions(newFunctions, functionOverload);
                foreach (var baseFunction in baseFunctions)
                {
                    var overloadedFunction = CreateOverriddenFunction(baseFunction, functionOverload);

                    newOverloads.Add(overloadedFunction);
                }
            }

            return(new ApiProfileBuilder(coalescedProfile)
                   .WithNativeSignatures(newFunctions)
                   .WithEnumerations(newEnums)
                   .WithOverloads(newOverloads)
                   .Build());
        }
Esempio n. 16
0
        /// <summary>
        /// Asynchronously writes the given profile to a directory.
        /// </summary>
        /// <param name="generatorSettings">The generator settings to use for the profile writer.</param>
        /// <param name="profile">The profile to write.</param>
        /// <param name="docs">The profile's documentation.</param>
        /// <param name="nc">The name container for this profile.</param>
        /// <returns>An asynchronous task.</returns>
        public static Task WriteAsync
        (
            IGeneratorSettings generatorSettings,
            ApiProfile profile,
            ProfileDocumentation docs,
            NameContainer nc
        )
        {
            var rootFolder    = Path.Combine(Program.Arguments.OutputPath, generatorSettings.OutputSubfolder);
            var rootNamespace = generatorSettings.Namespace;

            if (!Directory.Exists(rootFolder))
            {
                Directory.CreateDirectory(rootFolder);
            }

            if (!Directory.Exists(Path.Combine(rootFolder, rootNamespace)))
            {
                Directory.CreateDirectory(Path.Combine(rootFolder, rootNamespace));
            }

            if (!Directory.Exists(Path.Combine(rootFolder, ExtensionsFolder)))
            {
                Directory.CreateDirectory(Path.Combine(rootFolder, ExtensionsFolder));
            }

            return(Task.WhenAll
                   (
                       GetProjects(profile)
                       .Select
                       (
                           x => WriteProjectAsync(
                               x,
                               generatorSettings,
                               nc,
                               docs)
                       )
                   ));
        }
Esempio n. 17
0
        private async Task <ApiResponseType> PostDomesticConsent <ApiRequestType, ApiResponseType>(
            JwtFactory jwtFactory,
            SoftwareStatementProfile softwareStatementProfile,
            ApiRequestType consent,
            ApiProfile apiProfile,
            BankClientProfile bankClientProfile,
            TokenEndpointResponse tokenEndpointResponse)
            where ApiRequestType : class
            where ApiResponseType : class
        {
            string jwt = jwtFactory.CreateJwt(
                profile: softwareStatementProfile,
                claims: consent,
                useOpenBankingJwtHeaders: true);

            string[]          jwsComponents = jwt.Split('.');
            string            jwsSignature  = $"{jwsComponents[0]}..{jwsComponents[2]}";
            UriBuilder        ub            = new UriBuilder(new Uri(apiProfile.BaseUrl + "/domestic-payment-consents"));
            string            payloadJson   = JsonConvert.SerializeObject(consent);
            List <HttpHeader> headers       = new List <HttpHeader>
            {
                new HttpHeader(name: "x-fapi-financial-id", value: bankClientProfile.XFapiFinancialId),
                new HttpHeader(name: "Authorization", value: "Bearer " + tokenEndpointResponse.AccessToken),
                new HttpHeader(name: "x-idempotency-key", value: Guid.NewGuid().ToString()),
                new HttpHeader(name: "x-jws-signature", value: jwsSignature)
            };

            return(await new HttpRequestBuilder()
                   .SetMethod(HttpMethod.Post)
                   .SetUri(ub.Uri)
                   .SetHeaders(headers)
                   .SetContentType("application/json")
                   .SetContent(payloadJson)
                   .Create()
                   .RequestJsonAsync <ApiResponseType>(client: _apiClient, requestContentIsJson: true));
        }
Esempio n. 18
0
 public ProfileModel(ApiProfile profile)
 {
     _profile = profile ?? throw new ArgumentNullException(nameof(profile));
 }
Esempio n. 19
0
        public async Task <PaymentConsentResponse> CreateAsync(DomesticPaymentConsent consent)
        {
            consent.ArgNotNull(nameof(consent));

            // Load relevant objects
            ApiProfile apiProfile = await _apiProfileRepo.GetAsync(consent.ApiProfileId)
                                    ?? throw new KeyNotFoundException("The API Profile does not exist.");

            BankClientProfile bankClientProfile = await _bankClientProfileRepo.GetAsync(apiProfile.BankClientProfileId)
                                                  ?? throw new KeyNotFoundException(
                                                            "The Bank Client Profile does not exist.");

            SoftwareStatementProfile softwareStatementProfile =
                _softwareStatementProfileService.GetSoftwareStatementProfile(
                    bankClientProfile.SoftwareStatementProfileId);

            // Get client credentials grant (we will not cache token for now but simply use to POST consent)
            TokenEndpointResponse tokenEndpointResponse =
                await PostClientCredentialsGrant(scope : "payments", client : bankClientProfile);

            // TODO: validate the response???

            // Create new Open Banking consent by posting JWT
            JwtFactory jwtFactory = new JwtFactory();
            OBWriteDomesticConsentResponse4 consentResponse;

            switch (apiProfile.ApiVersion)
            {
            case ApiVersion.V3P1P1:
                OBWriteDomesticConsent2 newDomesticConsent =
                    _mapper.Map <OBWriteDomesticConsent2>(consent.DomesticConsent);
                OBWriteDomesticConsentResponse2 rawConsentResponse = await
                                                                     PostDomesticConsent <OBWriteDomesticConsent2, OBWriteDomesticConsentResponse2>(
                    jwtFactory : jwtFactory,
                    softwareStatementProfile : softwareStatementProfile,
                    consent : newDomesticConsent,
                    apiProfile : apiProfile,
                    bankClientProfile : bankClientProfile,
                    tokenEndpointResponse : tokenEndpointResponse);

                consentResponse = _mapper.Map <OBWriteDomesticConsentResponse4>(rawConsentResponse);
                break;

            case ApiVersion.V3P1P2:
                throw new ArgumentOutOfRangeException();

            case ApiVersion.V3P1P4:
                consentResponse = await
                                  PostDomesticConsent <OBWriteDomesticConsent4, OBWriteDomesticConsentResponse4>(
                    jwtFactory : jwtFactory,
                    softwareStatementProfile : softwareStatementProfile,
                    consent : consent.DomesticConsent,
                    apiProfile : apiProfile,
                    bankClientProfile : bankClientProfile,
                    tokenEndpointResponse : tokenEndpointResponse);

                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            // Generate URL for user auth
            string consentId   = consentResponse.Data.ConsentId;
            string redirectUrl = softwareStatementProfile.DefaultFragmentRedirectUrl;

            if (redirectUrl == "")
            {
                redirectUrl = bankClientProfile.BankClientRegistrationClaims.RedirectUris[0];
            }

            OAuth2RequestObjectClaims oAuth2RequestObjectClaims = Factories.CreateOAuth2RequestObjectClaims(
                openBankingClient: bankClientProfile,
                redirectUrl: redirectUrl,
                scope: new[] { "openid", "payments" },
                intentId: consentId);
            string requestObjectJwt = jwtFactory.CreateJwt(
                profile: softwareStatementProfile,
                claims: oAuth2RequestObjectClaims,
                useOpenBankingJwtHeaders: false);
            Dictionary <string, string> keyValuePairs = new Dictionary <string, string>
            {
                { "response_type", oAuth2RequestObjectClaims.ResponseType },
                { "client_id", oAuth2RequestObjectClaims.ClientId },
                { "redirect_uri", oAuth2RequestObjectClaims.RedirectUri },
                { "scope", oAuth2RequestObjectClaims.Scope },
                { "request", requestObjectJwt },
                { "nonce", oAuth2RequestObjectClaims.Nonce },
                { "state", oAuth2RequestObjectClaims.State }
            };
            string queryString = keyValuePairs.ToUrlEncoded();
            string authUrl     = bankClientProfile.OpenIdConfiguration.AuthorizationEndpoint + "?" + queryString;

            // Create and store persistent object
            string          domesticConsentId = Guid.NewGuid().ToString();
            DomesticConsent value             = new DomesticConsent
            {
                State = oAuth2RequestObjectClaims.State,
                SoftwareStatementProfileId = bankClientProfile.SoftwareStatementProfileId,
                IssuerUrl              = bankClientProfile.IssuerUrl,
                ApiProfileId           = apiProfile.Id,
                ObWriteDomesticConsent = consent.DomesticConsent,
                TokenEndpointResponse  = null,
                Id     = domesticConsentId,
                BankId = consentId
            };
            await _domesticConsentRepo.UpsertAsync(value);

            await _dbMultiEntityMethods.SaveChangesAsync();

            return(new PaymentConsentResponse
            {
                AuthUrl = authUrl,
                ConsentId = domesticConsentId
            });
        }
Esempio n. 20
0
        private static TokenSignature ResolveEnumerationTokenReference
        (
            [NotNull] string tokenName,
            [CanBeNull] string targetEnumName,
            [NotNull] ApiProfile coalescedProfile,
            [NotNull] ApiProfileOverride coalescedOverrides,
            [CanBeNull] List <string> visitedEnumerations = null
        )
        {
            visitedEnumerations = visitedEnumerations ?? new List <string>();

            if (visitedEnumerations.Contains(targetEnumName))
            {
                Debug.WriteLine(
                    $"Cyclical dependency in enum found when resolving \"{tokenName}\" in \"{targetEnumName}\".");

                return(null);
            }

            var profileEnumCandidates = targetEnumName is null
                ? coalescedProfile.Enumerations
                : coalescedProfile.Enumerations.Where(e => e.Name == targetEnumName);

            var overrideEnumCandidates = targetEnumName is null
                ? coalescedOverrides.AddedEnumerations
                : coalescedOverrides.AddedEnumerations.Where(e => e.Name == targetEnumName);

            foreach (var profileEnum in profileEnumCandidates)
            {
                var token = profileEnum.Tokens.FirstOrDefault(t => t.Name == tokenName);

                if (!(token is null))
                {
                    return(token);
                }
            }

            foreach (var overrideEnum in overrideEnumCandidates)
            {
                var token = overrideEnum.DirectTokens.FirstOrDefault(t => t.Name == tokenName);

                if (!(token is null))
                {
                    return(token);
                }

                var nestedUseToken = overrideEnum.UseTokens.FirstOrDefault(t => t.Token == tokenName);
                if (!(nestedUseToken is null))
                {
                    visitedEnumerations.Add(targetEnumName);

                    // We'll recursively resolve that token until we find it or run out of options, in which case an
                    // exception will be thrown.
                    token = ResolveEnumerationTokenReference(
                        nestedUseToken.Token,
                        nestedUseToken.Enumeration,
                        coalescedProfile,
                        coalescedOverrides,
                        visitedEnumerations);

                    if (!(token is null))
                    {
                        return(token);
                    }
                }

                var reuseTokens = overrideEnum.ReuseEnumerations;
                foreach (var reuseToken in reuseTokens)
                {
                    visitedEnumerations.Add(targetEnumName);

                    // We'll recursively resolve that token until we find it or run out of options
                    token = ResolveEnumerationTokenReference(
                        tokenName,
                        reuseToken.Enumeration,
                        coalescedProfile,
                        coalescedOverrides,
                        visitedEnumerations);

                    if (!(token is null))
                    {
                        return(token);
                    }
                }
            }

            return(null);
        }
Esempio n. 21
0
        /// <summary>
        /// Resolves all external token references in the override enumerations, recursively searching for them as
        /// needed. This method modifies the contents of the <paramref name="coalescedOverrides"/> parameter.
        /// </summary>
        /// <param name="coalescedOverrides">The override profile to resolve the enumerations in.</param>
        /// <param name="coalescedProfile">The profile that the overrides are applicable to.</param>
        private void ResolveEnumerationOverrides([NotNull] ApiProfileOverride coalescedOverrides, [NotNull] ApiProfile coalescedProfile)
        {
            // Resolve the various token references in the enumeration overrides
            foreach (var enumeration in coalescedOverrides.AddedEnumerations.Where(e => e.UseTokens.Any()))
            {
                var resolvedTokens = new List <TokenSignature>();
                foreach (var useToken in enumeration.UseTokens)
                {
                    var tokenName      = useToken.Token;
                    var targetEnumName = useToken.Enumeration;

                    var foundToken =
                        ResolveEnumerationTokenReference(tokenName, targetEnumName, coalescedProfile, coalescedOverrides);

                    if (foundToken is null)
                    {
                        throw new InvalidDataException
                              (
                                  $"Failed to resolve token \"{tokenName}\". Consider using the optional attribute to " +
                                  "suppress this message, or fix the override."
                              );
                    }

                    resolvedTokens.Add(foundToken);
                }

                enumeration.DirectTokens = enumeration.DirectTokens
                                           .Concat(resolvedTokens)
                                           .DistinctBy(t => t.Name)
                                           .ToList();

                enumeration.UseTokens = new List <UseTokenOverride>();
            }

            // Resolve enumeration reuses in the enumeration overrides
            foreach (var enumeration in coalescedOverrides.AddedEnumerations.Where(e => e.ReuseEnumerations.Any()))
            {
                var resolvedTokens = new List <TokenSignature>();
                foreach (var reuseToken in enumeration.ReuseEnumerations)
                {
                    var foundTokens =
                        ResolveReuseEnumerationToken(reuseToken.Enumeration, coalescedProfile, coalescedOverrides);
                    resolvedTokens.AddRange(foundTokens);
                }

                enumeration.DirectTokens = enumeration.DirectTokens
                                           .Concat(resolvedTokens)
                                           .DistinctBy(t => t.Name)
                                           .ToList();

                enumeration.ReuseEnumerations = new List <ReuseEnumerationOverride>();
            }
        }
Esempio n. 22
0
        public async Task <OBWriteDomesticResponse4> CreateAsync(string consentId)
        {
            // Load relevant data objects
            DomesticConsent consent = await _domesticConsentRepo.GetAsync(consentId)
                                      ?? throw new KeyNotFoundException("The Consent does not exist.");

            ApiProfile apiProfile = await _apiProfileRepo.GetAsync(consent.ApiProfileId)
                                    ?? throw new KeyNotFoundException("The API Profile does not exist.");

            BankClientProfile bankClientProfile = await _openBankingClientRepo.GetAsync(apiProfile.BankClientProfileId)
                                                  ?? throw new KeyNotFoundException(
                                                            "The Bank Client Profile does not exist.");

            SoftwareStatementProfile softwareStatementProfile =
                _softwareStatementProfileService.GetSoftwareStatementProfile(
                    bankClientProfile.SoftwareStatementProfileId);

            TokenEndpointResponse tokenEndpointResponse =
                _mapper.Map <TokenEndpointResponse>(consent.TokenEndpointResponse);

            // Create new Open Banking payment by posting JWT
            OBWriteDomesticConsent4 obConsent        = consent.ObWriteDomesticConsent;
            OBWriteDomestic2        referencePayment = new OBWriteDomestic2
            {
                Data = new OBWriteDomestic2Data
                {
                    ConsentId  = consent.BankId,
                    Initiation = obConsent.Data.Initiation
                },
                Risk = obConsent.Risk
            };

            // Create new Open Banking payment by posting JWT
            OBWriteDomesticResponse4 paymentResponse;

            switch (apiProfile.ApiVersion)
            {
            case ApiVersion.V3P1P1:
                ObModels.PaymentInitiation.V3p1p1.Model.OBWriteDomestic2 newPayment =
                    _mapper.Map <ObModels.PaymentInitiation.V3p1p1.Model.OBWriteDomestic2>(referencePayment);
                OBWriteDomesticResponse2 rawPaymentResponse = await
                                                              PostDomesticPayment <ObModels.PaymentInitiation.V3p1p1.Model.OBWriteDomestic2,
                                                                                   OBWriteDomesticResponse2>(
                    payment : newPayment,
                    apiProfile : apiProfile,
                    softwareStatementProfile : softwareStatementProfile,
                    bankClientProfile : bankClientProfile,
                    tokenEndpointResponse : tokenEndpointResponse);

                paymentResponse = _mapper.Map <OBWriteDomesticResponse4>(rawPaymentResponse);
                break;

            case ApiVersion.V3P1P2:
                throw new ArgumentOutOfRangeException();

            case ApiVersion.V3P1P4:
                paymentResponse = await PostDomesticPayment <OBWriteDomestic2, OBWriteDomesticResponse4>(
                    payment : referencePayment,
                    apiProfile : apiProfile,
                    softwareStatementProfile : softwareStatementProfile,
                    bankClientProfile : bankClientProfile,
                    tokenEndpointResponse : tokenEndpointResponse);

                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(paymentResponse);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="DocumentationBaker"/> class.
        /// </summary>
        /// <param name="apiProfile">The profile that the documentation should be baked against.</param>
        public DocumentationBaker([NotNull] ApiProfile apiProfile)
        {
            _apiProfile = apiProfile ?? throw new ArgumentNullException(nameof(apiProfile));

            _identifierTranslator = new NativeIdentifierTranslator();
        }