com.ksc.auth.profile.internal.ProfilesConfigFileLoader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ksyun-java-sdk-core Show documentation
Show all versions of ksyun-java-sdk-core Show documentation
The KSC SDK for Java - Core module holds the classes that is used
by the individual service clients to interact with KSC Web Services.
Users need to depend on KSC-java-sdk artifact for accessing individual client classes.
The newest version!
/*
* Copyright 2014-2016 ksyun.com, Inc. or its affiliates. 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://ksyun.com/apache2.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.ksc.auth.profile.internal;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.ksc.KscClientException;
import com.ksc.auth.BasicAWSCredentials;
import com.ksc.auth.BasicSessionCredentials;
import com.ksc.auth.credentials.AWSCredentials;
import com.ksc.auth.profile.internal.securitytoken.ProfileCredentialsService;
import com.ksc.auth.profile.internal.securitytoken.RoleInfo;
import com.ksc.util.StringUtils;
public class ProfilesConfigFileLoader {
private static final Log LOG = LogFactory.getLog(ProfilesConfigFileLoader.class);
public static Map loadProfiles(File file, ProfileCredentialsService profileCredentialsService) {
if (file == null) {
throw new IllegalArgumentException(
"Unable to load AWS profiles: specified file is null.");
}
if (!file.exists() || !file.isFile()) {
throw new IllegalArgumentException(
"AWS credential profiles file not found in the given path: "
+ file.getAbsolutePath());
}
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
return loadProfiles(fis, profileCredentialsService);
} catch (IOException ioe) {
throw new KscClientException(
"Unable to load AWS credential profiles file at: " + file.getAbsolutePath(), ioe);
} finally {
if (fis != null) try {fis.close();} catch (IOException ioe) {}
}
}
/**
* Loads the credential profiles from the given input stream.
*
* @param is input stream from where the profile details are read.
* @throws IOException
*/
private static Map loadProfiles(InputStream is, ProfileCredentialsService profileCredentialsService) throws IOException {
ProfilesConfigFileLoaderHelper helper = new ProfilesConfigFileLoaderHelper();
Map> allProfileProperties = helper.parseProfileProperties(new Scanner(is, StringUtils.UTF8.name()));
// Convert the loaded property map to credential objects
Map profilesByName = new LinkedHashMap();
for (Entry> entry : allProfileProperties.entrySet()) {
String profileName = entry.getKey();
Map properties = entry.getValue();
if (profileName.startsWith("profile ")) {
LOG.warn("The legacy profile format requires the 'profile ' prefix before the profile name. "
+ "The latest code does not require such prefix, and will consider it as part of the profile name. "
+ "Please remove the prefix if you are seeing this warning.");
}
assertParameterNotEmpty(profileName,
"Unable to load credentials into profile: ProfileName is empty.");
if (properties.containsKey(Profile.ROLE_ARN)) {
profilesByName.put(profileName, fromAssumeRole(profileName, properties, allProfileProperties, profileCredentialsService));
} else {
profilesByName.put(profileName, fromStaticCredentials(profileName, properties));
}
}
return profilesByName;
}
private static Profile fromStaticCredentials(String profileName, Map properties) {
String accessKey = properties.get(Profile.AWS_ACCESS_KEY_ID);
String secretKey = properties.get(Profile.AWS_SECRET_ACCESS_KEY);
String sessionToken = properties.get(Profile.AWS_SESSION_TOKEN);
if (StringUtils.isNullOrEmpty(accessKey)) {
throw new KscClientException(
String.format("Unable to load credentials into profile [%s]: AWS Access Key ID is not specified.",
profileName));
}
if (StringUtils.isNullOrEmpty(secretKey)) {
throw new KscClientException(
String.format("Unable to load credentials into profile [%s]: AWS Secret Access Key is not specified.",
profileName));
}
if (sessionToken == null) {
return new Profile(profileName,
new BasicAWSCredentials(accessKey, secretKey));
} else {
if (sessionToken.isEmpty()) {
throw new KscClientException(
String.format("Unable to load credentials into profile [%s]: AWS Session Token is empty.",
profileName));
}
return new Profile(profileName,
new BasicSessionCredentials(accessKey, secretKey, sessionToken));
}
}
private static Profile fromAssumeRole(String profileName, Map properties,
Map> allProfileProperties,
ProfileCredentialsService profileCredentialsService) {
String roleArn = properties.get(Profile.ROLE_ARN);
String sourceProfileName = properties.get(Profile.SOURCE_PROFILE);
String roleSessionName = properties.get(Profile.ROLE_SESSION_NAME);
String externalId = properties.get(Profile.EXTERNAL_ID);
if (StringUtils.isNullOrEmpty(sourceProfileName)) {
return Profile.createInvalidProfile(profileName, String.format(
"Unable to load credentials into profile [%s]: Source profile name is not specified",
profileName));
}
Map sourceProfileProperties = allProfileProperties.get(sourceProfileName);
if (sourceProfileProperties == null) {
return Profile.createInvalidProfile(profileName, String.format(
"Unable to load source profile [%s]: Source profile not found [%s]",
profileName, sourceProfileName));
}
String sourceAccessKey = sourceProfileProperties.get(Profile.AWS_ACCESS_KEY_ID);
String sourceSecretKey = sourceProfileProperties.get(Profile.AWS_SECRET_ACCESS_KEY);
String sourceSessionToken = sourceProfileProperties.get(Profile.AWS_SESSION_TOKEN);
AWSCredentials sourceCredentials;
if (StringUtils.isNullOrEmpty(sourceAccessKey)) {
return Profile.createInvalidProfile(profileName, String.format(
"Unable to load credentials into profile [%s]: AWS Access Key ID is not specified in source profile [%s].",
profileName, sourceProfileName));
}
if (StringUtils.isNullOrEmpty(sourceSecretKey)) {
return Profile.createInvalidProfile(profileName, String.format(
"Unable to load credentials into profile [%s]: AWS Secret Access Key is not specified in source profile [%s].",
profileName, sourceProfileName));
}
if (StringUtils.isNullOrEmpty(sourceSessionToken)) {
sourceCredentials = new BasicAWSCredentials(sourceAccessKey, sourceSecretKey);
} else {
sourceCredentials = new BasicSessionCredentials(sourceAccessKey, sourceSecretKey,
sourceSessionToken);
}
if (StringUtils.isNullOrEmpty(roleSessionName)) {
roleSessionName = "aws-sdk-java-" + System.currentTimeMillis();
}
RoleInfo roleInfo = new RoleInfo()
.withRoleArn(roleArn)
.withRoleSessionName(roleSessionName)
.withExternalId(externalId)
.withLongLivedCredentials(sourceCredentials);
return new Profile(profileName, sourceProfileName, profileCredentialsService.getAssumeRoleCredentialsProvider(roleInfo), roleInfo);
}
/**
*
* Asserts that the specified parameter value is neither empty
* nor null, and if it is, throws an AmazonClientException
with
* the specified error message.
*
*
* @param parameterValue
* The parameter value being checked.
* @param errorMessage
* The error message to include in the AmazonClientException if
* the specified parameter value is empty.
*/
private static void assertParameterNotEmpty(String parameterValue, String errorMessage) {
if (StringUtils.isNullOrEmpty(parameterValue)) {
throw new KscClientException(errorMessage);
}
}
/**
* Implementation of AbstractProfilesConfigFileScanner that groups profile
* properties into a map while scanning through the credentials profile.
*/
private static class ProfilesConfigFileLoaderHelper extends AbstractProfilesConfigFileScanner {
/**
* Map from the parsed profile name to the map of all the property values
* included the specific profile
*/
protected final Map> allProfileProperties = new LinkedHashMap>();
/**
* Parses the input and returns a map of all the profile properties.
*/
public Map> parseProfileProperties(Scanner scanner) {
allProfileProperties.clear();
run(scanner);
return new LinkedHashMap>(allProfileProperties);
}
@Override
protected void onEmptyOrCommentLine(String profileName, String line) {
// Ignore empty or comment line
}
@Override
protected void onProfileStartingLine(String newProfileName, String line) {
// If the same profile name has already been declared, clobber the
// previous one
allProfileProperties.put(newProfileName, new HashMap());
}
@Override
protected void onProfileEndingLine(String prevProfileName) {
// No-op
}
@Override
protected void onProfileProperty(String profileName,
String propertyKey, String propertyValue,
boolean isSupportedProperty, String line) {
if ( !isSupportedProperty ) {
LOG.info(String.format(
"Skip unsupported property name %s in profile [%s].",
propertyKey, profileName));
return;
}
// Not strictly necessary, since the abstract super class guarantees
// onProfileStartingLine is always invoked before this method.
// Just to be safe...
if (allProfileProperties.get(profileName) == null) {
allProfileProperties.put(profileName, new HashMap());
}
Map properties = allProfileProperties.get(profileName);
if (properties.containsKey(propertyKey)) {
throw new IllegalArgumentException(
"Duplicate property values for ["
+ propertyKey + "].");
}
properties.put(propertyKey, propertyValue);
}
@Override
protected void onEndOfFile() {
// No-op
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy