You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by di...@apache.org on 2019/11/08 17:23:13 UTC
[airavata-custos] branch develop updated: Draft API definitions for
Resource, Secret and CILogon controllers
This is an automated email from the ASF dual-hosted git repository.
dimuthuupe pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/airavata-custos.git
The following commit(s) were added to refs/heads/develop by this push:
new 269a523 Draft API definitions for Resource, Secret and CILogon controllers
269a523 is described below
commit 269a523b125a6966c8489836f444dbd8631961aa
Author: Dimuthu Wannipurage <di...@gmail.com>
AuthorDate: Fri Nov 8 12:22:59 2019 -0500
Draft API definitions for Resource, Secret and CILogon controllers
---
.../custos/rest/controller/CILogonController.java | 78 ++++++++++++++++++++--
.../custos/rest/controller/ResourceController.java | 6 ++
.../custos/rest/controller/SecretController.java | 47 +++++++++++++
.../custos/rest/controller/TenantController.java | 20 +++++-
.../org/apache/custos/rest/core/AppConfig.java | 6 ++
.../rest/resources/CILogonClientInfoResource.java | 61 +++++++++++++++++
.../resources/CILogonClientRequestResource.java | 4 ++
.../custos/rest/resources/KVSecretResource.java | 23 +++++++
.../org/apache/custos/rest/resources/Resource.java | 44 ++++++++++++
.../org/apache/custos/rest/util/SecretEngine.java | 15 +++++
10 files changed, 296 insertions(+), 8 deletions(-)
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/controller/CILogonController.java b/custos-rest-api/src/main/java/org/apache/custos/rest/controller/CILogonController.java
index 7b411e9..65329b7 100644
--- a/custos-rest-api/src/main/java/org/apache/custos/rest/controller/CILogonController.java
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/controller/CILogonController.java
@@ -1,15 +1,81 @@
package org.apache.custos.rest.controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.custos.commons.model.security.AuthzToken;
+import org.apache.custos.profile.iam.admin.services.cpi.exception.IamAdminServicesException;
+import org.apache.custos.profile.tenant.cpi.TenantProfileService;
+import org.apache.custos.rest.resources.CILogonClientInfoResource;
+import org.apache.http.HttpHeaders;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.ws.rs.PathParam;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Base64;
@RestController
@RequestMapping("/cilogon")
public class CILogonController {
- @RequestMapping(value = "hello", method = RequestMethod.GET)
- public String helloMethod() {
- return "Hello";
+ private static AuthzToken authzToken = new AuthzToken("empy_token");
+
+ private String cILogonAdminClientId = "";
+ private String cILogonAdminClientSecret = "";
+ private String cILogonAdminUrl = "";
+
+ @Autowired
+ private TenantProfileService.Client tenantClient;
+
+ @RequestMapping(value = "client/{tenant}", method = RequestMethod.POST)
+ public CILogonClientInfoResource createCILogOnClient(@PathVariable("tenant") String tenantId) throws Exception {
+ // Check realm is created is first, is callback urls exist
+ boolean gatewayExist = tenantClient.isGatewayExist(authzToken, tenantId);
+ if (!gatewayExist) {
+ throw new Exception("Tennant " + tenantId + " does not exist");
+ }
+
+ CloseableHttpClient httpClient = HttpClients.createSystem();
+
+ HttpPost httpPost = new HttpPost(cILogonAdminUrl);
+ String encoded = Base64.getEncoder().encodeToString((cILogonAdminClientId+":"+cILogonAdminClientSecret).getBytes(StandardCharsets.UTF_8));
+ httpPost.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + encoded);
+ JSONObject data = new JSONObject();
+ data.put("client_name", cILogonAdminClientId);
+ data.put("redirect_uris", new JSONArray(new ArrayList<>()));
+ data.put("comments", "Created by custos");
+ httpPost.setEntity(new StringEntity(data.toString(), ContentType.APPLICATION_JSON));
+
+ try {
+ CloseableHttpResponse response = httpClient.execute(httpPost);
+ if(response.getStatusLine().getStatusCode() < 200 || response.getStatusLine().getStatusCode() > 299) {
+ throw new Exception("Could not create a cilogon client");
+ }
+ try {
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ CILogonClientInfoResource ciLogonClientInfoResource = objectMapper.readValue(EntityUtils.toString(response.getEntity()), CILogonClientInfoResource.class);
+ return ciLogonClientInfoResource;
+ } finally {
+ response.close();
+ }
+ } finally {
+ try {
+ httpClient.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
}
+
}
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/controller/ResourceController.java b/custos-rest-api/src/main/java/org/apache/custos/rest/controller/ResourceController.java
new file mode 100644
index 0000000..0a8cbeb
--- /dev/null
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/controller/ResourceController.java
@@ -0,0 +1,6 @@
+package org.apache.custos.rest.controller;
+
+public class ResourceController {
+
+ // CURD operations for Resource
+}
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/controller/SecretController.java b/custos-rest-api/src/main/java/org/apache/custos/rest/controller/SecretController.java
new file mode 100644
index 0000000..8e7ae1e
--- /dev/null
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/controller/SecretController.java
@@ -0,0 +1,47 @@
+package org.apache.custos.rest.controller;
+
+import org.apache.custos.rest.resources.KVSecretResource;
+import org.apache.custos.rest.util.SecretEngine;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.*;
+
+@RestController
+@RequestMapping("/secret")
+public class SecretController {
+
+ @Autowired
+ private SecretEngine secretEngine;
+
+ /**
+ * This saves a single key value pair in vault and returns a vault id
+ * @return Unique id for the secret
+ */
+ @RequestMapping(value = "single", method = RequestMethod.POST)
+ public String saveSecret(@RequestBody KVSecretResource secret) {
+ return secretEngine.soreKV(Collections.singletonMap(secret.getKey(), secret.getValue()));
+ }
+
+
+ /**
+ * This saves multiple key value pairs in vault and returns a single vault id
+ * @param secrets
+ * @return Unique id for all secrets
+ */
+ @RequestMapping(value = "multiple", method = RequestMethod.POST)
+ public String saveSecrets(@RequestBody List<KVSecretResource> secrets) {
+ Map<String, String> secMap = new HashMap<>();
+ secrets.forEach(s-> secMap.put(s.getKey(), s.getValue()));
+ return secretEngine.soreKV(secMap);
+ }
+
+ public List<KVSecretResource> getSecrets(String token) {
+ //Optional.ofNullable(secretEngine.getKV(token)).orElse(new HashMap<>());
+ //secretEngine.getKV(token).
+ return new ArrayList<>();
+ }
+}
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/controller/TenantController.java b/custos-rest-api/src/main/java/org/apache/custos/rest/controller/TenantController.java
index 8329693..d9e9e62 100644
--- a/custos-rest-api/src/main/java/org/apache/custos/rest/controller/TenantController.java
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/controller/TenantController.java
@@ -9,6 +9,7 @@ import org.apache.thrift.TException;
import org.dozer.DozerBeanMapper;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.keycloak.admin.client.KeycloakBuilder;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@@ -62,7 +63,7 @@ public class TenantController {
/*
Sample Request
- GET
+ POST
Creating a realm on keycloak for above gateway
http://localhost:8080/tenant/realm/40e5be38-0fde-41fe-a846-13de8b2ecfec
*/
@@ -73,16 +74,29 @@ public class TenantController {
RealmRepresentation realmRepresentation = new RealmRepresentation();
realmRepresentation.setRealm(gatewayT.getGatewayId());
keycloakAdminClient.realms().create(realmRepresentation);
-
return gateway;
}
+ /*
+ Sample Request
+
+ GET
+ Get the tenant with given id
+ http://localhost:8080/tenant/40e5be38-0fde-41fe-a846-13de8b2ecfec
+ */
@RequestMapping(value = "/{tenant}", method = RequestMethod.GET)
public GatewayResource getTenant(@PathVariable("tenant")String tenantId) throws TException {
Gateway gateway = tenantClient.getGateway(authzToken, tenantId);
return mapper.map(gateway, GatewayResource.class);
}
+ /*
+ Sample Request
+
+ GET
+ Get all tenants
+ http://localhost:8080/tenant
+ */
@RequestMapping(value = "/", method = RequestMethod.GET)
public List<GatewayResource> getAllTenants() throws TException {
@@ -98,4 +112,6 @@ public class TenantController {
public Boolean isTenantExists(@PathVariable("tenant")String tenantId) throws TException {
return tenantClient.isGatewayExist(authzToken, tenantId);
}
+
+ // save cilogon client id / secret. Secret goes to vault
}
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/core/AppConfig.java b/custos-rest-api/src/main/java/org/apache/custos/rest/core/AppConfig.java
index 48b607d..8f47c27 100644
--- a/custos-rest-api/src/main/java/org/apache/custos/rest/core/AppConfig.java
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/core/AppConfig.java
@@ -3,6 +3,7 @@ package org.apache.custos.rest.core;
import org.apache.custos.client.profile.service.CustosProfileServiceClientFactory;
import org.apache.custos.profile.tenant.cpi.TenantProfileService;
import org.apache.custos.profile.tenant.cpi.exception.TenantProfileServiceException;
+import org.apache.custos.rest.util.SecretEngine;
import org.dozer.DozerBeanMapper;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.keycloak.admin.client.Keycloak;
@@ -27,6 +28,11 @@ public class AppConfig {
return CustosProfileServiceClientFactory.createCustosTenantProfileServiceClient("iam.custos.scigap.org", 8081);
}
+ @Bean
+ public SecretEngine secretEngine() {
+ return new SecretEngine();
+ }
+
@Bean Keycloak keycloakAdminClient() {
ResteasyClientBuilder clientBuilder = new ResteasyClientBuilder()
.connectionPoolSize(10);
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/resources/CILogonClientInfoResource.java b/custos-rest-api/src/main/java/org/apache/custos/rest/resources/CILogonClientInfoResource.java
new file mode 100644
index 0000000..4fb336e
--- /dev/null
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/resources/CILogonClientInfoResource.java
@@ -0,0 +1,61 @@
+package org.apache.custos.rest.resources;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class CILogonClientInfoResource {
+
+ @JsonProperty("client_id")
+ private String clientId;
+
+ @JsonProperty("client_secret")
+ private String clientSecret;
+
+ @JsonProperty("client_id_issued_at")
+ private String clientIdIssuedAt;
+
+ @JsonProperty("client_secret_expires_at")
+ private String clientSecretExpiresAt;
+
+ @JsonProperty("registration_client_uri")
+ private String registrationClientUri;
+
+ public String getClientId() {
+ return clientId;
+ }
+
+ public void setClientId(String clientId) {
+ this.clientId = clientId;
+ }
+
+ public String getClientSecret() {
+ return clientSecret;
+ }
+
+ public void setClientSecret(String clientSecret) {
+ this.clientSecret = clientSecret;
+ }
+
+ public String getClientIdIssuedAt() {
+ return clientIdIssuedAt;
+ }
+
+ public void setClientIdIssuedAt(String clientIdIssuedAt) {
+ this.clientIdIssuedAt = clientIdIssuedAt;
+ }
+
+ public String getClientSecretExpiresAt() {
+ return clientSecretExpiresAt;
+ }
+
+ public void setClientSecretExpiresAt(String clientSecretExpiresAt) {
+ this.clientSecretExpiresAt = clientSecretExpiresAt;
+ }
+
+ public String getRegistrationClientUri() {
+ return registrationClientUri;
+ }
+
+ public void setRegistrationClientUri(String registrationClientUri) {
+ this.registrationClientUri = registrationClientUri;
+ }
+}
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/resources/CILogonClientRequestResource.java b/custos-rest-api/src/main/java/org/apache/custos/rest/resources/CILogonClientRequestResource.java
new file mode 100644
index 0000000..fdf973f
--- /dev/null
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/resources/CILogonClientRequestResource.java
@@ -0,0 +1,4 @@
+package org.apache.custos.rest.resources;
+
+public class CILogonClientRequestResource {
+}
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/resources/KVSecretResource.java b/custos-rest-api/src/main/java/org/apache/custos/rest/resources/KVSecretResource.java
new file mode 100644
index 0000000..7f0ccb3
--- /dev/null
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/resources/KVSecretResource.java
@@ -0,0 +1,23 @@
+package org.apache.custos.rest.resources;
+
+public class KVSecretResource {
+
+ private String key;
+ private String value;
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/resources/Resource.java b/custos-rest-api/src/main/java/org/apache/custos/rest/resources/Resource.java
new file mode 100644
index 0000000..ae3f81c
--- /dev/null
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/resources/Resource.java
@@ -0,0 +1,44 @@
+package org.apache.custos.rest.resources;
+
+public class Resource {
+
+ private String resourceId;
+ private String resourceName;
+ private String description;
+ // TODO
+ // This should be a class. Consider moving into ENUMS
+ private String visibility;
+
+
+ public String getResourceId() {
+ return resourceId;
+ }
+
+ public void setResourceId(String resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ public String getResourceName() {
+ return resourceName;
+ }
+
+ public void setResourceName(String resourceName) {
+ this.resourceName = resourceName;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getVisibility() {
+ return visibility;
+ }
+
+ public void setVisibility(String visibility) {
+ this.visibility = visibility;
+ }
+}
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/util/SecretEngine.java b/custos-rest-api/src/main/java/org/apache/custos/rest/util/SecretEngine.java
new file mode 100644
index 0000000..7ca3ea6
--- /dev/null
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/util/SecretEngine.java
@@ -0,0 +1,15 @@
+package org.apache.custos.rest.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class SecretEngine {
+
+ public String soreKV(Map<String, String> secrets) {
+ return "";
+ }
+
+ public Map<String, String> getKV(String token) {
+ return new HashMap<>();
+ }
+}