|
| 1 | +/* |
| 2 | + * MDES for Merchants |
| 3 | + * |
| 4 | + * The MDES APIs are designed as RPC style stateless web services where each API endpoint represents an operation to be performed. All request and response payloads are sent in the JSON (JavaScript Object Notation) data-interchange format. Each endpoint in the API specifies the HTTP Method used to access it. All strings in request and response objects are to be UTF-8 encoded. Each API URI includes the major and minor version of API that it conforms to. This will allow multiple concurrent versions of the API to be deployed simultaneously. <br> __Authentication__ Mastercard uses OAuth 1.0a with body hash extension for authenticating the API clients. This requires every request that you send to Mastercard to be signed with an RSA private key. A private-public RSA key pair must be generated consisting of: <br> 1 . A private key for the OAuth signature for API requests. It is recommended to keep the private key in a password-protected or hardware keystore. <br> 2. A public key is shared with Mastercard during the project setup process through either a certificate signing request (CSR) or the API Key Generator. Mastercard will use the public key to verify the OAuth signature that is provided on every API call.<br> An OAUTH1.0a signer library is available on [GitHub](https://github.com/Mastercard/oauth1-signer-java) <br> __Encryption__<br> All communications between Issuer web service and the Mastercard gateway is encrypted using TLS. <br> __Additional Encryption of Sensitive Data__ In addition to the OAuth authentication, when using MDES Digital Enablement Service, any PCI sensitive and all account holder Personally Identifiable Information (PII) data must be encrypted. This requirement applies to the API fields containing encryptedData. Sensitive data is encrypted using a symmetric session (one-time-use) key. The symmetric session key is then wrapped with an RSA Public Key supplied by Mastercard during API setup phase (the Customer Encryption Key). <br> Java Client Encryption Library available on [GitHub](https://github.com/Mastercard/client-encryption-java) |
| 5 | + * |
| 6 | + * The version of the OpenAPI document: 1.2.10 |
| 7 | + * Generated by: https://github.com/openapitools/openapi-generator.git |
| 8 | + */ |
| 9 | + |
| 10 | + |
| 11 | +using System; |
| 12 | +using System.Collections; |
| 13 | +using System.Globalization; |
| 14 | +using System.IO; |
| 15 | +using System.Linq; |
| 16 | +using System.Text; |
| 17 | +using System.Text.RegularExpressions; |
| 18 | + |
| 19 | +namespace Acme.App.MastercardApi.Client.Client |
| 20 | +{ |
| 21 | + /// <summary> |
| 22 | + /// Utility functions providing some benefit to API client consumers. |
| 23 | + /// </summary> |
| 24 | + public static class ClientUtils |
| 25 | + { |
| 26 | + /// <summary> |
| 27 | + /// Sanitize filename by removing the path |
| 28 | + /// </summary> |
| 29 | + /// <param name="filename">Filename</param> |
| 30 | + /// <returns>Filename</returns> |
| 31 | + public static string SanitizeFilename(string filename) |
| 32 | + { |
| 33 | + Match match = Regex.Match(filename, @".*[/\\](.*)$"); |
| 34 | + return match.Success ? match.Groups[1].Value : filename; |
| 35 | + } |
| 36 | + |
| 37 | + /// <summary> |
| 38 | + /// Convert params to key/value pairs. |
| 39 | + /// Use collectionFormat to properly format lists and collections. |
| 40 | + /// </summary> |
| 41 | + /// <param name="collectionFormat">The swagger-supported collection format, one of: csv, tsv, ssv, pipes, multi</param> |
| 42 | + /// <param name="name">Key name.</param> |
| 43 | + /// <param name="value">Value object.</param> |
| 44 | + /// <returns>A multimap of keys with 1..n associated values.</returns> |
| 45 | + public static Multimap<string, string> ParameterToMultiMap(string collectionFormat, string name, object value) |
| 46 | + { |
| 47 | + var parameters = new Multimap<string, string>(); |
| 48 | + |
| 49 | + if (value is ICollection collection && collectionFormat == "multi") |
| 50 | + { |
| 51 | + foreach (var item in collection) |
| 52 | + { |
| 53 | + parameters.Add(name, ParameterToString(item)); |
| 54 | + } |
| 55 | + } |
| 56 | + else |
| 57 | + { |
| 58 | + parameters.Add(name, ParameterToString(value)); |
| 59 | + } |
| 60 | + |
| 61 | + return parameters; |
| 62 | + } |
| 63 | + |
| 64 | + /// <summary> |
| 65 | + /// If parameter is DateTime, output in a formatted string (default ISO 8601), customizable with Configuration.DateTime. |
| 66 | + /// If parameter is a list, join the list with ",". |
| 67 | + /// Otherwise just return the string. |
| 68 | + /// </summary> |
| 69 | + /// <param name="obj">The parameter (header, path, query, form).</param> |
| 70 | + /// <param name="configuration">An optional configuration instance, providing formatting options used in processing.</param> |
| 71 | + /// <returns>Formatted string.</returns> |
| 72 | + public static string ParameterToString(object obj, IReadableConfiguration configuration = null) |
| 73 | + { |
| 74 | + if (obj is DateTime dateTime) |
| 75 | + // Return a formatted date string - Can be customized with Configuration.DateTimeFormat |
| 76 | + // Defaults to an ISO 8601, using the known as a Round-trip date/time pattern ("o") |
| 77 | + // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8 |
| 78 | + // For example: 2009-06-15T13:45:30.0000000 |
| 79 | + return dateTime.ToString((configuration ?? GlobalConfiguration.Instance).DateTimeFormat); |
| 80 | + if (obj is DateTimeOffset dateTimeOffset) |
| 81 | + // Return a formatted date string - Can be customized with Configuration.DateTimeFormat |
| 82 | + // Defaults to an ISO 8601, using the known as a Round-trip date/time pattern ("o") |
| 83 | + // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx#Anchor_8 |
| 84 | + // For example: 2009-06-15T13:45:30.0000000 |
| 85 | + return dateTimeOffset.ToString((configuration ?? GlobalConfiguration.Instance).DateTimeFormat); |
| 86 | + if (obj is bool boolean) |
| 87 | + return boolean ? "true" : "false"; |
| 88 | + if (obj is ICollection collection) |
| 89 | + return string.Join(",", collection.Cast<object>()); |
| 90 | + |
| 91 | + return Convert.ToString(obj, CultureInfo.InvariantCulture); |
| 92 | + } |
| 93 | + |
| 94 | + /// <summary> |
| 95 | + /// URL encode a string |
| 96 | + /// Credit/Ref: https://github.com/restsharp/RestSharp/blob/master/RestSharp/Extensions/StringExtensions.cs#L50 |
| 97 | + /// </summary> |
| 98 | + /// <param name="input">String to be URL encoded</param> |
| 99 | + /// <returns>Byte array</returns> |
| 100 | + public static string UrlEncode(string input) |
| 101 | + { |
| 102 | + const int maxLength = 32766; |
| 103 | + |
| 104 | + if (input == null) |
| 105 | + { |
| 106 | + throw new ArgumentNullException("input"); |
| 107 | + } |
| 108 | + |
| 109 | + if (input.Length <= maxLength) |
| 110 | + { |
| 111 | + return Uri.EscapeDataString(input); |
| 112 | + } |
| 113 | + |
| 114 | + StringBuilder sb = new StringBuilder(input.Length * 2); |
| 115 | + int index = 0; |
| 116 | + |
| 117 | + while (index < input.Length) |
| 118 | + { |
| 119 | + int length = Math.Min(input.Length - index, maxLength); |
| 120 | + string subString = input.Substring(index, length); |
| 121 | + |
| 122 | + sb.Append(Uri.EscapeDataString(subString)); |
| 123 | + index += subString.Length; |
| 124 | + } |
| 125 | + |
| 126 | + return sb.ToString(); |
| 127 | + } |
| 128 | + |
| 129 | + /// <summary> |
| 130 | + /// Encode string in base64 format. |
| 131 | + /// </summary> |
| 132 | + /// <param name="text">String to be encoded.</param> |
| 133 | + /// <returns>Encoded string.</returns> |
| 134 | + public static string Base64Encode(string text) |
| 135 | + { |
| 136 | + return Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(text)); |
| 137 | + } |
| 138 | + |
| 139 | + /// <summary> |
| 140 | + /// Convert stream to byte array |
| 141 | + /// </summary> |
| 142 | + /// <param name="inputStream">Input stream to be converted</param> |
| 143 | + /// <returns>Byte array</returns> |
| 144 | + public static byte[] ReadAsBytes(Stream inputStream) |
| 145 | + { |
| 146 | + using (var ms = new MemoryStream()) |
| 147 | + { |
| 148 | + inputStream.CopyTo(ms); |
| 149 | + return ms.ToArray(); |
| 150 | + } |
| 151 | + } |
| 152 | + |
| 153 | + /// <summary> |
| 154 | + /// Select the Content-Type header's value from the given content-type array: |
| 155 | + /// if JSON type exists in the given array, use it; |
| 156 | + /// otherwise use the first one defined in 'consumes' |
| 157 | + /// </summary> |
| 158 | + /// <param name="contentTypes">The Content-Type array to select from.</param> |
| 159 | + /// <returns>The Content-Type header to use.</returns> |
| 160 | + public static String SelectHeaderContentType(String[] contentTypes) |
| 161 | + { |
| 162 | + if (contentTypes.Length == 0) |
| 163 | + return null; |
| 164 | + |
| 165 | + foreach (var contentType in contentTypes) |
| 166 | + { |
| 167 | + if (IsJsonMime(contentType)) |
| 168 | + return contentType; |
| 169 | + } |
| 170 | + |
| 171 | + return contentTypes[0]; // use the first content type specified in 'consumes' |
| 172 | + } |
| 173 | + |
| 174 | + /// <summary> |
| 175 | + /// Select the Accept header's value from the given accepts array: |
| 176 | + /// if JSON exists in the given array, use it; |
| 177 | + /// otherwise use all of them (joining into a string) |
| 178 | + /// </summary> |
| 179 | + /// <param name="accepts">The accepts array to select from.</param> |
| 180 | + /// <returns>The Accept header to use.</returns> |
| 181 | + public static String SelectHeaderAccept(String[] accepts) |
| 182 | + { |
| 183 | + if (accepts.Length == 0) |
| 184 | + return null; |
| 185 | + |
| 186 | + if (accepts.Contains("application/json", StringComparer.OrdinalIgnoreCase)) |
| 187 | + return "application/json"; |
| 188 | + |
| 189 | + return String.Join(",", accepts); |
| 190 | + } |
| 191 | + |
| 192 | + /// <summary> |
| 193 | + /// Provides a case-insensitive check that a provided content type is a known JSON-like content type. |
| 194 | + /// </summary> |
| 195 | + public static readonly Regex JsonRegex = new Regex("(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$"); |
| 196 | + |
| 197 | + /// <summary> |
| 198 | + /// Check if the given MIME is a JSON MIME. |
| 199 | + /// JSON MIME examples: |
| 200 | + /// application/json |
| 201 | + /// application/json; charset=UTF8 |
| 202 | + /// APPLICATION/JSON |
| 203 | + /// application/vnd.company+json |
| 204 | + /// </summary> |
| 205 | + /// <param name="mime">MIME</param> |
| 206 | + /// <returns>Returns True if MIME type is json.</returns> |
| 207 | + public static bool IsJsonMime(String mime) |
| 208 | + { |
| 209 | + if (String.IsNullOrWhiteSpace(mime)) return false; |
| 210 | + |
| 211 | + return JsonRegex.IsMatch(mime) || mime.Equals("application/json-patch+json"); |
| 212 | + } |
| 213 | + } |
| 214 | +} |
0 commit comments