public void Throws_On_OAuth_Code_Used()
        {
            string rawBody  = "{\"error\":\"invalid_request\",\"error_description\":\"The authorization code was not found or was already used\"}";
            var    response = new HttpResponseMessage()
            {
                StatusCode   = HttpStatusCode.NotAcceptable,
                ReasonPhrase = "Not Acceptable"
            };
            ShopifyException ex = null;

            try
            {
                ShopifyService.CheckResponseExceptions(response, rawBody);
            }
            catch (ShopifyException e)
            {
                ex = e;
            }

            Assert.NotNull(ex);
            Assert.Contains("authorization code was not found or was already used", ex.Message);
            Assert.NotNull(ex.RawBody);
            Assert.Equal(1, ex.Errors.Count);
            Assert.Equal("invalid_request", ex.Errors.First().Key);
            Assert.Equal(1, ex.Errors.First().Value.Count());
        }
        /// <summary>
        /// Authorizes an application installation, generating an access token for the given shop.
        /// </summary>
        /// <param name="code">The authorization code generated by Shopify, which should be a parameter named 'code' on the request querystring.</param>
        /// <param name="myShopifyUrl">The store's *.myshopify.com URL, which should be a paramter named 'shop' on the request querystring.</param>
        /// <param name="shopifyApiKey">Your app's public API key.</param>
        /// <param name="shopifySecretKey">Your app's secret key.</param>
        /// <returns>The authorization result.</returns>
        public static async Task <AuthorizationResult> AuthorizeWithResult(string code, string myShopifyUrl, string shopifyApiKey, string shopifySecretKey)
        {
            var ub = new UriBuilder(ShopifyService.BuildShopUri(myShopifyUrl, false))
            {
                Path = "admin/oauth/access_token"
            };
            var content = new JsonContent(new
            {
                client_id     = shopifyApiKey,
                client_secret = shopifySecretKey,
                code,
            });

            using (var client = new HttpClient())
                using (var msg = new CloneableRequestMessage(ub.Uri, HttpMethod.Post, content))
                {
                    var request       = client.SendAsync(msg);
                    var response      = await request;
                    var rawDataString = await response.Content.ReadAsStringAsync();

                    ShopifyService.CheckResponseExceptions(response, rawDataString);

                    var json = JToken.Parse(rawDataString);
                    return(new AuthorizationResult(json.Value <string>("access_token"), json.Value <string>("scope").Split(',')));
                }
        }
        /// <summary>
        /// Builds an authorization URL for Shopify OAuth integration.
        /// </summary>
        /// <param name="scopes">An array of Shopify permission strings, e.g. 'read_orders' or 'write_script_tags'. These are the permissions that your app needs to run.</param>
        /// <param name="myShopifyUrl">The shop's *.myshopify.com URL.</param>
        /// <param name="shopifyApiKey">Your app's public API key.</param>
        /// <param name="redirectUrl">URL to redirect the user to after integration.</param>
        /// <param name="state">An optional, random string value provided by your application which is unique for each authorization request. During the OAuth callback phase, your application should check that this value matches the one you provided to this method.</param>
        /// <param name="grants">Requested grant types, which will change the type of access token granted upon OAuth completion. Only known grant type is "per-user", which will give an access token restricted to the permissions of the user accepting OAuth integration and will expire when that user logs out. Leave the grants array empty or null to receive a full access token that doesn't expire.</param>
        /// <returns>The authorization url.</returns>
        public static Uri BuildAuthorizationUrl(IEnumerable <string> scopes, string myShopifyUrl, string shopifyApiKey, string redirectUrl, string state = null, IEnumerable <string> grants = null)
        {
            //Prepare a uri builder for the shop URL
            var builder = new UriBuilder(ShopifyService.BuildShopUri(myShopifyUrl, false));

            //Build the querystring
            var qs = new List <KeyValuePair <string, string> >()
            {
                new KeyValuePair <string, string>("client_id", shopifyApiKey),
                new KeyValuePair <string, string>("scope", string.Join(",", scopes)),
                new KeyValuePair <string, string>("redirect_uri", redirectUrl),
            };

            if (string.IsNullOrEmpty(state) == false)
            {
                qs.Add(new KeyValuePair <string, string>("state", state));
            }

            if (grants != null && grants.Count() > 0)
            {
                foreach (var grant in grants)
                {
                    qs.Add(new KeyValuePair <string, string>("grant_options[]", grant));
                }
            }

            builder.Path  = "admin/oauth/authorize";
            builder.Query = string.Join("&", qs.Select(s => $"{s.Key}={s.Value}"));

            return(builder.Uri);
        }
Esempio n. 4
0
        public void Throws_On_OAuth_Code_Used()
        {
            var rawBody = "{\"error\":\"invalid_request\",\"error_description\":\"The authorization code was not found or was already used\"}";
            var res     = new HttpResponseMessage()
            {
                StatusCode   = HttpStatusCode.NotAcceptable,
                ReasonPhrase = "Not Acceptable",
                Content      = new StringContent(rawBody)
            };

            res.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

            ShopifyException ex = null;

            try
            {
                ShopifyService.CheckResponseExceptions(res, rawBody);
            }
            catch (ShopifyException e)
            {
                ex = e;
            }

            Assert.NotNull(ex);
            Assert.NotNull(ex.RawBody);
            Assert.Single(ex.Errors);
            Assert.Equal("(406 Not Acceptable) invalid_request: The authorization code was not found or was already used", ex.Message);
            Assert.Equal("invalid_request: The authorization code was not found or was already used", ex.Errors.First());
        }
Esempio n. 5
0
        public void Returns_Message_About_The_StatusCode()
        {
            var res = new HttpResponseMessage()
            {
                StatusCode   = System.Net.HttpStatusCode.InternalServerError,
                ReasonPhrase = "Internal Server Error",
                Content      = new StringContent("{}")
            };

            res.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

            ShopifyException ex = null;

            try
            {
                ShopifyService.CheckResponseExceptions(res, "{}");
            }
            catch (ShopifyException e)
            {
                ex = e;
            }

            Assert.NotNull(ex);
            Assert.Equal(ex.HttpStatusCode, System.Net.HttpStatusCode.InternalServerError);
            Assert.Contains("Response did not indicate success. Status: 500", ex.Message);
        }
        public IHttpActionResult DeleteWebhook(string id, [FromUri] string token, [FromUri] string shopname)
        {
            var service  = new ShopifyService();
            var webhooks = service.DeleteEntity("webhooks", token, shopname, id);

            return(Ok(webhooks));
        }
        /// <summary>
        /// A convenience function that tries to ensure that a given URL is a valid Shopify domain. It does this by making a HEAD request to the given domain, and returns true if the response contains an X-ShopId header.
        ///
        /// **Warning**: a domain could fake the response header, which would cause this method to return true.
        ///
        /// **Warning**: this method of validation is not officially supported by Shopify and could break at any time.
        /// </summary>
        /// <param name="url">The URL of the shop to check.</param>
        /// <returns>A boolean indicating whether the URL is valid.</returns>
        public static async Task <bool> IsValidShopDomainAsync(string url)
        {
            var uri = ShopifyService.BuildShopUri(url, false);

            using (var handler = new HttpClientHandler
            {
                AllowAutoRedirect = false
            })
                using (var client = new HttpClient(handler))
                    using (var msg = new HttpRequestMessage(HttpMethod.Head, uri))
                    {
                        var version = (typeof(AuthorizationService)).GetTypeInfo().Assembly.GetName().Version;
                        msg.Headers.Add("User-Agent", $"ShopifySharp v{version} (https://github.com/nozzlegear/shopifysharp)");

                        try
                        {
                            var response = await client.SendAsync(msg);

                            return(response.Headers.Any(h => h.Key.Equals("X-ShopId", StringComparison.OrdinalIgnoreCase)));
                        }
                        catch (HttpRequestException)
                        {
                            return(false);
                        }
                    }
        }
Esempio n. 8
0
        public static async Task <Order> GetShopifyOrder(IConfiguration appConfig, string orderName)
        {
            // get shopify configuration parameters
            string shopifyDomain      = appConfig["ShopifyDomain"];
            string shopifyAPIPassword = appConfig["ShopifyAPIPassword"];

            string url = String.Format("https://{0}/admin/orders.json?name={1}&status=any", shopifyDomain, orderName);

            using (var client = new HttpClient())
            {
                var msg = new HttpRequestMessage(method: HttpMethod.Get, requestUri: url);
                msg.Headers.Add("X-Shopify-Access-Token", shopifyAPIPassword);
                msg.Headers.Add("Accept", "application/json");

                // request message is now ready to be sent via HttpClient
                HttpResponseMessage response = client.SendAsync(msg).Result;

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

                ShopifyService.CheckResponseExceptions(response, rawResult);

                var serializer = new JsonSerializer {
                    DateParseHandling = DateParseHandling.DateTimeOffset
                };
                var reader = new JsonTextReader(new StringReader(rawResult));
                var data   = serializer.Deserialize <JObject>(reader).SelectToken("orders");
                var result = data.ToObject <List <Order> >();

                return(result.FirstOrDefault());
            }
        }
        public IHttpActionResult GetCollection(string id, [FromUri] string token, [FromUri] string shopname,
                                               [FromUri] string[] fields, [FromUri] int top = 0)
        {
            var service    = new ShopifyService();
            var collection = service.GetEntity("collections", id, token, shopname, fields, top);

            return(Ok(collection));
        }
Esempio n. 10
0
        public IHttpActionResult GetProduct(string id, [FromUri] string token, [FromUri] string shopname,
                                            [FromUri] string[] fields, [FromUri] int top = 0)
        {
            var service = new ShopifyService();
            var product = service.GetEntity("products", id, token, shopname, fields, top);

            return(Ok(product));
        }
Esempio n. 11
0
        public IHttpActionResult GetCollections([FromUri] string token, [FromUri] string shopname,
                                                [FromUri] string[] fields, [FromUri] int top = 0)
        {
            var service     = new ShopifyService();
            var collections = service.GetEntities("custom_collections", token, shopname, fields, top, null);

            return(Ok(collections));
        }
Esempio n. 12
0
        public IHttpActionResult GetProducts([FromUri] string token, [FromUri] string shopname,
                                             [FromUri] string[] fields, [FromUri] int top = 0)
        {
            var service  = new ShopifyService();
            var products = service.GetEntities("products", token, shopname, fields, top, null);

            return(Ok(products));
        }
Esempio n. 13
0
        public IHttpActionResult GetAccessToken([FromUri] string code, [FromUri] string shop)
        {
            var shopName = shop.Replace(".myshopify.com", "");
            var service  = new ShopifyService();
            var token    = service.GetAccessToken(code, shopName);

            return(Ok(token)); // Returns 401 if our App is'nt installed or the Token is invalid
        }
Esempio n. 14
0
        public IHttpActionResult GetFilters([FromUri] string token, [FromUri] string shopname, [FromUri] string[] fields,
                                            [FromUri] int top = 0)
        {
            var service = new ShopifyService();
            var filters = service.GetEntities("customer_saved_searches", token, shopname, fields, top, null);

            return(Ok(filters));
        }
Esempio n. 15
0
        public IHttpActionResult CreateWebhook([FromBody] JObject webhook, [FromUri] string token,
                                               [FromUri] string shopname)
        {
            var service  = new ShopifyService();
            var webhooks = service.CreateEntity("webhooks", token, shopname, webhook);

            return(Ok(webhooks));
        }
Esempio n. 16
0
        public IHttpActionResult GetWebhooks([FromUri] string token, [FromUri] string shopname,
                                             [FromUri] string[] fields, [FromUri] int top = 0)
        {
            var service  = new ShopifyService();
            var webhooks = service.GetEntities("webhooks", token, shopname, fields, top, null);

            return(Ok(webhooks));
        }
Esempio n. 17
0
 public void Returns_False_For_Invalid_Json()
 {
     Assert.False(ShopifyService.TryParseErrorJson("", out _));
     Assert.False(ShopifyService.TryParseErrorJson("text here", out _));
     Assert.False(ShopifyService.TryParseErrorJson("[]", out _));
     Assert.False(ShopifyService.TryParseErrorJson("[1,2,3]", out _));
     Assert.False(ShopifyService.TryParseErrorJson("true", out _));
     Assert.False(ShopifyService.TryParseErrorJson("false", out _));
 }
        static void Main(string[] args)
        {
            ShopifyService.SetGlobalExecutionPolicy(new SmartRetryExecutionPolicy());

            Authenticate();
            ImportProducts();

            Console.ReadKey();
        }
        public async Task <ActionResult <PagedResults <CustomerDTO> > > Get([FromQuery] PaginationDTO pagination)
        {
            var customers = await _customerRepo.GetAll(pagination.Page, pagination.RecordsPerPage);

            ShopifyService shopify = new ShopifyService();
            var            result  = (shopify.QueryAPI(ShopifyQueryStrings.GetShop));

            Console.WriteLine(result);
            return(customers);
        }
 public DropshippingController(DropshippingService dropship, ISearchService search, ShopifyService shopify,
                               OAuthService oauthdb, DropshipItemsPostgres dbItems, DropshipAccountsPostgres dbAccounts, IRavenClient raven)
 {
     this.dropship   = dropship;
     this.raven      = raven;
     this.shopify    = shopify;
     this.oauthdb    = oauthdb;
     this.dbItems    = dbItems;
     this.dbAccounts = dbAccounts;
     this.search     = search;
 }
Esempio n. 21
0
 public DropshippingService(ShopifyService shopify, ISearchService search, OAuthPostgres dbOauth,
                            OAuthService oauthdb, DropshipItemsPostgres dbItems, DropshipAccountsPostgres dbAccounts, IApplicationCache cache)
 {
     this.shopify    = shopify;
     this.search     = search;
     this.dbItems    = dbItems;
     this.dbAccounts = dbAccounts;
     this.cache      = cache;
     this.dbOAuth    = dbOauth;
     this.oauthdb    = oauthdb;
 }
Esempio n. 22
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddControllers();

            ConfigureOptions(services);
            ConfigureAppServices(services);
            ConfigureBackgroundServices(services);
            ConfigureInfrastructure(services);
            ShopifyService.SetGlobalExecutionPolicy(new SmartRetryExecutionPolicy());
        }
Esempio n. 23
0
 static void Main(string[] args)
 {
     try
     {
         ShopifyService shopServ = new ShopifyService();
         shopServ.InsertarEntradas();
     }
     catch (Exception ex)
     {
         Console.WriteLine(ex.Message);
     }
 }
Esempio n. 24
0
        public void Returns_False_For_Json_That_Does_Not_Match_Expected_Formats()
        {
            var json = "{\"error_foo\":\"bar\"}";

            Assert.False(ShopifyService.TryParseErrorJson(json, out _));

            json = "{\"error_foo\":\"bar\",\"error_description\":\"baz\"}";

            Assert.False(ShopifyService.TryParseErrorJson(json, out _));

            json = "{\"errors_foo\":\"bar\"}";

            Assert.False(ShopifyService.TryParseErrorJson(json, out _));
        }
Esempio n. 25
0
        public void Parses_Errors_Of_Type_Three_With_Multiple_Messages()
        {
            var json = "{\"errors\":{\"order\":[\"foo error message\",\"bar error message\"]}}";

            if (ShopifyService.TryParseErrorJson(json, out var errors))
            {
                Assert.Equal(2, errors.Count());
                Assert.Equal("order: foo error message", errors.First());
                Assert.Equal("order: bar error message", errors.Last());
            }
            else
            {
                CustomAssert.Fail("TryParseErrorJson failed to parse and returned false.");
            }
        }
Esempio n. 26
0
        public async Task Allows_Setting_Global_HttpClientFactory()
        {
            var factory = new FakeHttpClientFactory();

            ShopifyService.SetGlobalHttpClientFactory(factory);

            var shopService  = new ShopService(Utils.MyShopifyUrl, Utils.AccessToken);
            var orderService = new OrderService(Utils.MyShopifyUrl, Utils.AccessToken);
            var policy       = new LeakyBucketExecutionPolicy();
            var orderFilter  = new OrderListFilter
            {
                Limit = 1
            };

            shopService.SetExecutionPolicy(policy);
            orderService.SetExecutionPolicy(policy);

            var ex1 = await Assert.ThrowsAsync <Exception>(() => shopService.GetAsync());

            var ex2 = await Assert.ThrowsAsync <Exception>(() => orderService.ListAsync(orderFilter));

            Assert.Equal("This is an exception thrown by the FakeHttpClient", ex1.Message);
            Assert.Equal("This is an exception thrown by the FakeHttpClient", ex2.Message);

            // Removing the factory should only remove it for future instances
            ShopifyService.SetGlobalHttpClientFactory(null);

            ex1 = await Assert.ThrowsAsync <Exception>(() => shopService.GetAsync());

            ex2 = await Assert.ThrowsAsync <Exception>(() => orderService.ListAsync(orderFilter));

            Assert.Equal("This is an exception thrown by the FakeHttpClient", ex1.Message);
            Assert.Equal("This is an exception thrown by the FakeHttpClient", ex2.Message);

            // Instantiating the services again should now use the default HttpClientFactory
            shopService  = new ShopService(Utils.MyShopifyUrl, Utils.AccessToken);
            orderService = new OrderService(Utils.MyShopifyUrl, Utils.AccessToken);

            shopService.SetExecutionPolicy(policy);
            orderService.SetExecutionPolicy(policy);

            var shop = await shopService.GetAsync();

            var orders = await orderService.ListAsync(orderFilter);

            Assert.NotNull(shop);
            Assert.NotNull(orders);
        }
Esempio n. 27
0
        public void Parses_Errors_Of_Type_Three()
        {
            var json = "{\"errors\":{\"order\":[\"foo error message\"]}}";

            if (ShopifyService.TryParseErrorJson(json, out var errors))
            {
                Assert.Single(errors);

                var error = errors.First();

                Assert.Equal("order: foo error message", error);
            }
            else
            {
                CustomAssert.Fail("TryParseErrorJson failed to parse and returned false.");
            }
        }
Esempio n. 28
0
        public void Parses_Errors_Of_Type_Five()
        {
            var json = "{\"error\":\"location_id must be specified when creating fulfillments.\"}";

            if (ShopifyService.TryParseErrorJson(json, out var errors))
            {
                Assert.Single(errors);

                var error = errors.First();

                Assert.Equal("location_id must be specified when creating fulfillments.", error);
            }
            else
            {
                CustomAssert.Fail("TryParseErrorJson failed to parse and returned false.");
            }
        }
Esempio n. 29
0
        public async Task Throws_On_Error_Object()
        {
            HttpResponseMessage response;
            string           rawBody;
            ShopifyException ex = null;

            using (var client = new HttpClient())
            {
                while (ex == null)
                {
                    // This request will return a response which looks like { errors: { "order" : "some error message" } }
                    using (var msg = PrepareRequest(HttpMethod.Post, "orders.json", new JsonContent(new { })))
                    {
                        var req = client.SendAsync(msg);
                        response = await req;
                        rawBody  = await response.Content.ReadAsStringAsync();
                    }

                    try
                    {
                        ShopifyService.CheckResponseExceptions(response, rawBody);
                    }
                    catch (ShopifyRateLimitException)
                    {
                        // Ignore this exception and retry the request.
                        // RateLimitExceptions may happen when all Exception tests are running and
                        // execution policies are retrying.
                    }
                    catch (ShopifyException e)
                    {
                        ex = e;
                    }
                }
            }

            Assert.NotNull(ex);
            Assert.NotEmpty(ex.Errors);
            Assert.Equal("(400 Bad Request) order: Required parameter missing or invalid", ex.Message);

            var error = ex.Errors.First();

            Assert.Equal("order: Required parameter missing or invalid", error);
        }
Esempio n. 30
0
        public void Returns_Message_Saying_Json_Could_Not_Be_Parsed()
        {
            var json            = "{}";
            var res             = BadResponse(HttpStatusCode.InternalServerError, json);
            ShopifyException ex = null;

            try
            {
                ShopifyService.CheckResponseExceptions(res, json);
            }
            catch (ShopifyException e)
            {
                ex = e;
            }

            Assert.NotNull(ex);
            Assert.Equal(HttpStatusCode.InternalServerError, ex.HttpStatusCode);
            Assert.Contains("(500 Internal Server Error) Shopify returned 500 Internal Server Error, but ShopifySharp was unable to parse the response JSON.", ex.Message);
        }