Commit 3e138202 authored by Rostislav Dublin (EPAM)'s avatar Rostislav Dublin (EPAM) Committed by Riabokon Stanislav(EPAM)[GCP]
Browse files

Closes GONRG-1108 by adding flexibility to INTEGRATION_TESTING and...

Closes GONRG-1108 by adding flexibility to INTEGRATION_TESTING and NO_DATA_ACCESS_TESTER ENV VARS pass ways (filename or content, plain or base64)
parent 1bd7e8e1
......@@ -32,12 +32,12 @@ In order to run the service locally, you will need to have the following environ
| `TENANT` | `opendes` | Tenant name | no | - |
| `DEFAULT_DATA_PARTITION_ID_TENANT1` | `opendes` | Data partition id | no | - |
| `DEFAULT_DATA_PARTITION_ID_TENANT2` | `opendes` | Data partition id | no | - |
| `SEARCH_INTEGRATION_TESTER` | `********` | Service account for API calls. Note: this user must have entitlements configured already | yes | https://console.cloud.google.com/iam-admin/serviceaccounts |
| `SEARCH_INTEGRATION_TESTER` | `********` | Service account for API calls, passed as a filename or JSON content, plain or Base64 encoded. Note: this user must have entitlements configured already | yes | https://console.cloud.google.com/iam-admin/serviceaccounts |
| `INTEGRATION_TEST_AUDIENCE` | `********` | Client application ID | yes | https://console.cloud.google.com/apis/credentials |
| `LEGAL_TAG` | ex `opendes-osdu-demo-legaltag` | Currently existing, not expired legal tag name| no | create one with POST {{legal_url}}api/legal/v1/legaltags |
| `OTHER_RELEVANT_DATA_COUNTRIES` | ex `US` | - | no | - |
| `GCLOUD_PROJECT` | ex `osdu-cicd-epam` | Google cloud project id | no | - |
| `GCP_DEPLOY_FILE` | `********` | Service account for test data tear down, must have cloud storage role configured | yes | https://console.cloud.google.com/iam-admin/serviceaccounts |
| `GCP_DEPLOY_FILE` | `********` | Service account for test data tear down, passed as a filename or JSON content, plain or Base64 encoded. Must have cloud storage role configured | yes | https://console.cloud.google.com/iam-admin/serviceaccounts |
**Entitlements configuration for integration accounts**
......
package org.opengroup.osdu.util;
import lombok.RequiredArgsConstructor;
import lombok.extern.java.Log;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.function.Predicate;
@Log
@RequiredArgsConstructor
public class DecodedContentExtractor {
private final String inputFilenameOrContent;
private final Predicate<String> contentAcceptanceTester;
private boolean validOutputContentFound;
private String outputContent;
public String getContent() {
validOutputContentFound = false;
outputContent = null;
log.info("Treat value as a content");
if (inputFilenameOrContent.trim().isEmpty()) {
log.info("provided value is empty. Output as is.");
return setValidOutputContent(inputFilenameOrContent);
}
if (!treatValueAsAContent(inputFilenameOrContent)) {
log.info("Value is not a valid content. Treat value as a filename");
if (!treatValueAsAFileName(inputFilenameOrContent)){
log.info("Value is not a filename with a valid content");
}
}
return getValidOutputContentIfFound();
}
private boolean treatValueAsAContent(String input) {
if (contentAcceptanceTester.test(input)) {
log.info("the value is a valid content. Output as is.");
setValidOutputContent(input);
return true;
}
String output;
try {
output = new String(Base64.getDecoder().decode(input));
log.info("the value is probably Base64 encoded. Just decoded");
if (contentAcceptanceTester.test(output)) {
log.info("the decoded value is a valid content. Output decoded value.");
setValidOutputContent(output);
} else {
log.info("the decoded value is not a valid content.");
}
} catch (IllegalArgumentException e) {
log.info("the value is not Base64 encoded. ");
}
return validOutputContentFound;
}
private boolean treatValueAsAFileName(String filename) {
if (treatFileContent(filename)) return true;
try {
filename = new String(Base64.getDecoder().decode(filename));
log.info("the filename is probably Base64 encoded. Just decoded");
if (treatFileContent(filename)) return true;
} catch (IllegalArgumentException e) {
log.info("the filename is not Base64 encoded. ");
}
return validOutputContentFound;
}
private boolean treatFileContent(String filename) {
try {
Path path = Paths.get(filename);
if (Files.exists(path)) {
log.info("the filename is of existing file. Read file.");
try {
String fileContent = new String(Files.readAllBytes(path));
if (treatValueAsAContent(fileContent)) {
return true;
}
} catch (IOException | SecurityException | OutOfMemoryError ex) {
log.info(() -> ("unable to read the file: " + ex.getClass().getSimpleName()));
}
}
} catch (InvalidPathException ex) {
log.info("the filename is not valid or the file doesn't exist.");
}
return false;
}
private String setValidOutputContent(String outputContent) {
this.outputContent = outputContent;
this.validOutputContentFound = true;
return getValidOutputContentIfFound();
}
public String getValidOutputContentIfFound() {
return validOutputContentFound ? outputContent : null;
}
}
/**
/*
* Copyright 2020 Google LLC
* Copyright 2020 EPAM Systems, Inc
*
......@@ -14,7 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.util;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
......@@ -25,13 +24,8 @@ import com.google.api.client.json.webtoken.JsonWebToken;
import com.google.api.client.util.Clock;
import com.google.common.base.Strings;
import com.google.gson.Gson;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
import lombok.extern.java.Log;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
......@@ -42,13 +36,24 @@ import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
@Log
class JwtTokenUtil {
public final static Predicate<String> CREDENTIALS_CONTENT_ACCEPTANCE_TESTER = s -> s.trim().startsWith("{");
private static String accessToken;
static String getAccessToken() throws IOException {
if (Strings.isNullOrEmpty(accessToken)) {
log.info("Get SEARCH_INTEGRATION_TESTER credentials");
accessToken = getServiceAccountAccessToken(getJwtForIntegrationTesterAccount());
}
return accessToken;
......@@ -76,40 +81,43 @@ class JwtTokenUtil {
}
private static String getJwtForIntegrationTesterAccount() throws IOException {
String serviceAccountFile = Config.getKeyValue();
return getJwt(serviceAccountFile);
String serviceAccountValue = Config.getKeyValue();
return getJwt(serviceAccountValue);
}
private static String getJwt(String serviceAccountFile) throws IOException {
private static String getJwt(String serviceAccountValue) throws IOException {
String targetAudience = Config.getTargetAudience();
long currentTime = Clock.SYSTEM.currentTimeMillis();
InputStream stream = new FileInputStream(serviceAccountFile);
GoogleCredential credential = GoogleCredential.fromStream(stream);
JsonWebSignature.Header header = new JsonWebSignature.Header();
header.setAlgorithm("RS256");
header.setType("JWT");
header.setKeyId(credential.getServiceAccountPrivateKeyId());
JsonWebSignature.Payload payload = new JsonWebToken.Payload();
payload.setIssuedAtTimeSeconds(currentTime / 1000);
payload.setExpirationTimeSeconds(currentTime / 1000 + 3600);
payload.setAudience("https://www.googleapis.com/oauth2/v4/token");
payload.setIssuer(credential.getServiceAccountId());
payload.set("target_audience", targetAudience);
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
String signedJwt = null;
try {
signedJwt = JsonWebSignature
.signUsingRsaSha256(credential.getServiceAccountPrivateKey(), jsonFactory, header, payload);
} catch (GeneralSecurityException e) {
e.printStackTrace();
serviceAccountValue = new DecodedContentExtractor(serviceAccountValue, CREDENTIALS_CONTENT_ACCEPTANCE_TESTER).getContent();
try (InputStream inputStream = new ByteArrayInputStream(serviceAccountValue.getBytes())) {
GoogleCredential credential = GoogleCredential.fromStream(inputStream);
JsonWebSignature.Header header = new JsonWebSignature.Header();
header.setAlgorithm("RS256");
header.setType("JWT");
header.setKeyId(credential.getServiceAccountPrivateKeyId());
JsonWebSignature.Payload payload = new JsonWebToken.Payload();
payload.setIssuedAtTimeSeconds(currentTime / 1000);
payload.setExpirationTimeSeconds(currentTime / 1000 + 3600);
payload.setAudience("https://www.googleapis.com/oauth2/v4/token");
payload.setIssuer(credential.getServiceAccountId());
payload.set("target_audience", targetAudience);
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
String signedJwt = null;
try {
signedJwt = JsonWebSignature
.signUsingRsaSha256(credential.getServiceAccountPrivateKey(), jsonFactory, header, payload);
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
return signedJwt;
}
return signedJwt;
}
@Data
......
/**
/*
* Copyright 2020 Google LLC
* Copyright 2020 EPAM Systems, Inc
*
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
......@@ -19,20 +19,34 @@ package org.opengroup.osdu.util;
import com.google.auth.Credentials;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.FileInputStream;
import lombok.extern.java.Log;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
import static org.opengroup.osdu.util.JwtTokenUtil.CREDENTIALS_CONTENT_ACCEPTANCE_TESTER;
@Log
public class StorageServiceAccountCredentialsProvider {
private static GoogleCredentials credentials = null;
public static Credentials getCredentials() {
try {
credentials = GoogleCredentials
.fromStream(new FileInputStream(GcpConfig.getStorageAccount()));
} catch (IOException e) {
e.printStackTrace();
}
return credentials;
}
private static GoogleCredentials credentials = null;
public static Credentials getCredentials() {
if (Objects.isNull(credentials)) {
log.info("Get GCP_DEPLOY_FILE credentials");
String serviceAccountValue = GcpConfig.getStorageAccount();
serviceAccountValue = new DecodedContentExtractor(serviceAccountValue, CREDENTIALS_CONTENT_ACCEPTANCE_TESTER).getContent();
try (InputStream inputStream = new ByteArrayInputStream(serviceAccountValue.getBytes())) {
credentials = GoogleCredentials.fromStream(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
return credentials;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment