/// <summary> /// This method is not for regular use. If you are attempting to use it for any reason consult the project lead /// If you need the context of an authenticated user ensure you're using a valid OrderCloudIntegrationsAuth attribute /// and reference the VerifiedUserContext from the BaseController /// </summary> /// <param name="config"></param> /// <returns></returns> public async Task <VerifiedUserContext> Define(OrderCloudClientConfig config) { var auth = await _oc.AuthenticateAsync(); var user = await _oc.Me.GetAsync(); var jwt = new JwtSecurityToken(auth.AccessToken); var cid = new ClaimsIdentity("OrderCloudIntegrations"); cid.AddClaim(new Claim("accesstoken", auth.AccessToken)); cid.AddClaim(new Claim("clientid", jwt.GetClientID())); cid.AddClaim(new Claim("usrtype", jwt.GetUserType())); cid.AddClaim(new Claim("username", user.Username)); cid.AddClaim(new Claim("userid", user.ID)); cid.AddClaim(new Claim("email", user.Email ?? "")); cid.AddClaim(new Claim("buyer", user.Buyer?.ID ?? "")); cid.AddClaim(new Claim("supplier", user.Supplier?.ID ?? "")); cid.AddClaim(new Claim("seller", user.Seller?.ID ?? "")); cid.AddClaims(user.AvailableRoles.Select(r => new Claim(ClaimTypes.Role, r))); var roles = user.AvailableRoles.Select(r => new Claim(ClaimTypes.Role, r)).ToList(); roles.Add(new Claim(ClaimTypes.Role, "BaseUserRole")); cid.AddClaims(roles); Principal = new ClaimsPrincipal(cid); _token = new JwtSecurityTokenHandler().ReadJwtToken(auth.AccessToken); return(this); }
public async Task <HSSupplier> UpdateSupplier(string supplierID, PartialSupplier supplier, DecodedToken decodedToken) { var me = await _oc.Me.GetAsync(accessToken : decodedToken.AccessToken); Require.That(decodedToken.CommerceRole == CommerceRole.Seller || supplierID == me.Supplier.ID, new ErrorCode("Unauthorized", $"You are not authorized to update supplier {supplierID}", 401)); var currentSupplier = await _oc.Suppliers.GetAsync <HSSupplier>(supplierID); var updatedSupplier = await _oc.Suppliers.PatchAsync <HSSupplier>(supplierID, supplier); // Update supplier products only on a name change if (currentSupplier.Name != supplier.Name || currentSupplier.xp.Currency.ToString() != supplier.xp.Currency.Value) { var productsToUpdate = await _oc.Products.ListAllAsync <HSProduct>( supplierID : supplierID, accessToken : decodedToken.AccessToken ); ApiClient supplierClient = await _apiClientHelper.GetSupplierApiClient(supplierID, decodedToken.AccessToken); if (supplierClient == null) { throw new Exception($"Default supplier client not found. SupplierID: {supplierID}"); } var configToUse = new OrderCloudClientConfig { ApiUrl = decodedToken.ApiUrl, AuthUrl = decodedToken.AuthUrl, ClientId = supplierClient.ID, ClientSecret = supplierClient.ClientSecret, GrantType = GrantType.ClientCredentials, Roles = new[] { ApiRole.SupplierAdmin, ApiRole.ProductAdmin }, }; var ocClient = new OrderCloudClient(configToUse); await ocClient.AuthenticateAsync(); var token = ocClient.TokenResponse.AccessToken; foreach (var product in productsToUpdate) { product.xp.Facets["supplier"] = new List <string>() { supplier.Name }; product.xp.Currency = supplier.xp.Currency; } await Throttler.RunAsync(productsToUpdate, 100, 5, product => ocClient.Products.SaveAsync(product.ID, product, accessToken: token)); } return(updatedSupplier); }
public static async Task RunAction(OrderCloudClientConfig config, Func <OrderCloudClient, Task> action) { // If another client is needed, use this to store it. This ensures only one client is created and reused. storageConnectionByClientID.GetOrAdd(config.ClientId, x => new OrderCloudClient(config)); try { await action(storageConnectionByClientID[config.ClientId]); } catch (Exception ex) { throw new Exception($"Unable to get OC connection for client: {config.ClientId}, {ex.Message}"); } }
public async Task <Product> FilterOptionOverride(string id, string supplierID, IDictionary <string, object> facets, VerifiedUserContext user) { ApiClient supplierClient = await _apiClientHelper.GetSupplierApiClient(supplierID, user.AccessToken); if (supplierClient == null) { throw new Exception($"Default supplier client not found. SupplierID: {supplierID}"); } var configToUse = new OrderCloudClientConfig { ApiUrl = user.TokenApiUrl, AuthUrl = user.TokenAuthUrl, ClientId = supplierClient.ID, ClientSecret = supplierClient.ClientSecret, GrantType = GrantType.ClientCredentials, Roles = new[] { ApiRole.SupplierAdmin, ApiRole.ProductAdmin }, }; var ocClient = new OrderCloudClient(configToUse); await ocClient.AuthenticateAsync(); var token = ocClient.TokenResponse.AccessToken; //Format the facet data to change for request body var facetDataFormatted = new ExpandoObject(); var facetDataFormattedCollection = (ICollection <KeyValuePair <string, object> >)facetDataFormatted; foreach (var kvp in facets) { facetDataFormattedCollection.Add(kvp); } dynamic facetDataFormattedDynamic = facetDataFormatted; //Update the product with a supplier token var updatedProduct = await ocClient.Products.PatchAsync( id, new PartialProduct() { xp = new { Facets = facetDataFormattedDynamic } }, accessToken : token ); return(updatedProduct); }
private async Task <VerifiedUserContext> GetVerifiedUserContext(ApiClient middlewareApiClient) { // some endpoints such as documents and documentschemas require a verified user context for a user in the seller org // however the context that we get when calling this endpoint is for the dev user so we need to create a user context // with the seller user var ocConfig = new OrderCloudClientConfig { ApiUrl = _settings.OrderCloudSettings.ApiUrl, AuthUrl = _settings.OrderCloudSettings.ApiUrl, ClientId = middlewareApiClient.ID, ClientSecret = middlewareApiClient.ClientSecret, GrantType = GrantType.ClientCredentials, Roles = new[] { ApiRole.FullAccess } }; return(await new VerifiedUserContext(_oc).Define(ocConfig)); }
public static IServiceCollection InjectOrderCloud <T>(this IServiceCollection services, OrderCloudClientConfig config) { services.AddSingleton <IOrderCloudClient>(provider => new OrderCloudClient(config)); return(services); }
public async Task <SuperHSProduct> UpdateMonitoredSuperProductNotificationStatus(Document <MonitoredProductFieldModifiedNotification> document, string supplierID, string productID, VerifiedUserContext user) { HSProduct product = null; HSProduct patchedProduct = null; var token = await GetAdminToken(); try { product = await _oc.Products.GetAsync <HSProduct>(productID); } catch (OrderCloudException ex) { //Product was deleted after it was updated. Delete orphaned notification if (ex.HttpStatus == System.Net.HttpStatusCode.NotFound) { await _cms.Documents.Delete(_documentSchemaID, document.ID, token); return(new SuperHSProduct()); } } if (document.Doc.Status == NotificationStatus.ACCEPTED) { var supplierClient = await _apiClientHelper.GetSupplierApiClient(supplierID, user.AccessToken); if (supplierClient == null) { throw new Exception($"Default supplier client not found. SupplierID: {supplierID}, ProductID: {productID}"); } var configToUse = new OrderCloudClientConfig { ApiUrl = user.ApiUrl, AuthUrl = user.AuthUrl, ClientId = supplierClient.ID, ClientSecret = supplierClient.ClientSecret, GrantType = GrantType.ClientCredentials, Roles = new[] { ApiRole.SupplierAdmin, ApiRole.ProductAdmin }, }; try { await ClientHelper.RunAction(configToUse, async x => { patchedProduct = await x.Products.PatchAsync <HSProduct>(productID, new PartialProduct() { Active = true }); } ); } catch (OrderCloudException ex) { if (ex?.Errors?[0]?.Data != null) { throw new Exception($"Unable to re-activate product: {ex?.Errors?[0]?.Message}: {ex?.Errors?[0]?.Data.ToJRaw()}"); } throw new Exception($"Unable to re-activate product: {ex?.Errors?.ToJRaw()}"); } //Delete document after acceptance await _cms.Documents.Delete(_documentSchemaID, document.ID, token); } else { await _cms.Documents.Save(_documentSchemaID, document.ID, document, token); } var superProduct = await _productCommand.Get(productID, token); superProduct.Product = patchedProduct; return(superProduct); }