From c53bf3c8d17fb95e1067a83ee0b6e3b9517a51f0 Mon Sep 17 00:00:00 2001 From: Tareq Abuzuhri <tareq.abuzuhri@gmail.com> Date: Tue, 24 Oct 2023 09:06:35 +0200 Subject: [PATCH 1/8] add number to JE_VOEC = 9 --- Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Orders/OrderItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Orders/OrderItem.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Orders/OrderItem.cs index 4ce30a3b..d1f1dab8 100644 --- a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Orders/OrderItem.cs +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Orders/OrderItem.cs @@ -85,7 +85,7 @@ public enum DeemedResellerCategoryEnum /// Enum JE_VOEC for value: JE_VOEC /// </summary> [EnumMember(Value = "JE_VOEC")] - JE_VOEC + JE_VOEC = 9 } /// <summary> From 0f44bc73df85fcb0238ddd5db0ba088bec2f3240 Mon Sep 17 00:00:00 2001 From: Tareq Abuzuhri <tareq.abuzuhri@gmail.com> Date: Tue, 24 Oct 2023 11:09:55 +0200 Subject: [PATCH 2/8] Remove AWS authorization --- Source/FikaAmazonAPI.SampleCode/Program.cs | 10 +- Source/FikaAmazonAPI/AmazonConnection.cs | 13 +- .../Token/AWSAuthenticationTokenData.cs | 5 +- .../Runtime/AWSAuthenticationCredentials.cs | 20 -- .../AmazonSpApiSDK/Runtime/AWSSigV4Signer.cs | 82 ------ .../AmazonSpApiSDK/Runtime/AWSSignerHelper.cs | 256 ------------------ .../Runtime/LWAAuthorizationSigner.cs | 34 --- Source/FikaAmazonAPI/FikaAmazonAPI.csproj | 3 - .../FikaAmazonAPI/Services/RequestService.cs | 8 +- .../FikaAmazonAPI/Services/TokenGeneration.cs | 82 +++--- 10 files changed, 58 insertions(+), 455 deletions(-) delete mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/AWSAuthenticationCredentials.cs delete mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/AWSSigV4Signer.cs delete mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/AWSSignerHelper.cs delete mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/LWAAuthorizationSigner.cs diff --git a/Source/FikaAmazonAPI.SampleCode/Program.cs b/Source/FikaAmazonAPI.SampleCode/Program.cs index ddbb1b95..9da07c2c 100644 --- a/Source/FikaAmazonAPI.SampleCode/Program.cs +++ b/Source/FikaAmazonAPI.SampleCode/Program.cs @@ -17,9 +17,9 @@ static async Task Main(string[] args) AmazonConnection amazonConnection = new AmazonConnection(new AmazonCredential() { - AccessKey = config.GetSection("FikaAmazonAPI:AccessKey").Value, - SecretKey = config.GetSection("FikaAmazonAPI:SecretKey").Value, - RoleArn = config.GetSection("FikaAmazonAPI:RoleArn").Value, + //AccessKey = config.GetSection("FikaAmazonAPI:AccessKey").Value, + //SecretKey = config.GetSection("FikaAmazonAPI:SecretKey").Value, + //RoleArn = config.GetSection("FikaAmazonAPI:RoleArn").Value, ClientId = config.GetSection("FikaAmazonAPI:ClientId").Value, ClientSecret = config.GetSection("FikaAmazonAPI:ClientSecret").Value, RefreshToken = config.GetSection("FikaAmazonAPI:RefreshToken").Value, @@ -29,8 +29,8 @@ static async Task Main(string[] args) }); - //FeedsSample feedsSample = new FeedsSample(amazonConnection); - //feedsSample.SubmitFeedPRICING(69.3F, "8809606851663"); + FeedsSample feedsSample = new FeedsSample(amazonConnection); + feedsSample.SubmitFeedPRICING(69.3F, "8809606851663"); var feeds = amazonConnection.Feed.GetFeeds(new Parameter.Feed.ParameterGetFeed() { diff --git a/Source/FikaAmazonAPI/AmazonConnection.cs b/Source/FikaAmazonAPI/AmazonConnection.cs index 4b49aace..84071504 100644 --- a/Source/FikaAmazonAPI/AmazonConnection.cs +++ b/Source/FikaAmazonAPI/AmazonConnection.cs @@ -149,12 +149,13 @@ private void ValidateCredentials(AmazonCredential Credentials) { if (Credentials == null) throw new AmazonUnauthorizedException($"Error, you cannot make calls to Amazon without credentials!"); - else if (string.IsNullOrEmpty(Credentials.AccessKey)) - throw new AmazonInvalidInputException($"InvalidInput, AccessKey cannot be empty!"); - else if (string.IsNullOrEmpty(Credentials.SecretKey)) - throw new AmazonInvalidInputException($"InvalidInput, SecretKey cannot be empty!"); - else if (string.IsNullOrEmpty(Credentials.RoleArn)) - throw new AmazonInvalidInputException($"InvalidInput, RoleArn cannot be empty!"); + //Remove AWS authorization + //else if (string.IsNullOrEmpty(Credentials.AccessKey)) + // throw new AmazonInvalidInputException($"InvalidInput, AccessKey cannot be empty!"); + //else if (string.IsNullOrEmpty(Credentials.SecretKey)) + // throw new AmazonInvalidInputException($"InvalidInput, SecretKey cannot be empty!"); + //else if (string.IsNullOrEmpty(Credentials.RoleArn)) + // throw new AmazonInvalidInputException($"InvalidInput, RoleArn cannot be empty!"); else if (string.IsNullOrEmpty(Credentials.ClientId)) throw new AmazonInvalidInputException($"InvalidInput, ClientId cannot be empty!"); else if (string.IsNullOrEmpty(Credentials.ClientSecret)) diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Token/AWSAuthenticationTokenData.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Token/AWSAuthenticationTokenData.cs index f5a40f8c..ca512a16 100644 --- a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Token/AWSAuthenticationTokenData.cs +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Token/AWSAuthenticationTokenData.cs @@ -1,11 +1,10 @@ -using FikaAmazonAPI.AmazonSpApiSDK.Runtime; -using System; +using System; namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Token { public class AWSAuthenticationTokenData { - public AWSAuthenticationCredentials AWSAuthenticationCredential { get; set; } + //public AWSAuthenticationCredentials AWSAuthenticationCredential { get; set; } public string SessionToken { get; set; } public DateTime Expiration { get; set; } diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/AWSAuthenticationCredentials.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/AWSAuthenticationCredentials.cs deleted file mode 100644 index 8ecfba39..00000000 --- a/Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/AWSAuthenticationCredentials.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace FikaAmazonAPI.AmazonSpApiSDK.Runtime -{ - public class AWSAuthenticationCredentials - { - /** - * AWS IAM User Access Key Id - */ - public string AccessKeyId { get; set; } - - /** - * AWS IAM User Secret Key - */ - public string SecretKey { get; set; } - - /** - * AWS Region - */ - public string Region { get; set; } - } -} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/AWSSigV4Signer.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/AWSSigV4Signer.cs deleted file mode 100644 index b8273f99..00000000 --- a/Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/AWSSigV4Signer.cs +++ /dev/null @@ -1,82 +0,0 @@ -using RestSharp; -using System; -using System.Text; - -namespace FikaAmazonAPI.AmazonSpApiSDK.Runtime -{ - public class AWSSigV4Signer - - { - public virtual AWSSignerHelper AwsSignerHelper { get; set; } - private AWSAuthenticationCredentials awsCredentials; - - /// <summary> - /// Constructor for AWSSigV4Signer - /// </summary> - /// <param name="awsAuthenticationCredentials">AWS Developer Account Credentials</param> - public AWSSigV4Signer(AWSAuthenticationCredentials awsAuthenticationCredentials) - { - awsCredentials = awsAuthenticationCredentials; - AwsSignerHelper = new AWSSignerHelper(); - } - - /// <summary> - /// Signs a Request with AWS Signature Version 4 - /// </summary> - /// <param name="request">RestRequest which needs to be signed</param> - /// <param name="host">Request endpoint</param> - /// <returns>RestRequest with AWS Signature</returns> - public RestRequest Sign(RestRequest request, string host) - { - DateTime signingDate = AwsSignerHelper.InitializeHeaders(request, host); - string signedHeaders = AwsSignerHelper.ExtractSignedHeaders(request); - - string hashedCanonicalRequest = CreateCanonicalRequest(request, signedHeaders); - - string stringToSign = AwsSignerHelper.BuildStringToSign(signingDate, - hashedCanonicalRequest, - awsCredentials.Region); - - string signature = AwsSignerHelper.CalculateSignature(stringToSign, - signingDate, - awsCredentials.SecretKey, - awsCredentials.Region); - - AwsSignerHelper.AddSignature(request, - awsCredentials.AccessKeyId, - signedHeaders, - signature, - awsCredentials.Region, - signingDate); - - return request; - } - - private string CreateCanonicalRequest(RestRequest restRequest, string signedHeaders) - { - var canonicalizedRequest = new StringBuilder(); - //Request Method - canonicalizedRequest.AppendFormat("{0}\n", restRequest.Method.ToString().ToUpperInvariant()); - - //CanonicalURI - canonicalizedRequest.AppendFormat("{0}\n", AwsSignerHelper.ExtractCanonicalURIParameters(restRequest.Resource)); - - //CanonicalQueryString - canonicalizedRequest.AppendFormat("{0}\n", AwsSignerHelper.ExtractCanonicalQueryString(restRequest)); - - //CanonicalHeaders - canonicalizedRequest.AppendFormat("{0}\n", AwsSignerHelper.ExtractCanonicalHeaders(restRequest)); - - //SignedHeaders - canonicalizedRequest.AppendFormat("{0}\n", signedHeaders); - - // Hash(digest) the payload in the body - canonicalizedRequest.AppendFormat(AwsSignerHelper.HashRequestBody(restRequest)); - - string canonicalRequest = canonicalizedRequest.ToString(); - - //Create a digest(hash) of the canonical request - return Utils.ToHex(Utils.Hash(canonicalRequest)); - } - } -} \ No newline at end of file diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/AWSSignerHelper.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/AWSSignerHelper.cs deleted file mode 100644 index 126c521b..00000000 --- a/Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/AWSSignerHelper.cs +++ /dev/null @@ -1,256 +0,0 @@ -using RestSharp; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; - -namespace FikaAmazonAPI.AmazonSpApiSDK.Runtime -{ - public class AWSSignerHelper - { - public const string ISO8601BasicDateTimeFormat = "yyyyMMddTHHmmssZ"; - public const string ISO8601BasicDateFormat = "yyyyMMdd"; - - public const string XAmzDateHeaderName = "X-Amz-Date"; - public const string AuthorizationHeaderName = "Authorization"; - public const string CredentialSubHeaderName = "Credential"; - public const string SignatureSubHeaderName = "Signature"; - public const string SignedHeadersSubHeaderName = "SignedHeaders"; - public const string HostHeaderName = "host"; - - public const string Scheme = "AWS4"; - public const string Algorithm = "HMAC-SHA256"; - public const string TerminationString = "aws4_request"; - public const string ServiceName = "execute-api"; - public const string Slash = "/"; - - private readonly static Regex CompressWhitespaceRegex = new Regex("\\s+"); - - public virtual IDateHelper DateHelper { get; set; } - - public AWSSignerHelper() - { - DateHelper = new SigningDateHelper(); - } - - /// <summary> - /// Returns URI encoded version of absolute path - /// </summary> - /// <param name="resource">Resource path(absolute path) from the request</param> - /// <returns>URI encoded version of absolute path</returns> - public virtual string ExtractCanonicalURIParameters(string resource) - { - string canonicalUri = string.Empty; - - if (string.IsNullOrEmpty(resource)) - { - canonicalUri = Slash; - } - else - { - if (!resource.StartsWith(Slash)) - { - canonicalUri = Slash; - } - //Split path at / into segments - IEnumerable<string> encodedSegments = resource.Split(new char[] { '/' }, StringSplitOptions.None); - - // Encode twice - //use Utils.UrlDecode before Encode twice - encodedSegments = encodedSegments.Select(segment => Utils.UrlEncode(Utils.UrlDecode(segment))); - encodedSegments = encodedSegments.Select(segment => Utils.UrlEncode(segment)); - - canonicalUri += string.Join(Slash, encodedSegments.ToArray()); - } - - return canonicalUri; - } - - /// <summary> - /// Returns query parameters in canonical order with URL encoding - /// </summary> - /// <param name="request">RestRequest</param> - /// <returns>Query parameters in canonical order with URL encoding</returns> - public virtual string ExtractCanonicalQueryString(RestRequest request) - { - IDictionary<string, string> queryParameters = request.Parameters - .Where(parameter => ParameterType.QueryString.Equals(parameter.Type)) - .ToDictionary(header => header.Name.Trim().ToString(), header => header.Value.ToString()); - - SortedDictionary<string, string> sortedqueryParameters = new SortedDictionary<string, string>(queryParameters); - - StringBuilder canonicalQueryString = new StringBuilder(); - foreach (var key in sortedqueryParameters.Keys) - { - if (canonicalQueryString.Length > 0) - { - canonicalQueryString.Append("&"); - } - canonicalQueryString.AppendFormat("{0}={1}", - Utils.UrlEncode(key), - Utils.UrlEncode(sortedqueryParameters[key])); - } - - return canonicalQueryString.ToString(); - } - - /// <summary> - /// Returns Http headers in canonical order with all header names to lowercase - /// </summary> - /// <param name="request">RestRequest</param> - /// <returns>Returns Http headers in canonical order</returns> - public virtual string ExtractCanonicalHeaders(RestRequest request) - { - IDictionary<string, string> headers = request.Parameters - .Where(parameter => ParameterType.HttpHeader.Equals(parameter.Type)) - .ToDictionary(header => header.Name.Trim().ToLowerInvariant(), header => header.Value.ToString()); - - SortedDictionary<string, string> sortedHeaders = new SortedDictionary<string, string>(headers); - - StringBuilder headerString = new StringBuilder(); - - foreach (string headerName in sortedHeaders.Keys) - { - headerString.AppendFormat("{0}:{1}\n", - headerName.ToLower(), - CompressWhitespaceRegex.Replace(sortedHeaders[headerName].Trim(), " ")); - } - - return headerString.ToString(); - } - - /// <summary> - /// Returns list(as string) of Http headers in canonical order - /// </summary> - /// <param name="request">RestRequest</param> - /// <returns>List of Http headers in canonical order</returns> - public virtual string ExtractSignedHeaders(RestRequest request) - { - List<string> rawHeaders = request.Parameters.Where(parameter => ParameterType.HttpHeader.Equals(parameter.Type)) - .Select(header => header.Name.Trim().ToLowerInvariant()) - .ToList(); - rawHeaders.Sort(StringComparer.OrdinalIgnoreCase); - - return string.Join(";", rawHeaders); - } - - /// <summary> - /// Returns hexadecimal hashed value(using SHA256) of payload in the body of request - /// </summary> - /// <param name="request">RestRequest</param> - /// <returns>Hexadecimal hashed value of payload in the body of request</returns> - public virtual string HashRequestBody(RestRequest request) - { - RestSharp.Parameter body = request.Parameters.FirstOrDefault(parameter => ParameterType.RequestBody.Equals(parameter.Type)); - string value = body != null ? body.Value.ToString() : string.Empty; - return Utils.ToHex(Utils.Hash(value)); - } - - /// <summary> - /// Builds the string for signing using signing date, hashed canonical request and region - /// </summary> - /// <param name="signingDate">Signing Date</param> - /// <param name="hashedCanonicalRequest">Hashed Canonical Request</param> - /// <param name="region">Region</param> - /// <returns>String to be used for signing</returns> - public virtual string BuildStringToSign(DateTime signingDate, string hashedCanonicalRequest, string region) - { - string scope = BuildScope(signingDate, region); - string stringToSign = string.Format(CultureInfo.InvariantCulture, "{0}-{1}\n{2}\n{3}\n{4}", - Scheme, - Algorithm, - signingDate.ToString(ISO8601BasicDateTimeFormat, CultureInfo.InvariantCulture), - scope, - hashedCanonicalRequest); - - return stringToSign; - } - - /// <summary> - /// Sets AWS4 mandated 'x-amz-date' header, returning the date/time that will - /// be used throughout the signing process. - /// </summary> - /// <param name="restRequest">RestRequest</param> - /// <param name="host">Request endpoint</param> - /// <returns>Date and time used for x-amz-date, in UTC</returns> - public virtual DateTime InitializeHeaders(RestRequest restRequest, string host) - { - lock (restRequest) - { - restRequest.Parameters.RemoveParameter(XAmzDateHeaderName); - restRequest.Parameters.RemoveParameter(HostHeaderName); - DateTime signingDate = DateHelper.GetUtcNow(); - - restRequest.AddOrUpdateHeader(XAmzDateHeaderName, signingDate.ToString(ISO8601BasicDateTimeFormat, CultureInfo.InvariantCulture)); - restRequest.AddOrUpdateHeader(HostHeaderName, host); - - return signingDate; - } - } - - /// <summary> - /// Calculates AWS4 signature for the string, prepared for signing - /// </summary> - /// <param name="stringToSign">String to be signed</param> - /// <param name="signingDate">Signing Date</param> - /// <param name="secretKey">Secret Key</param> - /// <param name="region">Region</param> - /// <returns>AWS4 Signature</returns> - public virtual string CalculateSignature(string stringToSign, - DateTime signingDate, - string secretKey, - string region) - { - string date = signingDate.ToString(ISO8601BasicDateFormat, CultureInfo.InvariantCulture); - byte[] kSecret = Encoding.UTF8.GetBytes(Scheme + secretKey); - byte[] kDate = Utils.GetKeyedHash(kSecret, date); - byte[] kRegion = Utils.GetKeyedHash(kDate, region); - byte[] kService = Utils.GetKeyedHash(kRegion, ServiceName); - byte[] kSigning = Utils.GetKeyedHash(kService, TerminationString); - - // Calculate the signature - return Utils.ToHex(Utils.GetKeyedHash(kSigning, stringToSign)); - } - - /// <summary> - /// Add a signature to a request in the form of an 'Authorization' header - /// </summary> - /// <param name="restRequest">Request to be signed</param> - /// <param name="accessKeyId">Access Key Id</param> - /// <param name="signedHeaders">Signed Headers</param> - /// <param name="signature">The signature to add</param> - /// <param name="region">AWS region for the request</param> - /// <param name="signingDate">Signature date</param> - public virtual void AddSignature(RestRequest restRequest, - string accessKeyId, - string signedHeaders, - string signature, - string region, - DateTime signingDate) - { - lock (restRequest) - { - string scope = BuildScope(signingDate, region); - StringBuilder authorizationHeaderValueBuilder = new StringBuilder(); - authorizationHeaderValueBuilder.AppendFormat("{0}-{1}", Scheme, Algorithm); - authorizationHeaderValueBuilder.AppendFormat(" {0}={1}/{2},", CredentialSubHeaderName, accessKeyId, scope); - authorizationHeaderValueBuilder.AppendFormat(" {0}={1},", SignedHeadersSubHeaderName, signedHeaders); - authorizationHeaderValueBuilder.AppendFormat(" {0}={1}", SignatureSubHeaderName, signature); - - restRequest.AddOrUpdateHeader(AuthorizationHeaderName, authorizationHeaderValueBuilder.ToString()); - } - - } - - private static string BuildScope(DateTime signingDate, string region) - { - return string.Format("{0}/{1}/{2}/{3}", - signingDate.ToString(ISO8601BasicDateFormat, CultureInfo.InvariantCulture), - region, - ServiceName, - TerminationString); - } - } -} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/LWAAuthorizationSigner.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/LWAAuthorizationSigner.cs deleted file mode 100644 index de834144..00000000 --- a/Source/FikaAmazonAPI/AmazonSpApiSDK/Runtime/LWAAuthorizationSigner.cs +++ /dev/null @@ -1,34 +0,0 @@ -using RestSharp; - -namespace AmazonSpApiSDK.Runtime -{ - public class LWAAuthorizationSigner - { - public const string AccessTokenHeaderName = "x-amz-access-token"; - - public LWAClient LWAClient { get; set; } - - /// <summary> - /// Constructor for LWAAuthorizationSigner - /// </summary> - /// <param name="lwaAuthorizationCredentials">LWA Authorization Credentials for token exchange</param> - public LWAAuthorizationSigner(LWAAuthorizationCredentials lwaAuthorizationCredentials) - { - LWAClient = new LWAClient(lwaAuthorizationCredentials); - } - - /// <summary> - /// Signs a request with LWA Access Token - /// </summary> - /// <param name="restRequest">Request to sign</param> - /// <returns>restRequest with LWA signature</returns> - public IRestRequest Sign(IRestRequest restRequest) - { - string accessToken = LWAClient.GetAccessToken(); - - restRequest.AddHeader(AccessTokenHeaderName, accessToken); - - return restRequest; - } - } -} diff --git a/Source/FikaAmazonAPI/FikaAmazonAPI.csproj b/Source/FikaAmazonAPI/FikaAmazonAPI.csproj index 015b333a..67689621 100644 --- a/Source/FikaAmazonAPI/FikaAmazonAPI.csproj +++ b/Source/FikaAmazonAPI/FikaAmazonAPI.csproj @@ -30,9 +30,6 @@ <EmbeddedResource Remove="ConstructFeed\xsd\**" /> <None Remove="ConstructFeed\xsd\**" /> </ItemGroup> - <ItemGroup> - <Compile Remove="AmazonSpApiSDK\Runtime\LWAAuthorizationSigner.cs" /> - </ItemGroup> <ItemGroup> <PackageReference Include="AWSSDK.SecurityToken" Version="3.7.100.52" /> diff --git a/Source/FikaAmazonAPI/Services/RequestService.cs b/Source/FikaAmazonAPI/Services/RequestService.cs index a6c383f5..bb2bc50a 100644 --- a/Source/FikaAmazonAPI/Services/RequestService.cs +++ b/Source/FikaAmazonAPI/Services/RequestService.cs @@ -1,7 +1,6 @@ using FikaAmazonAPI.AmazonSpApiSDK.Models.Exceptions; using FikaAmazonAPI.AmazonSpApiSDK.Models.Filters; using FikaAmazonAPI.AmazonSpApiSDK.Models.Token; -using FikaAmazonAPI.AmazonSpApiSDK.Runtime; using FikaAmazonAPI.AmazonSpApiSDK.Services; using FikaAmazonAPI.Search; using FikaAmazonAPI.Utils; @@ -118,7 +117,8 @@ protected void CreateAuthorizedPagedRequest(AmazonFilter filter, string url, Res AddAccessToken(); AddShippingBusinessId(); - Request = await TokenGeneration.SignWithSTSKeysAndSecurityTokenAsync(Request, RequestClient.Options.BaseUrl.Host, AmazonCredential, cancellationToken); + //Remove AWS authorization + //Request = await TokenGeneration.SignWithSTSKeysAndSecurityTokenAsync(Request, RequestClient.Options.BaseUrl.Host, AmazonCredential, cancellationToken); var response = await RequestClient.ExecuteAsync<T>(Request, cancellationToken); LogRequest(Request, response); SaveLastRequestHeader(response.Headers); @@ -181,8 +181,8 @@ private void RestHeader() { lock (Request) { - Request?.Parameters?.RemoveParameter(AWSSignerHelper.XAmzDateHeaderName); - Request?.Parameters?.RemoveParameter(AWSSignerHelper.AuthorizationHeaderName); + //Request?.Parameters?.RemoveParameter(AWSSignerHelper.XAmzDateHeaderName); + //Request?.Parameters?.RemoveParameter(AWSSignerHelper.AuthorizationHeaderName); Request?.Parameters?.RemoveParameter(AccessTokenHeaderName); Request?.Parameters?.RemoveParameter(SecurityTokenHeaderName); Request?.Parameters?.RemoveParameter(ShippingBusinessIdHeaderName); diff --git a/Source/FikaAmazonAPI/Services/TokenGeneration.cs b/Source/FikaAmazonAPI/Services/TokenGeneration.cs index 4acc902c..32a6aede 100644 --- a/Source/FikaAmazonAPI/Services/TokenGeneration.cs +++ b/Source/FikaAmazonAPI/Services/TokenGeneration.cs @@ -1,10 +1,7 @@ -using Amazon.SecurityToken; -using Amazon.SecurityToken.Model; -using FikaAmazonAPI.AmazonSpApiSDK.Models.Token; +using FikaAmazonAPI.AmazonSpApiSDK.Models.Token; using FikaAmazonAPI.AmazonSpApiSDK.Runtime; using FikaAmazonAPI.Utils; using Newtonsoft.Json; -using RestSharp; using System; using System.Collections.Generic; using System.Net.Http; @@ -64,48 +61,49 @@ public static async Task<TokenResponse> GetAccessTokenFromCodeAsync(string Clien return JsonConvert.DeserializeObject<TokenResponse>(data); } - public static async Task<RestRequest> SignWithSTSKeysAndSecurityTokenAsync(RestRequest restRequest, string host, AmazonCredential amazonCredential, CancellationToken cancellationToken = default) - { - var dataToken = amazonCredential.GetAWSAuthenticationTokenData(); - if (dataToken == null) - { - AssumeRoleResponse response1 = null; - using (var STSClient = new AmazonSecurityTokenServiceClient(amazonCredential.AccessKey, amazonCredential.SecretKey)) - { - var req = new AssumeRoleRequest() - { - RoleArn = amazonCredential.RoleArn, - DurationSeconds = 3600, - RoleSessionName = Guid.NewGuid().ToString() - }; + //Remove AWS authorization + //public static async Task<RestRequest> SignWithSTSKeysAndSecurityTokenAsync(RestRequest restRequest, string host, AmazonCredential amazonCredential, CancellationToken cancellationToken = default) + //{ + // var dataToken = amazonCredential.GetAWSAuthenticationTokenData(); + // if (dataToken == null) + // { + // AssumeRoleResponse response1 = null; + // using (var STSClient = new AmazonSecurityTokenServiceClient(amazonCredential.AccessKey, amazonCredential.SecretKey)) + // { + // var req = new AssumeRoleRequest() + // { + // RoleArn = amazonCredential.RoleArn, + // DurationSeconds = 3600, + // RoleSessionName = Guid.NewGuid().ToString() + // }; - response1 = await STSClient.AssumeRoleAsync(req, cancellationToken); - } + // response1 = await STSClient.AssumeRoleAsync(req, cancellationToken); + // } - //auth step 3 - var awsAuthenticationCredentials = new AWSAuthenticationCredentials - { - AccessKeyId = response1.Credentials.AccessKeyId, - SecretKey = response1.Credentials.SecretAccessKey, - Region = amazonCredential.MarketPlace.Region.RegionName - }; + // //auth step 3 + // var awsAuthenticationCredentials = new AWSAuthenticationCredentials + // { + // AccessKeyId = response1.Credentials.AccessKeyId, + // SecretKey = response1.Credentials.SecretAccessKey, + // Region = amazonCredential.MarketPlace.Region.RegionName + // }; - amazonCredential.SetAWSAuthenticationTokenData(new AWSAuthenticationTokenData() - { - AWSAuthenticationCredential = awsAuthenticationCredentials, - SessionToken = response1.Credentials.SessionToken, - Expiration = response1.Credentials.Expiration - }); - dataToken = amazonCredential.GetAWSAuthenticationTokenData(); - } + // amazonCredential.SetAWSAuthenticationTokenData(new AWSAuthenticationTokenData() + // { + // AWSAuthenticationCredential = awsAuthenticationCredentials, + // SessionToken = response1.Credentials.SessionToken, + // Expiration = response1.Credentials.Expiration + // }); + // dataToken = amazonCredential.GetAWSAuthenticationTokenData(); + // } - lock (restRequest) - { - restRequest.AddOrUpdateHeader(RequestService.SecurityTokenHeaderName, dataToken.SessionToken); - } - return new AWSSigV4Signer(dataToken.AWSAuthenticationCredential) - .Sign(restRequest, host); + // lock (restRequest) + // { + // restRequest.AddOrUpdateHeader(RequestService.SecurityTokenHeaderName, dataToken.SessionToken); + // } + // return new AWSSigV4Signer(dataToken.AWSAuthenticationCredential) + // .Sign(restRequest, host); - } + //} } } From b791cadc7fa8494f0ad2e586d809fc14a79e2be5 Mon Sep 17 00:00:00 2001 From: Tareq Abuzuhri <tareq.abuzuhri@gmail.com> Date: Tue, 24 Oct 2023 11:15:29 +0200 Subject: [PATCH 3/8] Update README.md --- README.md | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/README.md b/README.md index a9b576e3..0427527a 100644 --- a/README.md +++ b/README.md @@ -84,10 +84,7 @@ To get all keys needed you need to follow this step [Creating and configuring IA | Name | Description | | --- | --- | -| AccessKey | AWS USER ACCESS KEY | -| SecretKey | AWS USER SECRET KEY | -| RoleArn | AWS IAM Role ARN (needs permission to “Assume Role” STS) | -| Region | Marketplace region [List of Marketplaces](https://developer-docs.amazon.com/sp-api/docs/marketplace-ids)| +| Marketplace | Marketplace region [List of Marketplaces](https://developer-docs.amazon.com/sp-api/docs/marketplace-ids)| | ClientId | Your amazon app id | | ClientSecret | Your amazon app secret | | RefreshToken | Check how to get [RefreshToken](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/en-US/developer-guide/SellingPartnerApiDeveloperGuide.md#Self-authorization) | @@ -105,9 +102,6 @@ You can configure a connection like so please see [Here](https://github.com/abuz ```CSharp AmazonConnection amazonConnection = new AmazonConnection(new AmazonCredential() { - AccessKey = "AKIAXXXXXXXXXXXXXXX", - SecretKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", - RoleArn = "arn:aws:iam::XXXXXXXXXXXXX:role/XXXXXXXXXXXX", ClientId = "amzn1.application-XXX-client.XXXXXXXXXXXXXXXXXXXXXXXXXXXX", ClientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", RefreshToken= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", @@ -118,9 +112,6 @@ or AmazonConnection amazonConnection = new AmazonConnection(new AmazonCredential() { - AccessKey = "AKIAXXXXXXXXXXXXXXX", - SecretKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", - RoleArn = "arn:aws:iam::XXXXXXXXXXXXX:role/XXXXXXXXXXXX", ClientId = "amzn1.application-XXX-client.XXXXXXXXXXXXXXXXXXXXXXXXXXXX", ClientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", RefreshToken= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", @@ -134,9 +125,6 @@ Please see [here](https://github.com/abuzuhri/Amazon-SP-API-CSharp/blob/main/Sou >```csharp >AmazonConnection amazonConnection = new AmazonConnection(new AmazonCredential() >{ -> AccessKey = "AKIAXXXXXXXXXXXXXXX", -> SecretKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", -> RoleArn = "arn:aws:iam::XXXXXXXXXXXXX:role/XXXXXXXXXXXX", > ClientId = "amzn1.application-XXX-client.XXXXXXXXXXXXXXXXXXXXXXXXXXXX", > ClientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", > RefreshToken= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", @@ -216,9 +204,6 @@ var orders = _amazonConnection.Orders.GetOrders(parameterOrderList); ```CSharp AmazonConnection amazonConnection = new AmazonConnection(new AmazonCredential() { - AccessKey = "AKIAXXXXXXXXXXXXXXX", - SecretKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", - RoleArn = "arn:aws:iam::XXXXXXXXXXXXX:role/XXXXXXXXXXXX", ClientId = "amzn1.application-XXX-client.XXXXXXXXXXXXXXXXXXXXXXXXXXXX", ClientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", RefreshToken= "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", From 32c3fe64a4adb5001d2e330faf1853f4d1afd897 Mon Sep 17 00:00:00 2001 From: Tareq Abuzuhri <tareq.abuzuhri@gmail.com> Date: Tue, 24 Oct 2023 11:16:12 +0200 Subject: [PATCH 4/8] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0427527a..87205383 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Install-Package CSharpAmazonSpAPI ## Keys To get all keys needed you need to follow this step [Creating and configuring IAM policies and entities](https://developer-docs.amazon.com/sp-api/docs/creating-and-configuring-iam-policies-and-entities) and then you need to [Registering your Application](https://developer-docs.amazon.com/sp-api/docs/registering-your-application) then [Authorizing Selling Partner API applications ](https://developer-docs.amazon.com/sp-api/docs/authorizing-selling-partner-api-applications#step-1-request-a-login-with-amazon-access-token) -> :warning: **Use role ARN created in step 5 when you register your application**: and dont use IAM user + | Name | Description | | --- | --- | From b23267c96b268838acbbeb60493cf426bd79f7c1 Mon Sep 17 00:00:00 2001 From: Tareq Abuzuhri <tareq.abuzuhri@gmail.com> Date: Tue, 24 Oct 2023 11:20:03 +0200 Subject: [PATCH 5/8] change to v1.7.7 --- Source/FikaAmazonAPI/FikaAmazonAPI.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/FikaAmazonAPI/FikaAmazonAPI.csproj b/Source/FikaAmazonAPI/FikaAmazonAPI.csproj index 67689621..47699c11 100644 --- a/Source/FikaAmazonAPI/FikaAmazonAPI.csproj +++ b/Source/FikaAmazonAPI/FikaAmazonAPI.csproj @@ -7,9 +7,9 @@ <Product>CSharp Amazon Sp API</Product> <GeneratePackageOnBuild>true</GeneratePackageOnBuild> <LangVersion>8.0</LangVersion> - <Version>1.7.5</Version> - <AssemblyVersion>1.7.5</AssemblyVersion> - <FileVersion>1.7.5</FileVersion> + <Version>1.7.7</Version> + <AssemblyVersion>1.7.7</AssemblyVersion> + <FileVersion>1.7.7</FileVersion> <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> <PackageProjectUrl>https://github.com/abuzuhri/Amazon-SP-API-CSharp</PackageProjectUrl> <PackageLicenseExpression>MIT</PackageLicenseExpression> From a0e6794d86db8942bee3c004c8fb8ea5267168aa Mon Sep 17 00:00:00 2001 From: Tareq Abuzuhri <tareq.abuzuhri@gmail.com> Date: Thu, 26 Oct 2023 23:12:04 +0200 Subject: [PATCH 6/8] improve performace for SQS --- .../CustomMessageReceiver.cs | 9 ++---- .../Services/NotificationService.cs | 32 ++++++++++++------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/Source/FikaAmazonAPI.SampleCode/CustomMessageReceiver.cs b/Source/FikaAmazonAPI.SampleCode/CustomMessageReceiver.cs index 5f34c69c..568be1a1 100644 --- a/Source/FikaAmazonAPI.SampleCode/CustomMessageReceiver.cs +++ b/Source/FikaAmazonAPI.SampleCode/CustomMessageReceiver.cs @@ -1,11 +1,5 @@ -using Amazon; -using FikaAmazonAPI.NotificationMessages; +using FikaAmazonAPI.NotificationMessages; using FikaAmazonAPI.Parameter.Notification; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace FikaAmazonAPI.SampleCode { @@ -19,6 +13,7 @@ public void ErrorCatch(Exception ex) public void NewMessageRevicedTriger(NotificationMessageResponce message) { + Console.Write("."); //Your Code here } } diff --git a/Source/FikaAmazonAPI/Services/NotificationService.cs b/Source/FikaAmazonAPI/Services/NotificationService.cs index a71c7f75..8440dcad 100644 --- a/Source/FikaAmazonAPI/Services/NotificationService.cs +++ b/Source/FikaAmazonAPI/Services/NotificationService.cs @@ -140,20 +140,12 @@ public async Task StartReceivingNotificationMessagesAsync(ParameterMessageReceiv { foreach (var msg in Messages) { - try - { - var data = DeserializeNotification(msg); - - messageReceiver.NewMessageRevicedTriger(data); - await DeleteMessageFromQueueAsync(amazonSQSClient, SQS_URL, msg.ReceiptHandle, cancellationToken); - } - catch (Exception ex) - { - messageReceiver.ErrorCatch(ex); - await DeleteMessageFromQueueAsync(amazonSQSClient, SQS_URL, msg.ReceiptHandle, cancellationToken); - } + ProcessAnyOfferChangedMessage(msg, messageReceiver, amazonSQSClient, SQS_URL, cancellationToken).ConfigureAwait(false); } + + if (Messages.Count < 10) + Thread.Sleep(1000 * 5); } } catch (Exception ex) @@ -163,6 +155,22 @@ public async Task StartReceivingNotificationMessagesAsync(ParameterMessageReceiv } } } + + private async Task ProcessAnyOfferChangedMessage(Message msg, IMessageReceiver messageReceiver, AmazonSQSClient amazonSQSClient, string SQS_URL, CancellationToken cancellationToken = default) + { + try + { + var data = DeserializeNotification(msg); + + messageReceiver.NewMessageRevicedTriger(data); + await DeleteMessageFromQueueAsync(amazonSQSClient, SQS_URL, msg.ReceiptHandle, cancellationToken); + } + catch (Exception ex) + { + messageReceiver.ErrorCatch(ex); + await DeleteMessageFromQueueAsync(amazonSQSClient, SQS_URL, msg.ReceiptHandle, cancellationToken); + } + } private async Task DeleteMessageFromQueueAsync(AmazonSQSClient sqsClient, string QueueUrl, string ReceiptHandle, CancellationToken cancellationToken = default) { var deleteMessageRequest = new DeleteMessageRequest() { QueueUrl = QueueUrl, ReceiptHandle = ReceiptHandle }; From fd741bc21f41e121a922291c613651ca864c5379 Mon Sep 17 00:00:00 2001 From: Tareq Abuzuhri <tareq.abuzuhri@gmail.com> Date: Thu, 26 Oct 2023 23:13:11 +0200 Subject: [PATCH 7/8] change to v1.7.8 --- Source/FikaAmazonAPI/FikaAmazonAPI.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/FikaAmazonAPI/FikaAmazonAPI.csproj b/Source/FikaAmazonAPI/FikaAmazonAPI.csproj index 47699c11..c94202a7 100644 --- a/Source/FikaAmazonAPI/FikaAmazonAPI.csproj +++ b/Source/FikaAmazonAPI/FikaAmazonAPI.csproj @@ -7,9 +7,9 @@ <Product>CSharp Amazon Sp API</Product> <GeneratePackageOnBuild>true</GeneratePackageOnBuild> <LangVersion>8.0</LangVersion> - <Version>1.7.7</Version> - <AssemblyVersion>1.7.7</AssemblyVersion> - <FileVersion>1.7.7</FileVersion> + <Version>1.7.8</Version> + <AssemblyVersion>1.7.8</AssemblyVersion> + <FileVersion>1.7.8</FileVersion> <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> <PackageProjectUrl>https://github.com/abuzuhri/Amazon-SP-API-CSharp</PackageProjectUrl> <PackageLicenseExpression>MIT</PackageLicenseExpression> From 7e84b55e38dc8cc800d42f543a1638f9a48d23e9 Mon Sep 17 00:00:00 2001 From: Antoine Caillou <antoine.caillou@lisy.co> Date: Fri, 10 Nov 2023 18:31:43 +0100 Subject: [PATCH 8/8] Added: missing values from `VariantEnum` --- .../CatalogItems/V20220401/ItemImage.cs | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/CatalogItems/V20220401/ItemImage.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/CatalogItems/V20220401/ItemImage.cs index 88759248..69437ba0 100644 --- a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/CatalogItems/V20220401/ItemImage.cs +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/CatalogItems/V20220401/ItemImage.cs @@ -91,7 +91,61 @@ public enum VariantEnum /// Enum SWCH for value: SWCH /// </summary> [EnumMember(Value = "SWCH")] - SWCH = 10 + SWCH = 10, + + /// <summary> + /// Enum PT09 for value: PT09 + /// </summary> + [EnumMember(Value = "PT09")] + PT09 = 11, + + /// <summary> + /// Enum PT10 for value: PT10 + /// </summary> + [EnumMember(Value = "PT10")] + PT10 = 12, + + /// <summary> + /// Enum PT11 for value: PT11 + /// </summary> + [EnumMember(Value = "PT11")] + PT11 = 13, + + /// <summary> + /// Enum PT12 for value: PT12 + /// </summary> + [EnumMember(Value = "PT12")] + PT12 = 14, + + /// <summary> + /// Enum PT13 for value: PT13 + /// </summary> + [EnumMember(Value = "PT13")] + PT13 = 15, + + /// <summary> + /// Enum PT14 for value: PT14 + /// </summary> + [EnumMember(Value = "PT14")] + PT14 = 16, + + /// <summary> + /// Enum PT15 for value: PT15 + /// </summary> + [EnumMember(Value = "PT15")] + PT15 = 17, + + /// <summary> + /// Enum EEGL for value: EEGL + /// </summary> + [EnumMember(Value = "EEGL")] + EEGL = 18, + + /// <summary> + /// Enum EGUS for value: EGUS + /// </summary> + [EnumMember(Value = "EGUS")] + EGUS = 19 } /// <summary>