
com.axway.apim.appimport.adapter.ClientAppConfigAdapter Maven / Gradle / Ivy
package com.axway.apim.appimport.adapter;
import com.axway.apim.ClientAppAdapter;
import com.axway.apim.adapter.APIManagerAdapter;
import com.axway.apim.adapter.apis.APIFilter;
import com.axway.apim.adapter.apis.APIManagerAPIAdapter;
import com.axway.apim.adapter.jackson.AppCredentialsDeserializer;
import com.axway.apim.adapter.jackson.QuotaRestrictionDeserializer;
import com.axway.apim.adapter.jackson.QuotaRestrictionDeserializer.DeserializeMode;
import com.axway.apim.adapter.user.APIManagerUserAdapter;
import com.axway.apim.adapter.user.UserFilter;
import com.axway.apim.api.API;
import com.axway.apim.api.model.APIAccess;
import com.axway.apim.api.model.CustomProperties.Type;
import com.axway.apim.api.model.Image;
import com.axway.apim.api.model.QuotaRestriction;
import com.axway.apim.api.model.User;
import com.axway.apim.api.model.apps.ApplicationPermission;
import com.axway.apim.api.model.apps.ClientAppCredential;
import com.axway.apim.api.model.apps.ClientApplication;
import com.axway.apim.api.model.apps.OAuth;
import com.axway.apim.appimport.lib.AppImportParams;
import com.axway.apim.lib.Result;
import com.axway.apim.lib.error.AppException;
import com.axway.apim.lib.error.ErrorCode;
import com.axway.apim.lib.utils.Utils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class ClientAppConfigAdapter extends ClientAppAdapter {
private static final Logger LOG = LoggerFactory.getLogger(ClientAppConfigAdapter.class);
AppImportParams importParams;
public ClientAppConfigAdapter(AppImportParams params) {
this.importParams = params;
this.result = new Result();
}
public ClientAppConfigAdapter(AppImportParams params, Result result) {
this.importParams = params;
this.result = result;
}
@Override
protected void readConfig() throws AppException {
String config = importParams.getConfig();
String stage = importParams.getStage();
File configFile = Utils.locateConfigFile(config);
if (!configFile.exists()) return;
File stageConfig = Utils.getStageConfig(stage, importParams.getStageConfig(), configFile);
List baseApps;
// Try to read a list of applications
ObjectMapper mapper = Utils.createObjectMapper(configFile);
try {
mapper.registerModule(new SimpleModule().addDeserializer(ClientAppCredential.class, new AppCredentialsDeserializer()));
mapper.registerModule(new SimpleModule().addDeserializer(QuotaRestriction.class, new QuotaRestrictionDeserializer(DeserializeMode.configFile)));
baseApps = mapper.readValue(Utils.substituteVariables(configFile), new TypeReference>() {
});
if (stageConfig != null) {
throw new AppException("Stage overrides are not supported for application lists.", ErrorCode.CANT_READ_CONFIG_FILE);
} else {
this.apps = baseApps;
}
// Try to read single application
} catch (MismatchedInputException me) {
try {
LOG.debug("Error reading array of applications, hence trying to read single application now.");
ClientApplication app = mapper.readValue(Utils.substituteVariables(configFile), ClientApplication.class);
LOG.info("{}", app);
app = readClientApplication(mapper, app, stageConfig, stage);
LOG.info("{}", app);
this.apps = new ArrayList<>();
this.apps.add(app);
} catch (Exception pe) {
throw new AppException("Cannot read application(s) from config file: " + config, "Exception: " + pe.getClass().getName() + ": " + pe.getMessage(), ErrorCode.ERR_CREATING_APPLICATION, pe);
}
} catch (Exception e) {
throw new AppException("Cannot read application(s) from config file: " + config, "Exception: " + e.getClass().getName() + ": " + e.getMessage(), ErrorCode.ERR_CREATING_APPLICATION, e);
}
try {
addImage(apps, configFile.getCanonicalFile().getParentFile());
addOAuthCertificate(apps, configFile.getCanonicalFile().getParentFile());
} catch (Exception e) {
throw new AppException("Cannot read image/certificate for application(s) from config file: " + config, ErrorCode.ERR_CREATING_APPLICATION, e);
}
addAPIAccess(apps, result);
validateCustomProperties(apps);
validateAppPermissions(apps);
}
private void addImage(List apps, File parentFolder) throws AppException {
for (ClientApplication app : apps) {
String imageUrl = app.getImageUrl();
if (imageUrl == null || imageUrl.isEmpty()) continue;
if (imageUrl.startsWith("data:")) {
app.setImage(Image.createImageFromBase64(imageUrl));
} else {
app.setImage(Image.createImageFromFile(new File(parentFolder + File.separator + imageUrl)));
}
}
}
private void addOAuthCertificate(List apps, File parentFolder) throws AppException {
for (ClientApplication app : apps) {
for (ClientAppCredential cred : app.getCredentials()) {
if (cred instanceof OAuth && ((OAuth) cred).getCert() != null) {
String certificate = ((OAuth) cred).getCert();
if (certificate.startsWith("data:")) {
byte[] data = Base64.getDecoder().decode(certificate.replaceFirst("data:.+,", ""));
((OAuth) cred).setCert(new String(data));
} else {
File certFile = new File(parentFolder + File.separator + certificate);
if (!certFile.exists()) {
throw new AppException("Certificate file: '" + certFile + "' not found.", ErrorCode.UNXPECTED_ERROR);
}
try {
String certBlob = new String(Files.readAllBytes(certFile.toPath()));
((OAuth) cred).setCert(certBlob);
} catch (Exception e) {
throw new AppException("Can't read certificate from disc", ErrorCode.UNXPECTED_ERROR, e);
}
}
}
}
}
}
private void addAPIAccess(List apps, Result result) throws AppException {
APIManagerAPIAdapter apiAdapter = APIManagerAdapter.getInstance().getApiAdapter();
for (ClientApplication app : apps) {
if (app.getApiAccess() == null) continue;
Iterator it = app.getApiAccess().iterator();
while (it.hasNext()) {
APIAccess apiAccess = it.next();
List apis = apiAdapter.getAPIs(new APIFilter.Builder()
.hasName(apiAccess.getApiName())
.build()
, false);
if (apis == null || apis.isEmpty()) {
LOG.error("API with name: {} not found. Ignoring this APIs.", apiAccess.getApiName());
result.setError(ErrorCode.UNKNOWN_API);
it.remove();
continue;
}
if (apis.size() > 1 && apiAccess.getApiVersion() == null) {
LOG.error("Found: {} APIs with name: {} not providing a version. Ignoring this APIs.", apis.size(), apiAccess.getApiName());
result.setError(ErrorCode.UNKNOWN_API);
it.remove();
continue;
}
API api = apis.get(0);
apiAccess.setApiId(api.getId());
}
}
}
private void validateCustomProperties(List apps) throws AppException {
for (ClientApplication app : apps) {
Utils.validateCustomProperties(app.getCustomProperties(), Type.application);
}
}
private void validateAppPermissions(List apps) throws AppException {
APIManagerUserAdapter userAdapter = APIManagerAdapter.getInstance().getUserAdapter();
for (ClientApplication app : apps) {
if (app.getPermissions() == null || app.getPermissions().isEmpty()) continue;
// First check, if there is an ALL User
for (ApplicationPermission permission : app.getPermissions()) {
if ("ALL".equals(permission.getUsername())) {
// Create a map of all usernames
Map usernames = app.getPermissions().stream().collect(
Collectors.toMap(ApplicationPermission::getUsername, Function.identity()));
// Get all users for the app organization
List allOrgUsers = userAdapter.getUsers(new UserFilter.Builder().hasOrganization(app.getOrganization().getName()).build());
for (User user : allOrgUsers) {
// Only add permission based on ALL if not manually configured
if (!usernames.containsKey(user.getLoginName())) {
ApplicationPermission appPerm = new ApplicationPermission();
appPerm.setUser(user);
appPerm.setPermission(permission.getPermission());
app.getPermissions().add(appPerm);
}
}
break;
}
}
app.getPermissions().removeIf(e -> e.getUsername().equals("ALL"));
// Check individual permissions (e.g. single usernames)
for (int i = 0; i < app.getPermissions().size(); i++) {
ApplicationPermission permission = app.getPermissions().get(i);
if (permission.getUser() != null) continue;
User user = userAdapter.getUserForLoginName(permission.getUsername());
if (user == null) {
LOG.warn("Cannot share application with user: {} as user does not exists.", permission.getUsername());
app.getPermissions().remove(i);
continue;
}
permission.setUser(user);
}
}
}
public ClientApplication readClientApplication(ObjectMapper mapper, ClientApplication app, File stageConfig, String stage){
if (stageConfig != null) {
try {
ObjectReader updater = mapper.readerForUpdating(app);
return updater.readValue(Utils.substituteVariables(stageConfig));
} catch (IOException e) {
LOG.warn("No config file found for stage: {}", stage);
}
}
return app;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy