aboutsummaryrefslogtreecommitdiffstats
path: root/vespa-athenz
diff options
context:
space:
mode:
authorMorten Tokle <mortent@verizonmedia.com>2020-02-03 09:40:42 +0100
committerMorten Tokle <mortent@verizonmedia.com>2020-02-03 13:26:35 +0100
commit57496f95277de1527876eac773e88f18edaac005 (patch)
treec94e9b0b9ee46fd86d7695ead7df51a3a9349e76 /vespa-athenz
parent802a97b6726b70acc68c0971b5bf6061f8e04539 (diff)
Implement zts client getAccessToken
Diffstat (limited to 'vespa-athenz')
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java31
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/ZtsClient.java17
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/bindings/AccessTokenResponseEntity.java49
3 files changed, 97 insertions, 0 deletions
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java
index eec578ddc26..c05213c8008 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/DefaultZtsClient.java
@@ -2,14 +2,17 @@
package com.yahoo.vespa.athenz.client.zts;
import com.yahoo.security.Pkcs10Csr;
+import com.yahoo.vespa.athenz.api.AthenzAccessToken;
import com.yahoo.vespa.athenz.api.AthenzDomain;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
+import com.yahoo.vespa.athenz.api.AthenzResourceName;
import com.yahoo.vespa.athenz.api.AthenzRole;
import com.yahoo.vespa.athenz.api.AwsRole;
import com.yahoo.vespa.athenz.api.AwsTemporaryCredentials;
import com.yahoo.vespa.athenz.api.NToken;
import com.yahoo.vespa.athenz.api.ZToken;
import com.yahoo.vespa.athenz.client.common.ClientBase;
+import com.yahoo.vespa.athenz.client.zts.bindings.AccessTokenResponseEntity;
import com.yahoo.vespa.athenz.client.zts.bindings.AwsTemporaryCredentialsResponseEntity;
import com.yahoo.vespa.athenz.client.zts.bindings.IdentityRefreshRequestEntity;
import com.yahoo.vespa.athenz.client.zts.bindings.IdentityResponseEntity;
@@ -36,6 +39,7 @@ import java.time.Duration;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
@@ -147,6 +151,33 @@ public class DefaultZtsClient extends ClientBase implements ZtsClient {
}
@Override
+ public AthenzAccessToken getAccessToken(AthenzDomain domain) {
+ return this.getAccessTokenImpl(List.of(new AthenzResourceName(domain, "domain")));
+ }
+
+ @Override
+ public AthenzAccessToken getAccessToken(List<AthenzRole> athenzRole) {
+ List<AthenzResourceName> athenzResourceNames = athenzRole.stream()
+ .map(AthenzRole::toResourceName)
+ .collect(toList());
+ return this.getAccessTokenImpl(athenzResourceNames);
+ }
+
+ private AthenzAccessToken getAccessTokenImpl(List<AthenzResourceName> resources) {
+ URI uri = ztsUrl.resolve("oauth2/token");
+ RequestBuilder requestBuilder = RequestBuilder.post(uri)
+ .addHeader("Content-Type", "application/x-www-form-urlencoded")
+ .addParameter("grant_type", "client_credentials")
+ .addParameter("scope", resources.stream().map(AthenzResourceName::toResourceNameString).collect(Collectors.joining(" ")));
+
+ HttpUriRequest request = requestBuilder.build();
+ return execute(request, response -> {
+ AccessTokenResponseEntity accessTokenResponseEntity = readEntity(response, AccessTokenResponseEntity.class);
+ return accessTokenResponseEntity.accessToken();
+ });
+ }
+
+ @Override
public X509Certificate getRoleCertificate(AthenzRole role, Pkcs10Csr csr, Duration expiry) {
RoleCertificateRequestEntity requestEntity = new RoleCertificateRequestEntity(csr, expiry);
URI uri = ztsUrl.resolve(String.format("domain/%s/role/%s/token", role.domain().getName(), role.roleName()));
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/ZtsClient.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/ZtsClient.java
index c09ad8f48a0..baeb4271905 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/ZtsClient.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/ZtsClient.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.athenz.client.zts;
import com.yahoo.security.Pkcs10Csr;
+import com.yahoo.vespa.athenz.api.AthenzAccessToken;
import com.yahoo.vespa.athenz.api.AthenzDomain;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
import com.yahoo.vespa.athenz.api.AthenzRole;
@@ -78,6 +79,22 @@ public interface ZtsClient extends AutoCloseable {
ZToken getRoleToken(AthenzRole athenzRole);
/**
+ * Fetch an access token for the target domain
+ *
+ * @param domain Target domain
+ * @return An Athenz access token
+ */
+ AthenzAccessToken getAccessToken(AthenzDomain domain);
+
+ /**
+ * Fetch an access token for the target roles
+ *
+ * @param athenzRole List of athenz roles to get access token for
+ * @return An Athenz access token
+ */
+ AthenzAccessToken getAccessToken(List<AthenzRole> athenzRole);
+
+ /**
* Fetch role certificate for the target domain and role
*
* @param role Target role
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/bindings/AccessTokenResponseEntity.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/bindings/AccessTokenResponseEntity.java
new file mode 100644
index 00000000000..edd423b52bd
--- /dev/null
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/client/zts/bindings/AccessTokenResponseEntity.java
@@ -0,0 +1,49 @@
+// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.athenz.client.zts.bindings;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.yahoo.vespa.athenz.api.AthenzAccessToken;
+import com.yahoo.vespa.athenz.api.AthenzResourceName;
+import com.yahoo.vespa.athenz.api.AthenzRole;
+
+import java.time.Instant;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @author mortent
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class AccessTokenResponseEntity {
+ private final AthenzAccessToken accessToken;
+ private final Instant expiryTime;
+ private final List<AthenzRole> roles;
+
+ public AccessTokenResponseEntity(
+ @JsonProperty("access_token") String accessToken,
+ @JsonProperty("expires_in") int expiresIn,
+ @JsonProperty("scope") String roles) {
+
+ this.accessToken = new AthenzAccessToken(accessToken);
+ // We do not know from when, so best we can do is assume now ...
+ this.expiryTime = Instant.now().plusSeconds(expiresIn);
+ this.roles = Stream.of(roles.split(" "))
+ .map(AthenzResourceName::fromString)
+ .map(AthenzRole::fromResourceName)
+ .collect(Collectors.toList());
+ }
+
+ public AthenzAccessToken accessToken() {
+ return accessToken;
+ }
+
+ public Instant expiryTime() {
+ return expiryTime;
+ }
+
+ public List<AthenzRole> roles() {
+ return roles;
+ }
+}