1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.common.aws.auth;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  
21  import org.kuali.common.aws.model.ImmutableAWSCredentials;
22  import org.kuali.common.aws.model.ImmutableAWSSessionCredentials;
23  import org.kuali.common.util.Assert;
24  import org.kuali.common.util.enc.EncUtils;
25  import org.kuali.common.util.enc.EncryptionService;
26  import org.kuali.common.util.spring.env.EnvironmentService;
27  
28  import com.amazonaws.auth.AWSCredentials;
29  import com.amazonaws.auth.AWSCredentialsProvider;
30  import com.amazonaws.auth.AWSCredentialsProviderChain;
31  import com.amazonaws.auth.AWSSessionCredentials;
32  import com.amazonaws.auth.InstanceProfileCredentialsProvider;
33  import com.google.common.base.Optional;
34  import com.google.common.collect.ImmutableList;
35  
36  
37  
38  
39  public final class DefaultProviderChain extends AWSCredentialsProviderChain {
40  
41  	private final Optional<AWSCredentials> optionalCredentials;
42  	private final Optional<EncryptionService> enc;
43  	private final Optional<EnvironmentService> env;
44  	private final boolean instanceCredentialsOverride;
45  	private final List<AWSCredentialsProvider> providers;
46  
47  	public static class Builder {
48  
49  		
50  		private Optional<EncryptionService> enc = Optional.absent();
51  		private Optional<EnvironmentService> env = Optional.absent();
52  		private Optional<AWSCredentials> optionalCredentials = Optional.absent();
53  		private boolean instanceCredentialsOverride = false; 
54  
55  		
56  		private List<AWSCredentialsProvider> providers;
57  
58  		private static final String INSTANCE_CREDENTIALS_OVERRIDE_KEY = "aws.instanceCredentialsOverride";
59  
60  		public Builder enc(EncryptionService enc) {
61  			this.enc = Optional.of(enc);
62  			return this;
63  		}
64  
65  		public Builder env(EnvironmentService env) {
66  			this.env = Optional.of(env);
67  			return this;
68  		}
69  
70  		public Builder credentials(AWSCredentials credentials) {
71  			this.optionalCredentials = Optional.of(credentials);
72  			return this;
73  		}
74  
75  		public Builder instanceCredentialsOverride(boolean instanceCredentialsOverride) {
76  			this.instanceCredentialsOverride = instanceCredentialsOverride;
77  			return this;
78  		}
79  
80  		private void override() {
81  			if (env.isPresent()) {
82  				instanceCredentialsOverride(env.get().getBoolean(INSTANCE_CREDENTIALS_OVERRIDE_KEY, instanceCredentialsOverride));
83  			}
84  		}
85  
86  		private void validate(DefaultProviderChain provider) {
87  			Assert.noNulls(provider.getCredentials(), provider.getEnc(), provider.getEnv(), provider.getProviders());
88  			Assert.isTrue(provider.getProviders().size() > 0, "Must supply at least one provider");
89  		}
90  
91  		public DefaultProviderChain build() {
92  			override();
93  			this.providers = getProviders();
94  			DefaultProviderChain provider = new DefaultProviderChain(this);
95  			validate(provider);
96  			return provider;
97  		}
98  
99  		private List<AWSCredentialsProvider> getProviders() {
100 			
101 			List<AWSCredentialsProvider> providers = new ArrayList<AWSCredentialsProvider>();
102 
103 			
104 			if (env.isPresent()) {
105 				providers.add(new EnvCredentialsProvider.Builder(env.get()).build());
106 			}
107 
108 			
109 			providers.addAll(getOther());
110 
111 			
112 			return ImmutableList.copyOf(providers);
113 		}
114 
115 		protected List<AWSCredentialsProvider> getOther() {
116 			
117 			
118 			
119 			
120 			AWSCredentialsProvider ipcp = new InstanceProfileCredentialsProvider();
121 
122 			
123 			if (!optionalCredentials.isPresent()) {
124 				return ImmutableList.of(ipcp);
125 			}
126 
127 			
128 			AWSCredentialsProvider simple = new SimpleCredentialsProvider(optionalCredentials.get());
129 
130 			if (instanceCredentialsOverride) {
131 				
132 				return ImmutableList.of(ipcp, simple);
133 			} else {
134 				
135 				return ImmutableList.of(simple, ipcp);
136 			}
137 		}
138 	}
139 
140 	public DefaultProviderChain(Builder builder) {
141 		super(toArray(builder.providers));
142 		this.optionalCredentials = builder.optionalCredentials;
143 		this.enc = builder.enc;
144 		this.env = builder.env;
145 		this.instanceCredentialsOverride = builder.instanceCredentialsOverride;
146 		this.providers = builder.providers;
147 	}
148 
149 	private static AWSCredentialsProvider[] toArray(List<AWSCredentialsProvider> providers) {
150 		return providers.toArray(new AWSCredentialsProvider[providers.size()]);
151 	}
152 
153 	public Optional<AWSCredentials> getOptionalCredentials() {
154 		return optionalCredentials;
155 	}
156 
157 	public boolean isInstanceCredentialsOverride() {
158 		return instanceCredentialsOverride;
159 	}
160 
161 	@Override
162 	public AWSCredentials getCredentials() {
163 		AWSCredentials creds = super.getCredentials();
164 		String accessKey = creds.getAWSAccessKeyId();
165 		String secretKey = EncUtils.decrypt(enc, creds.getAWSSecretKey());
166 		if (creds instanceof AWSSessionCredentials) {
167 			AWSSessionCredentials sessionCreds = (AWSSessionCredentials) creds;
168 			return ImmutableAWSSessionCredentials.build(accessKey, secretKey, sessionCreds.getSessionToken());
169 		} else {
170 			return ImmutableAWSCredentials.build(accessKey, secretKey);
171 		}
172 	}
173 
174 	public List<AWSCredentialsProvider> getProviders() {
175 		return providers;
176 	}
177 
178 	public Optional<EncryptionService> getEnc() {
179 		return enc;
180 	}
181 
182 	public Optional<EnvironmentService> getEnv() {
183 		return env;
184 	}
185 
186 }