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); } }
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); } }
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; } }
/// <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) }; } }