Skip to content

Commit bbc6850

Browse files
SK-2645: Merge branch 'release/26.1.4' into release/26.1.5
2 parents 76227a5 + ebfe55d commit bbc6850

File tree

10 files changed

+1276
-29
lines changed

10 files changed

+1276
-29
lines changed

src/main/java/com/skyflow/config/Credentials.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ public class Credentials {
99
private String credentialsString;
1010
private String token;
1111
private String apiKey;
12+
private String tokenUri;
1213

1314
public Credentials() {
1415
this.path = null;
1516
this.context = null;
1617
this.credentialsString = null;
18+
this.tokenUri = null;
1719
}
1820

1921
public String getPath() {
@@ -63,4 +65,12 @@ public String getApiKey() {
6365
public void setApiKey(String apiKey) {
6466
this.apiKey = apiKey;
6567
}
68+
69+
public String getTokenUri() {
70+
return tokenUri;
71+
}
72+
73+
public void setTokenUri(String tokenUri) {
74+
this.tokenUri = tokenUri;
75+
}
6676
}

src/main/java/com/skyflow/errors/ErrorMessage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public enum ErrorMessage {
4545
MissingClientId("%s0 Initialization failed. Unable to read client ID in credentials. Verify your client ID."),
4646
MissingKeyId("%s0 Initialization failed. Unable to read key ID in credentials. Verify your key ID."),
4747
MissingTokenUri("%s0 Initialization failed. Unable to read token URI in credentials. Verify your token URI."),
48-
InvalidTokenUri("%s0 Initialization failed. Token URI in not a valid URL in credentials. Verify your token URI."),
48+
InvalidTokenUri("%s0 Initialization failed. Invalid Skyflow credentials. The token URI must be a string and a valid URL."),
4949
JwtInvalidFormat("%s0 Initialization failed. Invalid private key format. Verify your credentials."),
5050
InvalidAlgorithm("%s0 Initialization failed. Invalid algorithm to parse private key. Specify valid algorithm."),
5151
InvalidKeySpec("%s0 Initialization failed. Unable to parse RSA private key. Verify your credentials."),

src/main/java/com/skyflow/serviceaccount/util/BearerToken.java

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,23 @@ public class BearerToken {
3434
private final String ctx;
3535
private final ArrayList<String> roles;
3636
private final String credentialsType;
37+
private final String tokenUri;
3738

3839
private BearerToken(BearerTokenBuilder builder) {
3940
this.credentialsFile = builder.credentialsFile;
4041
this.credentialsString = builder.credentialsString;
4142
this.ctx = builder.ctx;
4243
this.roles = builder.roles;
4344
this.credentialsType = builder.credentialsType;
45+
this.tokenUri = builder.tokenUri;
4446
}
4547

4648
public static BearerTokenBuilder builder() {
4749
return new BearerTokenBuilder();
4850
}
4951

5052
private static V1GetAuthTokenResponse generateBearerTokenFromCredentials(
51-
File credentialsFile, String context, ArrayList<String> roles
53+
File credentialsFile, String context, ArrayList<String> roles, String overrideTokenUri
5254
) throws SkyflowException {
5355
LogUtil.printInfoLog(InfoLogs.GENERATE_BEARER_TOKEN_FROM_CREDENTIALS_TRIGGERED.getLog());
5456
try {
@@ -58,7 +60,7 @@ private static V1GetAuthTokenResponse generateBearerTokenFromCredentials(
5860
}
5961
FileReader reader = new FileReader(String.valueOf(credentialsFile));
6062
JsonObject serviceAccountCredentials = JsonParser.parseReader(reader).getAsJsonObject();
61-
return getBearerTokenFromCredentials(serviceAccountCredentials, context, roles);
63+
return getBearerTokenFromCredentials(serviceAccountCredentials, context, roles, overrideTokenUri);
6264
} catch (JsonSyntaxException e) {
6365
LogUtil.printErrorLog(ErrorLogs.INVALID_CREDENTIALS_FILE_FORMAT.getLog());
6466
throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), Utils.parameterizedString(
@@ -71,7 +73,7 @@ private static V1GetAuthTokenResponse generateBearerTokenFromCredentials(
7173
}
7274

7375
private static V1GetAuthTokenResponse generateBearerTokenFromCredentialString(
74-
String credentials, String context, ArrayList<String> roles
76+
String credentials, String context, ArrayList<String> roles, String overrideTokenUri
7577
) throws SkyflowException {
7678
LogUtil.printInfoLog(InfoLogs.GENERATE_BEARER_TOKEN_FROM_CREDENTIALS_STRING_TRIGGERED.getLog());
7779
try {
@@ -80,7 +82,7 @@ private static V1GetAuthTokenResponse generateBearerTokenFromCredentialString(
8082
throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidCredentials.getMessage());
8183
}
8284
JsonObject serviceAccountCredentials = JsonParser.parseString(credentials).getAsJsonObject();
83-
return getBearerTokenFromCredentials(serviceAccountCredentials, context, roles);
85+
return getBearerTokenFromCredentials(serviceAccountCredentials, context, roles, overrideTokenUri);
8486
} catch (JsonSyntaxException e) {
8587
LogUtil.printErrorLog(ErrorLogs.INVALID_CREDENTIALS_STRING_FORMAT.getLog());
8688
throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(),
@@ -89,7 +91,7 @@ private static V1GetAuthTokenResponse generateBearerTokenFromCredentialString(
8991
}
9092

9193
private static V1GetAuthTokenResponse getBearerTokenFromCredentials(
92-
JsonObject credentials, String context, ArrayList<String> roles
94+
JsonObject credentials, String context, ArrayList<String> roles, String overrideTokenUri
9395
) throws SkyflowException {
9496
try {
9597
JsonElement privateKey = credentials.get(Constants.CredentialFields.PRIVATE_KEY);
@@ -111,17 +113,19 @@ private static V1GetAuthTokenResponse getBearerTokenFromCredentials(
111113
}
112114

113115
JsonElement tokenURI = credentials.get(Constants.CredentialFields.TOKEN_URI);
114-
if (tokenURI == null) {
116+
if (tokenURI == null && overrideTokenUri == null) {
115117
LogUtil.printErrorLog(ErrorLogs.TOKEN_URI_IS_REQUIRED.getLog());
116118
throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.MissingTokenUri.getMessage());
117119
}
118120

121+
String finalTokenUri = (overrideTokenUri != null) ? overrideTokenUri : tokenURI.getAsString();
122+
119123
PrivateKey pvtKey = Utils.getPrivateKeyFromPem(privateKey.getAsString());
120124
String signedUserJWT = getSignedToken(
121-
clientID.getAsString(), keyID.getAsString(), tokenURI.getAsString(), pvtKey, context
125+
clientID.getAsString(), keyID.getAsString(), finalTokenUri, pvtKey, context
122126
);
123127

124-
String basePath = Utils.getBaseURL(tokenURI.getAsString());
128+
String basePath = Utils.getBaseURL(finalTokenUri);
125129
API_CLIENT_BUILDER.url(basePath);
126130
ApiClient apiClient = API_CLIENT_BUILDER.token(Constants.ApiToken.TOKEN).build();
127131
AuthenticationClient authenticationApi = apiClient.authentication();
@@ -174,10 +178,10 @@ public synchronized String getBearerToken() throws SkyflowException {
174178
V1GetAuthTokenResponse response;
175179
String accessToken = null;
176180
if (this.credentialsFile != null && Objects.equals(this.credentialsType, Constants.CredentialTypeValues.FILE)) {
177-
response = generateBearerTokenFromCredentials(this.credentialsFile, this.ctx, this.roles);
181+
response = generateBearerTokenFromCredentials(this.credentialsFile, this.ctx, this.roles, this.tokenUri);
178182
accessToken = response.getAccessToken().get();
179183
} else if (this.credentialsString != null && Objects.equals(this.credentialsType, Constants.CredentialTypeValues.STRING)) {
180-
response = generateBearerTokenFromCredentialString(this.credentialsString, this.ctx, this.roles);
184+
response = generateBearerTokenFromCredentialString(this.credentialsString, this.ctx, this.roles, this.tokenUri);
181185
accessToken = response.getAccessToken().get();
182186
}
183187
LogUtil.printInfoLog(InfoLogs.GET_BEARER_TOKEN_SUCCESS.getLog());
@@ -191,6 +195,7 @@ public static class BearerTokenBuilder {
191195
private String ctx;
192196
private ArrayList<String> roles;
193197
private String credentialsType;
198+
private String tokenUri;
194199

195200
private BearerTokenBuilder() {
196201
}
@@ -221,6 +226,19 @@ public BearerTokenBuilder setRoles(ArrayList<String> roles) {
221226
return this;
222227
}
223228

229+
public BearerTokenBuilder setTokenUri(String tokenUri) throws SkyflowException {
230+
if (tokenUri != null && !tokenUri.isEmpty()) {
231+
try {
232+
new java.net.URL(tokenUri);
233+
this.tokenUri = tokenUri;
234+
} catch (MalformedURLException e) {
235+
LogUtil.printErrorLog(ErrorLogs.INVALID_TOKEN_URI.getLog());
236+
throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidTokenUri.getMessage());
237+
}
238+
}
239+
return this;
240+
}
241+
224242
public BearerToken build() {
225243
return new BearerToken(this);
226244
}

src/main/java/com/skyflow/serviceaccount/util/SignedDataTokens.java

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import java.io.File;
1818
import java.io.FileNotFoundException;
1919
import java.io.FileReader;
20+
import java.net.MalformedURLException;
2021
import java.security.PrivateKey;
2122
import java.util.ArrayList;
2223
import java.util.Date;
@@ -30,6 +31,7 @@ public class SignedDataTokens {
3031
private final String ctx;
3132
private final ArrayList<String> dataTokens;
3233
private final Integer timeToLive;
34+
private final String tokenUri;
3335

3436
private SignedDataTokens(SignedDataTokensBuilder builder) {
3537
this.credentialsFile = builder.credentialsFile;
@@ -38,14 +40,15 @@ private SignedDataTokens(SignedDataTokensBuilder builder) {
3840
this.ctx = builder.ctx;
3941
this.dataTokens = builder.dataTokens;
4042
this.timeToLive = builder.timeToLive;
43+
this.tokenUri = builder.tokenUri;
4144
}
4245

4346
public static SignedDataTokensBuilder builder() {
4447
return new SignedDataTokensBuilder();
4548
}
4649

4750
private static List<SignedDataTokenResponse> generateSignedTokenFromCredentialsFile(
48-
File credentialsFile, ArrayList<String> dataTokens, Integer timeToLive, String context
51+
File credentialsFile, ArrayList<String> dataTokens, Integer timeToLive, String context, String overrideTokenUri
4952
) throws SkyflowException {
5053
LogUtil.printInfoLog(InfoLogs.GENERATE_SIGNED_TOKENS_FROM_CREDENTIALS_FILE_TRIGGERED.getLog());
5154
List<SignedDataTokenResponse> responseToken;
@@ -56,7 +59,7 @@ private static List<SignedDataTokenResponse> generateSignedTokenFromCredentialsF
5659
}
5760
FileReader reader = new FileReader(String.valueOf(credentialsFile));
5861
JsonObject serviceAccountCredentials = JsonParser.parseReader(reader).getAsJsonObject();
59-
responseToken = generateSignedTokensFromCredentials(serviceAccountCredentials, dataTokens, timeToLive, context);
62+
responseToken = generateSignedTokensFromCredentials(serviceAccountCredentials, dataTokens, timeToLive, context, overrideTokenUri);
6063
} catch (JsonSyntaxException e) {
6164
LogUtil.printErrorLog(ErrorLogs.INVALID_CREDENTIALS_FILE_FORMAT.getLog());
6265
throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), Utils.parameterizedString(
@@ -70,7 +73,7 @@ private static List<SignedDataTokenResponse> generateSignedTokenFromCredentialsF
7073
}
7174

7275
private static List<SignedDataTokenResponse> generateSignedTokensFromCredentialsString(
73-
String credentials, ArrayList<String> dataTokens, Integer timeToLive, String context
76+
String credentials, ArrayList<String> dataTokens, Integer timeToLive, String context, String overrideTokenUri
7477
) throws SkyflowException {
7578
LogUtil.printInfoLog(InfoLogs.GENERATE_SIGNED_TOKENS_FROM_CREDENTIALS_STRING_TRIGGERED.getLog());
7679
List<SignedDataTokenResponse> responseToken;
@@ -80,7 +83,7 @@ private static List<SignedDataTokenResponse> generateSignedTokensFromCredentials
8083
throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidCredentials.getMessage());
8184
}
8285
JsonObject serviceAccountCredentials = JsonParser.parseString(credentials).getAsJsonObject();
83-
responseToken = generateSignedTokensFromCredentials(serviceAccountCredentials, dataTokens, timeToLive, context);
86+
responseToken = generateSignedTokensFromCredentials(serviceAccountCredentials, dataTokens, timeToLive, context, overrideTokenUri);
8487
} catch (JsonSyntaxException e) {
8588
LogUtil.printErrorLog(ErrorLogs.INVALID_CREDENTIALS_STRING_FORMAT.getLog());
8689
throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(),
@@ -90,7 +93,7 @@ private static List<SignedDataTokenResponse> generateSignedTokensFromCredentials
9093
}
9194

9295
private static List<SignedDataTokenResponse> generateSignedTokensFromCredentials(
93-
JsonObject credentials, ArrayList<String> dataTokens, Integer timeToLive, String context
96+
JsonObject credentials, ArrayList<String> dataTokens, Integer timeToLive, String context, String overrideTokenUri
9497
) throws SkyflowException {
9598
List<SignedDataTokenResponse> signedDataTokens = null;
9699
try {
@@ -113,7 +116,7 @@ private static List<SignedDataTokenResponse> generateSignedTokensFromCredentials
113116
}
114117
PrivateKey pvtKey = Utils.getPrivateKeyFromPem(privateKey.getAsString());
115118
signedDataTokens = getSignedToken(
116-
clientID.getAsString(), keyID.getAsString(), pvtKey, dataTokens, timeToLive, context);
119+
clientID.getAsString(), keyID.getAsString(), pvtKey, dataTokens, timeToLive, context, overrideTokenUri);
117120
} catch (RuntimeException e) {
118121
LogUtil.printErrorLog(ErrorLogs.SIGNED_DATA_TOKENS_REJECTED.getLog());
119122
throw new SkyflowException(e);
@@ -123,7 +126,7 @@ private static List<SignedDataTokenResponse> generateSignedTokensFromCredentials
123126

124127
private static List<SignedDataTokenResponse> getSignedToken(
125128
String clientID, String keyID, PrivateKey pvtKey,
126-
ArrayList<String> dataTokens, Integer timeToLive, String context
129+
ArrayList<String> dataTokens, Integer timeToLive, String context, String overrideTokenUri
127130
) {
128131
final Date createdDate = new Date();
129132
final Date expirationDate;
@@ -134,15 +137,21 @@ private static List<SignedDataTokenResponse> getSignedToken(
134137
expirationDate = new Date(createdDate.getTime() + 60000); // Valid for 60 seconds
135138
}
136139

140+
String finalTokenUri = null;
141+
if (overrideTokenUri != null && !overrideTokenUri.isEmpty()) {
142+
finalTokenUri = overrideTokenUri;
143+
}
144+
137145
List<SignedDataTokenResponse> list = new ArrayList<>();
138146
for (String dataToken : dataTokens) {
139147
String eachSignedDataToken = Jwts.builder()
140-
.claim(Constants.JwtClaims.ISS, Constants.JwtClaims.SDK)
148+
.claim(Constants.JwtClaims.ISS, "sdk")
141149
.claim(Constants.JwtClaims.IAT, (createdDate.getTime() / 1000))
142150
.claim(Constants.JwtClaims.KEY, keyID)
143151
.claim(Constants.JwtClaims.SUB, clientID)
144152
.claim(Constants.JwtClaims.CTX, context)
145153
.claim(Constants.JwtClaims.TOK, dataToken)
154+
.claim(Constants.JwtClaims.AUD, finalTokenUri)
146155
.expiration(expirationDate)
147156
.signWith(pvtKey, Jwts.SIG.RS256)
148157
.compact();
@@ -156,9 +165,9 @@ public synchronized List<SignedDataTokenResponse> getSignedDataTokens() throws S
156165
LogUtil.printInfoLog(InfoLogs.GET_SIGNED_DATA_TOKENS_TRIGGERED.getLog());
157166
List<SignedDataTokenResponse> signedToken = new ArrayList<>();
158167
if (this.credentialsFile != null && Objects.equals(this.credentialsType, Constants.CredentialTypeValues.FILE)) {
159-
signedToken = generateSignedTokenFromCredentialsFile(this.credentialsFile, this.dataTokens, this.timeToLive, this.ctx);
168+
signedToken = generateSignedTokenFromCredentialsFile(this.credentialsFile, this.dataTokens, this.timeToLive, this.ctx, this.tokenUri);
160169
} else if (this.credentialsString != null && Objects.equals(this.credentialsType, Constants.CredentialTypeValues.STRING)) {
161-
signedToken = generateSignedTokensFromCredentialsString(this.credentialsString, this.dataTokens, this.timeToLive, this.ctx);
170+
signedToken = generateSignedTokensFromCredentialsString(this.credentialsString, this.dataTokens, this.timeToLive, this.ctx, this.tokenUri);
162171
}
163172
LogUtil.printInfoLog(InfoLogs.GET_SIGNED_DATA_TOKEN_SUCCESS.getLog());
164173
return signedToken;
@@ -171,6 +180,7 @@ public static class SignedDataTokensBuilder {
171180
private String credentialsString;
172181
private String ctx;
173182
private String credentialsType;
183+
private String tokenUri;
174184

175185
private SignedDataTokensBuilder() {
176186
}
@@ -206,6 +216,19 @@ public SignedDataTokensBuilder setTimeToLive(Integer timeToLive) {
206216
return this;
207217
}
208218

219+
public SignedDataTokensBuilder setTokenUri(String tokenUri) throws SkyflowException {
220+
if (tokenUri != null && !tokenUri.isEmpty()) {
221+
try {
222+
new java.net.URL(tokenUri);
223+
this.tokenUri = tokenUri;
224+
} catch (MalformedURLException e) {
225+
LogUtil.printErrorLog(ErrorLogs.INVALID_TOKEN_URI.getLog());
226+
throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidTokenUri.getMessage());
227+
}
228+
}
229+
return this;
230+
}
231+
209232
public SignedDataTokens build() {
210233
return new SignedDataTokens(this);
211234
}

src/main/java/com/skyflow/utils/Utils.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,23 @@ public static String getVaultURL(String clusterId, Env env) {
5151

5252
public static String generateBearerToken(Credentials credentials) throws SkyflowException {
5353
if (credentials.getPath() != null) {
54-
return BearerToken.builder()
54+
BearerToken.BearerTokenBuilder builder = BearerToken.builder()
5555
.setCredentials(new File(credentials.getPath()))
5656
.setRoles(credentials.getRoles())
57-
.setCtx(credentials.getContext())
58-
.build()
59-
.getBearerToken();
57+
.setCtx(credentials.getContext());
58+
if (credentials.getTokenUri() != null) {
59+
builder.setTokenUri(credentials.getTokenUri());
60+
}
61+
return builder.build().getBearerToken();
6062
} else if (credentials.getCredentialsString() != null) {
61-
return BearerToken.builder()
63+
BearerToken.BearerTokenBuilder builder = BearerToken.builder()
6264
.setCredentials(credentials.getCredentialsString())
6365
.setRoles(credentials.getRoles())
64-
.setCtx(credentials.getContext())
65-
.build()
66-
.getBearerToken();
66+
.setCtx(credentials.getContext());
67+
if (credentials.getTokenUri() != null) {
68+
builder.setTokenUri(credentials.getTokenUri());
69+
}
70+
return builder.build().getBearerToken();
6771
} else {
6872
return credentials.getToken();
6973
}

src/main/java/com/skyflow/utils/validations/Validations.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ public static void validateCredentials(Credentials credentials) throws SkyflowEx
170170
String token = credentials.getToken();
171171
String apiKey = credentials.getApiKey();
172172
String context = credentials.getContext();
173+
String tokenUri = credentials.getTokenUri();
173174
ArrayList<String> roles = credentials.getRoles();
174175

175176
if (path != null) nonNullMembers++;
@@ -228,6 +229,11 @@ public static void validateCredentials(Credentials credentials) throws SkyflowEx
228229
LogUtil.printErrorLog(ErrorLogs.EMPTY_OR_NULL_CONTEXT.getLog());
229230
throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.EmptyContext.getMessage());
230231
}
232+
233+
if (tokenUri != null && isInvalidURL(tokenUri)) {
234+
LogUtil.printErrorLog(ErrorLogs.INVALID_TOKEN_URI.getLog());
235+
throw new SkyflowException(ErrorCode.INVALID_INPUT.getCode(), ErrorMessage.InvalidTokenUri.getMessage());
236+
}
231237
}
232238

233239
public static void validateDetokenizeRequest(DetokenizeRequest detokenizeRequest) throws SkyflowException {

0 commit comments

Comments
 (0)