Exemple #1
0
        private bool ValidateInstallResponse(OAuthState installState)
        {
            var queryStringBuilder = new QueryStringBuilder {
                StartsWith = null
            };

            queryStringBuilder.Add(AppResources.CodeKeyword, installState.AuthorizationCode);
            queryStringBuilder.Add(AppResources.ShopKeyword, installState.ShopName);
            queryStringBuilder.Add(AppResources.TimestampKeyword, installState.AuthorizationTimestamp);
            var secretKeyBytes       = Encoding.UTF8.GetBytes(this.Configuration.SecretKey);
            var installResponseBytes = Encoding.UTF8.GetBytes(queryStringBuilder.ToString());

            using (var hmacsha256 = new HMACSHA256(secretKeyBytes))
            {
                var generatedInstallResponseHmacHashBytes = hmacsha256.ComputeHash(installResponseBytes);
                var generatedInstallResponseHmacHash      = ByteArrayToHexString(generatedInstallResponseHmacHashBytes);
                return(generatedInstallResponseHmacHash.Equals(installState.HmacHash));
            }
        }
        public async Task <int> CountAsync(string shopUrl, string accessToken, string address = "", WebhookTopic topic = WebhookTopic.None)
        {
            shopUrl.PerCallShopUrlContract();
            accessToken.PerCallAccessTokenContract();

            if (!string.IsNullOrWhiteSpace(address) && !address.IsValidUrlAddress())
            {
                throw new ArgumentException("Address parameter is not a well formed URL");
            }

            var queryStringBuilder = new QueryStringBuilder();

            if (!string.IsNullOrWhiteSpace(address))
            {
                queryStringBuilder.Add("address", address);
            }

            if (WebhookTopic.None != topic)
            {
                queryStringBuilder.Add("topic", topic.Convert());
            }

            using (var httpClient = new HttpClient())
            {
                httpClient.Configure(shopUrl, accessToken);
                var queryStringParameters = queryStringBuilder.ToString();
                var response = await httpClient.GetAsync(string.Format(CultureInfo.InvariantCulture, "{0}{1}", ApiRequestResources.GetWebhooksAllCount, string.IsNullOrWhiteSpace(queryStringParameters) ? string.Empty : queryStringParameters));

                if (!response.IsSuccessStatusCode)
                {
                    return(0);
                }

                var rawResponseContent = await response.Content.ReadAsStringAsync();

                var webhooksCount = JsonConvert.DeserializeObject <WebhooksCountJson>(rawResponseContent);
                return(webhooksCount.Count);
            }
        }
        public async Task<IList<Webhook>> GetAllAsync(
            string shopUrl,
            string accessToken,
            string address = "",
            DateTime createdBefore = default(DateTime),
            DateTime createdAfter = default(DateTime),
            WebhookField fields = WebhookField.None,
            int limit = 50,
            int page = 1,
            int idGreaterThan = 0,
            WebhookTopic topic = WebhookTopic.None,
            DateTime updatedBefore = default(DateTime),
            DateTime updatedAfter = default(DateTime))
        {
            //// Default contracts
            shopUrl.PerCallShopUrlContract();
            accessToken.PerCallAccessTokenContract();

            //// Optional parameter validation
            if (!string.IsNullOrWhiteSpace(address) && !address.IsValidUrlAddress())
            {
                throw new ArgumentException("Address parameter is not a well formed URL");
            }

            if (250 < limit)
            {
                throw new ArgumentException("Limit value cannot be more than 250, default is 50 if not specified");
            }

            if (0 == page)
            {
                throw new ArgumentException("Page value cannot be zero");
            }

            //// Build query string
            var queryStringBuilder = new QueryStringBuilder();
            if (!string.IsNullOrWhiteSpace(address))
            {
                queryStringBuilder.Add("address", address);
            }

            if (default(DateTime) != createdBefore)
            {
                queryStringBuilder.Add("created_at_max", createdBefore.ToString("yyyy-MM-dd HH:mm"));
            }

            if (default(DateTime) != createdAfter)
            {
                queryStringBuilder.Add("created_at_min", createdAfter.ToString("yyyy-MM-dd HH:mm"));
            }

            if (WebhookField.None != fields)
            {
                queryStringBuilder.Add("fields", fields.BuildWebhookFieldFilter());
            }

            if (0 != limit)
            {
                queryStringBuilder.Add("limit", limit.ToString(CultureInfo.InvariantCulture));
            }

            if (0 != page)
            {
                queryStringBuilder.Add("page", page.ToString(CultureInfo.InvariantCulture));
            }

            if (0 != idGreaterThan)
            {
                queryStringBuilder.Add("since_id", idGreaterThan.ToString(CultureInfo.InvariantCulture));
            }

            if (WebhookTopic.None != topic)
            {
                queryStringBuilder.Add("topic", topic.Convert());
            }

            if (default(DateTime) != updatedBefore)
            {
                queryStringBuilder.Add("updated_at_min", updatedBefore.ToString("yyyy-MM-dd HH:mm"));
            }

            if (default(DateTime) != updatedAfter)
            {
                queryStringBuilder.Add("updated_at_max", updatedAfter.ToString("yyyy-MM-dd HH:mm"));
            }

            //// Perform HTTP GET call to API
            using (var httpClient = new HttpClient())
            {
                httpClient.Configure(shopUrl, accessToken);
                var queryStringParameters = queryStringBuilder.ToString();
                var response = await httpClient.GetAsync(string.Format(CultureInfo.InvariantCulture, "{0}{1}", ApiRequestResources.GetWebhooksAll, string.IsNullOrWhiteSpace(queryStringParameters) ? string.Empty : queryStringParameters));
                if (!response.IsSuccessStatusCode)
                {
                    return null;
                }

                var rawResponseContent = await response.Content.ReadAsStringAsync();
                var webhooks = JsonConvert.DeserializeObject<WebhooksJson>(rawResponseContent);
                return webhooks.Hooks;
            }
        }
        public async Task<int> CountAsync(string shopUrl, string accessToken, string address = "", WebhookTopic topic = WebhookTopic.None)
        {
            shopUrl.PerCallShopUrlContract();
            accessToken.PerCallAccessTokenContract();

            if (!string.IsNullOrWhiteSpace(address) && !address.IsValidUrlAddress())
            {
                throw new ArgumentException("Address parameter is not a well formed URL");
            }

            var queryStringBuilder = new QueryStringBuilder();
            if (!string.IsNullOrWhiteSpace(address))
            {
                queryStringBuilder.Add("address", address);
            }

            if (WebhookTopic.None != topic)
            {
                queryStringBuilder.Add("topic", topic.Convert());
            }

            using (var httpClient = new HttpClient())
            {
                httpClient.Configure(shopUrl, accessToken);
                var queryStringParameters = queryStringBuilder.ToString();
                var response = await httpClient.GetAsync(string.Format(CultureInfo.InvariantCulture, "{0}{1}", ApiRequestResources.GetWebhooksAllCount, string.IsNullOrWhiteSpace(queryStringParameters) ? string.Empty : queryStringParameters));
                if (!response.IsSuccessStatusCode)
                {
                    return 0;
                }

                var rawResponseContent = await response.Content.ReadAsStringAsync();
                var webhooksCount = JsonConvert.DeserializeObject<WebhooksCountJson>(rawResponseContent);
                return webhooksCount.Count;
            }
        }
        public async Task<Webhook> GetSingleAsync(string shopUrl, string accessToken, string id, WebhookField fields = WebhookField.None)
        {
            //// Default contracts
            shopUrl.PerCallShopUrlContract();
            accessToken.PerCallAccessTokenContract();

            //// Build query string
            var queryStringBuilder = new QueryStringBuilder();
            if (WebhookField.None != fields)
            {
                queryStringBuilder.Add("fields", fields.BuildWebhookFieldFilter());
            }

            //// Perform HTTP GET call to API
            using (var httpClient = new HttpClient())
            {
                httpClient.Configure(shopUrl, accessToken);
                var queryStringParameters = queryStringBuilder.ToString();
                var response = await httpClient.GetAsync(string.Format(CultureInfo.InvariantCulture, "{0}{1}", string.Format(CultureInfo.InvariantCulture, ApiRequestResources.GetWebhookSingle, id), string.IsNullOrWhiteSpace(queryStringParameters) ? string.Empty : queryStringParameters));
                if (!response.IsSuccessStatusCode)
                {
                    return null;
                }

                var rawResponseContent = await response.Content.ReadAsStringAsync();
                var webhookJson = JsonConvert.DeserializeObject<WebhookJson>(rawResponseContent);
                return webhookJson.Webhook;
            }
        }
Exemple #6
0
        /// <summary>
        /// Performs SHOPIFY OAUTH 2.0 authorization process based on shop access permission accepted.
        /// </summary>
        /// <param name="shopName">Authorization shop name.</param>
        /// <param name="authorizationCode">Intermediate authorization code, required to complete SHOPIFY OAUTH 2.0 authorization.</param>
        /// <param name="hmacHash">HMAC hash value.</param>
        /// <param name="timestamp">Timestamp value returned in the callback query string.</param>
        /// <returns>
        /// Returns authorization state or error details.
        /// <para>The <see cref="OAuthState"/>'s 'IsSuccess' will result in false in case signature validation fails or any other exceptin occurrs.</para>
        /// <para>Error property will be filled with reason for 'IsSuccess' false. Three possible reason strings are:</para>
        /// <para>1. Required parameters in query string missing.</para>
        /// <para>2. HMAC signature validation failed.</para>
        /// <para>3. {Exception Type}: {Exception message} (for any exception).</para>
        /// </returns>
        /// <exception cref="ArgumentNullException">Throws argument null exception if input parameters are null or empty.</exception>
        public OAuthState AuthorizeClient(string shopName, string authorizationCode, string hmacHash, string timestamp)
        {
            if (string.IsNullOrEmpty(shopName))
            {
                throw new ArgumentNullException("shopName");
            }

            if (string.IsNullOrEmpty(authorizationCode))
            {
                throw new ArgumentNullException("authorizationCode");
            }

            if (string.IsNullOrEmpty(hmacHash))
            {
                throw new ArgumentNullException("hmacHash");
            }

            if (string.IsNullOrEmpty(timestamp))
            {
                throw new ArgumentNullException("timestamp");
            }

            var hashValidationResult = this.ValidateInstallResponse(new OAuthState {
                ShopName = shopName, AuthorizationCode = authorizationCode, HmacHash = hmacHash, AuthorizationTimestamp = timestamp
            });

            if (!hashValidationResult)
            {
                return(new OAuthState {
                    IsSuccess = false, Error = "HMAC signature validation failed"
                });
            }

            try
            {
                var accessTokenUrl = string.Format(CultureInfo.InvariantCulture, AppResources.AccessTokenUrl, shopName);
                var queryBuilder   = new QueryStringBuilder {
                    StartsWith = null
                };
                queryBuilder.Add(AppResources.ClientIdKeyword, this.Configuration.ApiKey);
                queryBuilder.Add(AppResources.ClientSecretKeyword, this.Configuration.SecretKey);
                queryBuilder.Add(AppResources.CodeKeyword, authorizationCode);

                var httpWebRequest = (HttpWebRequest)WebRequest.Create(accessTokenUrl);
                httpWebRequest.Method = HttpType.POST.ToString();

                //// Not sure if that would help but I encountered this while fixing another BUG so going to keep it in place.
                ServicePointManager.Expect100Continue = true;
                ServicePointManager.SecurityProtocol  = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
                ServicePointManager.ServerCertificateValidationCallback = delegate { return(true); };

                httpWebRequest.ContentType = AppResources.DefaultHttpClientContentType;
                using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
                {
                    streamWriter.Write(queryBuilder.ToString());
                    streamWriter.Close();
                }

                var httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                var jsonResponse    = string.Empty;
                using (var responseStream = httpWebResponse.GetResponseStream())
                {
                    if (responseStream != null)
                    {
                        using (var streamReader = new StreamReader(responseStream))
                        {
                            jsonResponse = streamReader.ReadToEnd();
                            streamReader.Close();
                        }
                    }
                }

                var oauthResponse = JsonConvert.DeserializeObject <OAuthState>(jsonResponse);
                oauthResponse.ShopName  = shopName;
                oauthResponse.IsSuccess = true;
                return(oauthResponse);
            }
            catch (Exception exception)
            {
                return(new OAuthState {
                    IsSuccess = false, Error = string.Format(CultureInfo.InvariantCulture, "{0}: {1}", exception.GetType().Name, exception.Message)
                });
            }
        }
        public async Task<int> CountAsync(string shopUrl, string accessToken, string source = "")
        {
            shopUrl.PerCallShopUrlContract();
            accessToken.PerCallAccessTokenContract();

            if (!string.IsNullOrWhiteSpace(source) && !source.IsValidUrlAddress())
            {
                throw new ArgumentException("Source parameter is not a well formed URL");
            }

            var queryStringBuilder = new QueryStringBuilder();
            if (!string.IsNullOrWhiteSpace(source))
            {
                queryStringBuilder.Add("src", source);
            }

            using (var httpClient = new HttpClient())
            {
                httpClient.Configure(shopUrl, accessToken);
                var queryStringParameters = queryStringBuilder.ToString();
                var response = await httpClient.GetAsync(string.Format(CultureInfo.InvariantCulture, "{0}{1}", ApiRequestResources.GetScriptTagsAllCount, string.IsNullOrWhiteSpace(queryStringParameters) ? string.Empty : queryStringParameters));
                if (!response.IsSuccessStatusCode)
                {
                    return 0;
                }

                var rawResponseContent = await response.Content.ReadAsStringAsync();
                var scriptTagsCount = JsonConvert.DeserializeObject<ScriptTagsCountJson>(rawResponseContent);
                return scriptTagsCount.Count;
            }
        }
        public async Task<ScriptTag> GetSingleAsync(string shopUrl, string accessToken, string id, ScriptTagField fields = ScriptTagField.None)
        {
            shopUrl.PerCallShopUrlContract();
            accessToken.PerCallAccessTokenContract();

            var queryStringBuilder = new QueryStringBuilder();
            if (ScriptTagField.None != fields)
            {
                queryStringBuilder.Add("fields", fields.BuildScriptTagFieldFilter());
            }

            using (var httpClient = new HttpClient())
            {
                httpClient.Configure(shopUrl, accessToken);
                var queryStringParameters = queryStringBuilder.ToString();
                var response = await httpClient.GetAsync(string.Format(CultureInfo.InvariantCulture, "{0}{1}", string.Format(CultureInfo.InvariantCulture, ApiRequestResources.GetScriptTagSingle, id), string.IsNullOrWhiteSpace(queryStringParameters) ? string.Empty : queryStringParameters));
                if (!response.IsSuccessStatusCode)
                {
                    return null;
                }

                var rawResponseContent = await response.Content.ReadAsStringAsync();
                var scriptTagJson = JsonConvert.DeserializeObject<ScriptTagJson>(rawResponseContent);
                return scriptTagJson.ScriptTag;
            }
        }
        public async Task <IList <Webhook> > GetAllAsync(
            string shopUrl,
            string accessToken,
            string address         = "",
            DateTime createdBefore = default(DateTime),
            DateTime createdAfter  = default(DateTime),
            WebhookField fields    = WebhookField.None,
            int limit              = 50,
            int page               = 1,
            int idGreaterThan      = 0,
            WebhookTopic topic     = WebhookTopic.None,
            DateTime updatedBefore = default(DateTime),
            DateTime updatedAfter  = default(DateTime))
        {
            //// Default contracts
            shopUrl.PerCallShopUrlContract();
            accessToken.PerCallAccessTokenContract();

            //// Optional parameter validation
            if (!string.IsNullOrWhiteSpace(address) && !address.IsValidUrlAddress())
            {
                throw new ArgumentException("Address parameter is not a well formed URL");
            }

            if (250 < limit)
            {
                throw new ArgumentException("Limit value cannot be more than 250, default is 50 if not specified");
            }

            if (0 == page)
            {
                throw new ArgumentException("Page value cannot be zero");
            }

            //// Build query string
            var queryStringBuilder = new QueryStringBuilder();

            if (!string.IsNullOrWhiteSpace(address))
            {
                queryStringBuilder.Add("address", address);
            }

            if (default(DateTime) != createdBefore)
            {
                queryStringBuilder.Add("created_at_max", createdBefore.ToString("yyyy-MM-dd HH:mm"));
            }

            if (default(DateTime) != createdAfter)
            {
                queryStringBuilder.Add("created_at_min", createdAfter.ToString("yyyy-MM-dd HH:mm"));
            }

            if (WebhookField.None != fields)
            {
                queryStringBuilder.Add("fields", fields.BuildWebhookFieldFilter());
            }

            if (0 != limit)
            {
                queryStringBuilder.Add("limit", limit.ToString(CultureInfo.InvariantCulture));
            }

            if (0 != page)
            {
                queryStringBuilder.Add("page", page.ToString(CultureInfo.InvariantCulture));
            }

            if (0 != idGreaterThan)
            {
                queryStringBuilder.Add("since_id", idGreaterThan.ToString(CultureInfo.InvariantCulture));
            }

            if (WebhookTopic.None != topic)
            {
                queryStringBuilder.Add("topic", topic.Convert());
            }

            if (default(DateTime) != updatedBefore)
            {
                queryStringBuilder.Add("updated_at_min", updatedBefore.ToString("yyyy-MM-dd HH:mm"));
            }

            if (default(DateTime) != updatedAfter)
            {
                queryStringBuilder.Add("updated_at_max", updatedAfter.ToString("yyyy-MM-dd HH:mm"));
            }

            //// Perform HTTP GET call to API
            using (var httpClient = new HttpClient())
            {
                httpClient.Configure(shopUrl, accessToken);
                var queryStringParameters = queryStringBuilder.ToString();
                var response = await httpClient.GetAsync(string.Format(CultureInfo.InvariantCulture, "{0}{1}", ApiRequestResources.GetWebhooksAll, string.IsNullOrWhiteSpace(queryStringParameters) ? string.Empty : queryStringParameters));

                if (!response.IsSuccessStatusCode)
                {
                    return(null);
                }

                var rawResponseContent = await response.Content.ReadAsStringAsync();

                var webhooks = JsonConvert.DeserializeObject <WebhooksJson>(rawResponseContent);
                return(webhooks.Hooks);
            }
        }
 private bool ValidateInstallResponse(OAuthState installState)
 {
     var queryStringBuilder = new QueryStringBuilder { StartsWith = null };
     queryStringBuilder.Add(AppResources.CodeKeyword, installState.AuthorizationCode);
     queryStringBuilder.Add(AppResources.ShopKeyword, installState.ShopName);
     queryStringBuilder.Add(AppResources.TimestampKeyword, installState.AuthorizationTimestamp);
     var secretKeyBytes = Encoding.UTF8.GetBytes(this.Configuration.SecretKey);
     var installResponseBytes = Encoding.UTF8.GetBytes(queryStringBuilder.ToString());
     using (var hmacsha256 = new HMACSHA256(secretKeyBytes))
     {
         var generatedInstallResponseHmacHashBytes = hmacsha256.ComputeHash(installResponseBytes);
         var generatedInstallResponseHmacHash = ByteArrayToHexString(generatedInstallResponseHmacHashBytes);
         return generatedInstallResponseHmacHash.Equals(installState.HmacHash);
     }
 }
        /// <summary>
        /// Performs SHOPIFY OAUTH 2.0 authorization process based on shop access permission accepted.
        /// </summary>
        /// <param name="shopName">Authorization shop name.</param>
        /// <param name="authorizationCode">Intermediate authorization code, required to complete SHOPIFY OAUTH 2.0 authorization.</param>
        /// <param name="hmacHash">HMAC hash value.</param>
        /// <param name="timestamp">Timestamp value returned in the callback query string.</param>
        /// <returns>
        /// Returns authorization state or error details.
        /// <para>The <see cref="OAuthState"/>'s 'IsSuccess' will result in false in case signature validation fails or any other exceptin occurrs.</para>
        /// <para>Error property will be filled with reason for 'IsSuccess' false. Three possible reason strings are:</para>
        /// <para>1. Required parameters in query string missing.</para>
        /// <para>2. HMAC signature validation failed.</para>
        /// <para>3. {Exception Type}: {Exception message} (for any exception).</para>
        /// </returns>
        /// <exception cref="ArgumentNullException">Throws argument null exception if input parameters are null or empty.</exception>
        public OAuthState AuthorizeClient(string shopName, string authorizationCode, string hmacHash, string timestamp)
        {
            if (string.IsNullOrEmpty(shopName))
            {
                throw new ArgumentNullException("shopName");
            }

            if (string.IsNullOrEmpty(authorizationCode))
            {
                throw new ArgumentNullException("authorizationCode");
            }

            if (string.IsNullOrEmpty(hmacHash))
            {
                throw new ArgumentNullException("hmacHash");
            }

            if (string.IsNullOrEmpty(timestamp))
            {
                throw new ArgumentNullException("timestamp");
            }

            var hashValidationResult = this.ValidateInstallResponse(new OAuthState { ShopName = shopName, AuthorizationCode = authorizationCode, HmacHash = hmacHash, AuthorizationTimestamp = timestamp });
            if (!hashValidationResult)
            {
                return new OAuthState { IsSuccess = false, Error = "HMAC signature validation failed" };
            }

            try
            {
                var accessTokenUrl = string.Format(CultureInfo.InvariantCulture, AppResources.AccessTokenUrl, shopName);
                var queryBuilder = new QueryStringBuilder { StartsWith = null };
                queryBuilder.Add(AppResources.ClientIdKeyword, this.Configuration.ApiKey);
                queryBuilder.Add(AppResources.ClientSecretKeyword, this.Configuration.SecretKey);
                queryBuilder.Add(AppResources.CodeKeyword, authorizationCode);

                var httpWebRequest = (HttpWebRequest)WebRequest.Create(accessTokenUrl);
                httpWebRequest.Method = HttpType.POST.ToString();

                //// Not sure if that would help but I encountered this while fixing another BUG so going to keep it in place.
                ServicePointManager.Expect100Continue = true;
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
                ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

                httpWebRequest.ContentType = AppResources.DefaultHttpClientContentType;
                using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
                {
                    streamWriter.Write(queryBuilder.ToString());
                    streamWriter.Close();
                }

                var httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                var jsonResponse = string.Empty;
                using (var responseStream = httpWebResponse.GetResponseStream())
                {
                    if (responseStream != null)
                    {
                        using (var streamReader = new StreamReader(responseStream))
                        {
                            jsonResponse = streamReader.ReadToEnd();
                            streamReader.Close();
                        }
                    }
                }

                var oauthResponse = JsonConvert.DeserializeObject<OAuthState>(jsonResponse);
                oauthResponse.ShopName = shopName;
                oauthResponse.IsSuccess = true;
                return oauthResponse;
            }
            catch (Exception exception)
            {
                return new OAuthState { IsSuccess = false, Error = string.Format(CultureInfo.InvariantCulture, "{0}: {1}", exception.GetType().Name, exception.Message) };
            }
        }