From 93264b6b3aec6b41bf4a9a78bff3f892f700673e Mon Sep 17 00:00:00 2001 From: ahongbynder Date: Fri, 10 Jan 2025 08:09:43 -0800 Subject: [PATCH 1/2] API-2194 add client credentials grant type --- .../com/bynder/sdk/model/oauth/GrantType.java | 2 +- .../bynder/sdk/query/oauth/TokenQuery.java | 4 ++-- .../sdk/service/oauth/OAuthService.java | 7 +++++++ .../sdk/service/oauth/OAuthServiceImpl.java | 21 +++++++++++++++++++ .../service/oauth/OAuthServiceImplTest.java | 8 +++++++ 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/bynder/sdk/model/oauth/GrantType.java b/src/main/java/com/bynder/sdk/model/oauth/GrantType.java index 4c49eff3..f0b9e2d5 100644 --- a/src/main/java/com/bynder/sdk/model/oauth/GrantType.java +++ b/src/main/java/com/bynder/sdk/model/oauth/GrantType.java @@ -11,7 +11,7 @@ */ public enum GrantType { - AUTHORIZATION_CODE("authorization_code"), REFRESH_TOKEN("refresh_token"); + AUTHORIZATION_CODE("authorization_code"), REFRESH_TOKEN("refresh_token"), CLIENT_CREDENTIALS("client_credentials"); private final String name; diff --git a/src/main/java/com/bynder/sdk/query/oauth/TokenQuery.java b/src/main/java/com/bynder/sdk/query/oauth/TokenQuery.java index 58d7be01..d0b36246 100644 --- a/src/main/java/com/bynder/sdk/query/oauth/TokenQuery.java +++ b/src/main/java/com/bynder/sdk/query/oauth/TokenQuery.java @@ -34,8 +34,8 @@ public class TokenQuery { @ApiField(name = "redirect_uri") private URI redirectUri; /** - * The authorization grant type. Possible values: {@link GrantType#AUTHORIZATION_CODE} and - * {@link GrantType#REFRESH_TOKEN}. + * The authorization grant type. Possible values: {@link GrantType#AUTHORIZATION_CODE} + * ,{@link GrantType#REFRESH_TOKEN} and {@link GrantType#CLIENT_CREDENTIALS}. */ @ApiField(name = "grant_type") private GrantType grantType; diff --git a/src/main/java/com/bynder/sdk/service/oauth/OAuthService.java b/src/main/java/com/bynder/sdk/service/oauth/OAuthService.java index 897c3134..945ae774 100644 --- a/src/main/java/com/bynder/sdk/service/oauth/OAuthService.java +++ b/src/main/java/com/bynder/sdk/service/oauth/OAuthService.java @@ -49,6 +49,13 @@ URL getAuthorizationUrl(final String state, final List scopes) */ Observable getAccessToken(final String code, final List scopes); + /** + * Gets an access token using the client credentials authorization grant. + * @param scopes + * @return {@link Observable} with {@link Token} information. + */ + Observable getAccessTokenClientCredentials(final List scopes); + /** * Gets a new access token using the refresh token. * diff --git a/src/main/java/com/bynder/sdk/service/oauth/OAuthServiceImpl.java b/src/main/java/com/bynder/sdk/service/oauth/OAuthServiceImpl.java index 40788db2..7d876a3e 100644 --- a/src/main/java/com/bynder/sdk/service/oauth/OAuthServiceImpl.java +++ b/src/main/java/com/bynder/sdk/service/oauth/OAuthServiceImpl.java @@ -98,6 +98,27 @@ public Observable getAccessToken(final String code, final List sc }); } + /** + * Check {@link OAuthService} for more information. + */ + @Override + public Observable getAccessTokenClientCredentials(final List scopes) { + // use grant type client credentials + TokenQuery tokenQuery = new TokenQuery(configuration.getOAuthSettings().getClientId(), + configuration.getOAuthSettings().getClientSecret(), null, + GrantType.CLIENT_CREDENTIALS, String.join(" ", scopes), null); + + Map params = queryDecoder.decode(tokenQuery); + Observable> accessTokenObservable = oauthClient.getAccessToken(params); + + return accessTokenObservable.map(response -> { + Token token = response.body(); + token.setAccessTokenExpiration(); + configuration.getOAuthSettings().setToken(token); + return token; + }); + } + /** * Check {@link OAuthService} for more information. */ diff --git a/src/test/java/com/bynder/sdk/service/oauth/OAuthServiceImplTest.java b/src/test/java/com/bynder/sdk/service/oauth/OAuthServiceImplTest.java index ef4f09b8..ad60faaf 100644 --- a/src/test/java/com/bynder/sdk/service/oauth/OAuthServiceImplTest.java +++ b/src/test/java/com/bynder/sdk/service/oauth/OAuthServiceImplTest.java @@ -95,6 +95,14 @@ public void getAccessToken() { verify(queryDecoder, times(1)).decode(any()); } + @Test + public void getAccessTokenClientCredentials() { + oAuthService.getAccessTokenClientCredentials(EXPECTED_SCOPES); + + verify(oauthClient, times(1)).getAccessToken(anyMap()); + verify(queryDecoder, times(1)).decode(any()); + } + @Test public void getRefreshToken() { oAuthService.refreshAccessToken(); From a702b6e4ea50ad2b61d9602a4c45ccc5cb5a2923 Mon Sep 17 00:00:00 2001 From: ahongbynder Date: Fri, 10 Jan 2025 08:52:31 -0800 Subject: [PATCH 2/2] API-2194 add client credentials sample --- .../sample/OAuthClientCredentialsSample.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/main/java/com/bynder/sdk/sample/OAuthClientCredentialsSample.java diff --git a/src/main/java/com/bynder/sdk/sample/OAuthClientCredentialsSample.java b/src/main/java/com/bynder/sdk/sample/OAuthClientCredentialsSample.java new file mode 100644 index 00000000..9491738a --- /dev/null +++ b/src/main/java/com/bynder/sdk/sample/OAuthClientCredentialsSample.java @@ -0,0 +1,74 @@ +package com.bynder.sdk.sample; + +import com.bynder.sdk.configuration.Configuration; +import com.bynder.sdk.configuration.HttpConnectionSettings; +import com.bynder.sdk.configuration.OAuthSettings; +import com.bynder.sdk.model.Brand; +import com.bynder.sdk.model.Media; +import com.bynder.sdk.model.MediaType; +import com.bynder.sdk.query.MediaQuery; +import com.bynder.sdk.query.OrderBy; +import com.bynder.sdk.service.BynderClient; +import com.bynder.sdk.service.asset.AssetService; +import com.bynder.sdk.service.oauth.OAuthService; +import com.bynder.sdk.util.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +public class OAuthClientCredentialsSample { + private static final Logger LOG = LoggerFactory.getLogger(MediaSample.class); + + public static void main(final String[] args) throws IOException, URISyntaxException { + /** + * Loads app.properties file under src/main/resources + */ + Properties appProperties = Utils.loadConfig("app"); + + // Initialize BynderClient with OAuth + OAuthSettings oAuthSettings = new OAuthSettings(appProperties.getProperty("CLIENT_ID"), appProperties.getProperty("CLIENT_SECRET"), null); + BynderClient client = BynderClient.Builder.create( + new Configuration.Builder(new URL(appProperties.getProperty("BASE_URL"))) + .setOAuthSettings(oAuthSettings) + .setHttpConnectionSettings(new HttpConnectionSettings()).build()); + List scopes = Arrays.asList("offline", "asset:read", "asset:write", "asset.usage:read", + "asset.usage:write", "collection:read", "collection:write", "meta.assetbank:read", + "meta.assetbank:write", "meta.workflow:read"); + + // Initialize OAuthService + OAuthService oauthService = client.getOAuthService(); + + // use client credentials + oauthService.getAccessTokenClientCredentials(scopes).blockingSingle(); + + // Initialize asset service + AssetService assetService = client.getAssetService(); + + // Call the API to request for brands + List brands = assetService.getBrands().blockingSingle().body(); + if (brands != null && !brands.isEmpty()) { + for (Brand brand : brands) { + LOG.info("Brand ID: " + brand.getId()); + LOG.info("Brand Name: " + brand.getName()); + LOG.info("Brand Description: " + brand.getDescription()); + } + } + + // Call the API to request for media assets + MediaQuery mediaQuery = new MediaQuery().setType(MediaType.IMAGE).setOrderBy(OrderBy.NAME_DESC).setLimit(10).setPage(1); + List mediaList = assetService.getMediaList(mediaQuery).blockingSingle().body(); + if (mediaList != null && !mediaList.isEmpty()) { + for (Media media : mediaList) { + LOG.info("Media ID: " + media.getId()); + LOG.info("Media Name: " + media.getName()); + } + } + + System.exit(0); + } +}