From fbac650b604fd596e3bbb2400f058acd946992d1 Mon Sep 17 00:00:00 2001 From: Carl-Tucker Date: Fri, 4 Feb 2022 20:25:41 -0700 Subject: [PATCH] Added support for Tokens. Note this will require that we use BP v5.4.2 or later --- .../BlackPearlManagementService.java | 3 + .../blackpearl/management/models/Token.java | 28 +++++++ .../management/models/UserCreds.java | 30 +++++++ .../management/network/RetroFitBuilder.java | 5 +- .../management/network/TokenInterceptor.java | 78 +++++++++++++++++++ 5 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/models/Token.java create mode 100644 bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/models/UserCreds.java create mode 100644 bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/network/TokenInterceptor.java diff --git a/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/BlackPearlManagementService.java b/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/BlackPearlManagementService.java index 090cecd..89f2d98 100644 --- a/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/BlackPearlManagementService.java +++ b/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/BlackPearlManagementService.java @@ -57,6 +57,9 @@ public interface BlackPearlManagementService { @POST("logs") Single createLogSet(@Body final LogCreator logCreator); + @POST("tokens") + Single generateToken(@Body final UserCreds credentials); + @GET("logs/{logSetName}") @Streaming Single getLogSet(@Path("logSetName") final String logSetName); diff --git a/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/models/Token.java b/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/models/Token.java new file mode 100644 index 0000000..6da1200 --- /dev/null +++ b/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/models/Token.java @@ -0,0 +1,28 @@ +/* + * **************************************************************************** + * Copyright 2016 Spectra Logic Corporation. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use + * this file except in compliance with the License. A copy of the License is located at + * http://www.apache.org/licenses/LICENSE-2.0 + * or in the "license" file accompanying this file. + * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * ************************************************************************** + */ +package com.spectralogic.blackpearl.management.models; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Token { + @JsonProperty("token") + private String token; + + public String getToken() { + return token; + } + + public void setToken(final String token) { + this.token = token; + } +} \ No newline at end of file diff --git a/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/models/UserCreds.java b/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/models/UserCreds.java new file mode 100644 index 0000000..d216dc5 --- /dev/null +++ b/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/models/UserCreds.java @@ -0,0 +1,30 @@ +package com.spectralogic.blackpearl.management.models; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class UserCreds { + @JsonProperty("username") + private String username; + + @JsonProperty("password") + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(final String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(final String password) { + this.password = password; + } + + public void setUserAndPass(final String user, final String pass) {this.username = user; this.password = pass;} + +} diff --git a/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/network/RetroFitBuilder.java b/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/network/RetroFitBuilder.java index 8f60586..ca7e02a 100644 --- a/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/network/RetroFitBuilder.java +++ b/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/network/RetroFitBuilder.java @@ -48,15 +48,12 @@ public static Retrofit build(final String url, final String username, final Stri } public static Retrofit build(final String url, final String username, final String password, final boolean apiPrefix) throws KeyManagementException, NoSuchAlgorithmException { - final String authorization = "Basic " + Base64 - .getEncoder() - .encodeToString((username + ":" + password).getBytes(Charset.forName("UTF-8"))); final OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); + httpClient.addInterceptor(new TokenInterceptor(url, username, password)); httpClient.addInterceptor(chain -> { final Request original = chain.request(); final Request request = original.newBuilder() - .header("Authorization", authorization) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .method(original.method(), original.body()) diff --git a/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/network/TokenInterceptor.java b/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/network/TokenInterceptor.java new file mode 100644 index 0000000..ad93167 --- /dev/null +++ b/bp-mgmt-client/src/main/java/com/spectralogic/blackpearl/management/network/TokenInterceptor.java @@ -0,0 +1,78 @@ +/* + * **************************************************************************** + * Copyright 2016 Spectra Logic Corporation. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use + * this file except in compliance with the License. A copy of the License is located at + * http://www.apache.org/licenses/LICENSE-2.0 + * or in the "license" file accompanying this file. + * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * ************************************************************************** + */ + +package com.spectralogic.blackpearl.management.network; + +import com.spectralogic.blackpearl.management.BlackPearlManagementService; +import com.spectralogic.blackpearl.management.models.Token; +import com.spectralogic.blackpearl.management.models.UserCreds; +import io.reactivex.Single; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; + +class TokenInterceptor implements Interceptor { + private final String tokenUrl; + private final String user; + private final String pass; + private final static String API_TOKENS = "/api/tokens"; + + public TokenInterceptor(String url, String username, String password) { + tokenUrl = url; + user = username; + pass = password; + } + + @Override public Response intercept(Chain chain) throws IOException { + final Request original = chain.request(); + + if (original.url().encodedPath().contains(API_TOKENS) && original.method().equals("POST")) { + return chain.proceed(original); + } + try { + final String token = fetchToken(); + final String authorization = "Bearer " + token; + final Request request = original.newBuilder() + .header("Authorization", authorization) + .method(original.method(), original.body()) + .build(); + return chain.proceed(request); + + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException("Failed to Fetch JWT Token", e); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + throw new RuntimeException("Failed to Fetch JWT Token", e); + } catch (KeyManagementException e) { + e.printStackTrace(); + throw new RuntimeException("Failed to Fetch JWT Token", e); + } + } + + private String fetchToken() throws InterruptedException, NoSuchAlgorithmException, KeyManagementException { + final String tokensEndpoint = tokenUrl; + + BlackPearlManagementService managementService = BlackPearlManagementService.getInstance(tokensEndpoint, user, pass); + + UserCreds userCreds = new UserCreds(); + userCreds.setUserAndPass(user, pass); + + final Single token = managementService.generateToken(userCreds); + + return token.map(Token::getToken).blockingGet(); + } +}