diff --git a/README.md b/README.md
index 292b036..b57cf41 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# GCube Security
+# GCube secrets
A core gCube library which empower authorization
@@ -13,7 +13,7 @@ A core gCube library which empower authorization
## Change log
-See [Releases](https://code-repo.d4science.org/gCubeSystem/gcube-security/releases).
+See [Releases](https://code-repo.d4science.org/gCubeSystem/gcube-secrets/releases).
## Authors
diff --git a/pom.xml b/pom.xml
index 4e3917e..f92c8d8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,9 +30,5 @@
org.slf4j
slf4j-api
-
- org.gcube.common
- keycloak-client
-
\ No newline at end of file
diff --git a/src/main/java/org/gcube/common/security/AuthorizedTasks.java b/src/main/java/org/gcube/common/security/AuthorizedTasks.java
index 7293f3e..83d2523 100644
--- a/src/main/java/org/gcube/common/security/AuthorizedTasks.java
+++ b/src/main/java/org/gcube/common/security/AuthorizedTasks.java
@@ -11,23 +11,23 @@ import org.slf4j.LoggerFactory;
public class AuthorizedTasks {
private static Logger logger= LoggerFactory.getLogger(AuthorizedTasks.class);
-
+
/**
* Binds a {@link Callable} task to the current scope and user.
* @param task the task
* @return an equivalent {@link Callable} task bound to the current scope and user
*/
static public Callable bind(final Callable task) {
-
-
+
+
final Secret secret = SecretManagerProvider.instance.get();
-
+
return new Callable() {
@Override
public V call() throws Exception {
-
+
SecretManagerProvider.instance.set(secret);
-
+
try {
logger.info("setting on authorized task context {} ", secret.getContext());
return task.call();
@@ -35,27 +35,27 @@ public class AuthorizedTasks {
finally {
SecretManagerProvider.instance.reset();
}
-
+
}
};
}
-
+
/**
* Binds a {@link Runnable} task to the current scope and user.
* @param task the task
* @return an equivalent {@link Runnable} task bound to the current scope and user
*/
static public Runnable bind(final Runnable task) {
-
-
+
+
final Secret secret = SecretManagerProvider.instance.get();
-
+
return new Runnable() {
@Override
public void run() {
-
+
SecretManagerProvider.instance.set(secret);
-
+
try {
logger.info("setting on authorized task context {} ", secret.getContext());
task.run();
@@ -63,9 +63,57 @@ public class AuthorizedTasks {
finally {
SecretManagerProvider.instance.reset();
}
-
+
}
};
}
-
+
+ /**
+ * Binds a {@link Runnable} task to the current scope and user.
+ * @param task the task
+ * @return an equivalent {@link Runnable} task bound to the current scope and user
+ */
+ static public void executeSafely(final Runnable task, final Secret secret) throws Throwable {
+
+ SafelyExecution se = new SafelyExecution(new Runnable() {
+
+ @Override
+ public void run() {
+ SecretManagerProvider.instance.set(secret);
+
+ try {
+ logger.info("setting on authorized task context {} ", secret.getContext());
+ task.run();
+ }finally {
+ SecretManagerProvider.instance.reset();
+ }
+
+ }
+ });
+
+ se.run();
+
+ if (se.e != null) throw se.e;
+
+ }
+
+ static private class SafelyExecution extends Thread{
+
+ protected Throwable e;
+
+ public SafelyExecution(Runnable target) {
+ super(target);
+ }
+
+ @Override
+ public void run() {
+ try {
+ super.run();
+ }catch (Throwable t) {
+ e = t;
+ }
+ }
+
+ }
+
}
diff --git a/src/main/java/org/gcube/common/security/ContextBean.java b/src/main/java/org/gcube/common/security/ContextBean.java
new file mode 100644
index 0000000..2cfe657
--- /dev/null
+++ b/src/main/java/org/gcube/common/security/ContextBean.java
@@ -0,0 +1,139 @@
+package org.gcube.common.security;
+
+
+
+/**
+ * A object model of a scope.
+ *
+ * @author Fabio Simeoni
+ *
+ */
+public class ContextBean {
+
+ /**
+ * Scope separators used in linear syntax.
+ */
+ protected static String separator = "/";
+
+ /**
+ * Scope types *
+ */
+ public static enum Type implements Comparable {VRE,VO,INFRASTRUCTURE}
+
+ /**
+ * The name of the scope.
+ */
+ private String name;
+
+ /**
+ * The type of the scope.
+ */
+ private Type type;
+
+ /**
+ * The enclosing scope, if any.
+ */
+ private ContextBean enclosingScope;
+
+
+ /**
+ * Returns the name of the scope.
+ * @return the name
+ */
+ public String name() {
+ return name;
+ }
+
+ /**
+ * Returns true
if the scope has a given {@link Type}.
+ * @param type the type
+ * @return true
if the scope has the given type, false
otherwise
+ */
+ public boolean is(Type type) {
+ return this.type.equals(type);
+ }
+
+ /**
+ * Returns the {@link Type} of the scope.
+ * @return the type
+ */
+ public Type type() {
+ return type;
+ }
+
+ /**
+ * Returns the enclosing scope, if any.
+ * @return the enclosing scope, or null
if the scope is top-level
+ */
+ public ContextBean enclosingScope() {
+ return enclosingScope;
+ }
+
+ public ContextBean(String scope) throws IllegalArgumentException {
+
+ String[] components=scope.split(separator);
+
+ if (components.length<2 || components.length>4)
+ throw new IllegalArgumentException("scope "+scope+" is malformed");
+
+ if(components.length>3) {
+ this.name=components[3];
+ this.enclosingScope = new ContextBean(separator+components[1]+separator+components[2]);
+ this.type=Type.VRE;
+ }
+ else if (components.length>2) {
+ this.name=components[2];
+ this.enclosingScope=new ContextBean(separator+components[1]);
+ this.type=Type.VO;
+ }
+ else {
+ this.name=components[1];
+ this.type=Type.INFRASTRUCTURE;
+ }
+
+ }
+
+ /**
+ * Returns the linear expression of the scope.
+ */
+ public String toString() {
+ return is(Type.INFRASTRUCTURE)?separator+name():
+ enclosingScope().toString()+separator+name();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((enclosingScope == null) ? 0 : enclosingScope.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + ((type == null) ? 0 : type.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ContextBean other = (ContextBean) obj;
+ if (enclosingScope == null) {
+ if (other.enclosingScope != null)
+ return false;
+ } else if (!enclosingScope.equals(other.enclosingScope))
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (type != other.type)
+ return false;
+ return true;
+ }
+
+
+}
diff --git a/src/main/java/org/gcube/common/security/GCubeJWTObject.java b/src/main/java/org/gcube/common/security/GCubeJWTObject.java
deleted file mode 100644
index 8f38386..0000000
--- a/src/main/java/org/gcube/common/security/GCubeJWTObject.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package org.gcube.common.security;
-
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.gcube.com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import org.gcube.com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class GCubeJWTObject {
-
- protected final static List MINIMAL_ROLES = Arrays.asList("Member");
-
- @JsonProperty("aud")
- private String context;
-
- @JsonProperty("resource_access")
- private Map contextAccess = new HashMap<>();
-
- @JsonProperty("preferred_username")
- private String username;
-
- @JsonProperty("given_name")
- private String firstName;
-
- @JsonProperty("family_name")
- private String lastName;
-
- @JsonProperty("clientId")
- private String clientId;
-
- //"name", as the client pretty name, e.g. Catalogue for gcat, Workspace for storage-hub
- @JsonProperty("name")
- private String clientName;
-
- //username of the user who requested such client
- @JsonProperty("contact_person")
- private String contactPerson;
-
- //the name of the organisation / community using such client. D4Science will be used for internal clients.
- @JsonProperty("contact_organisation")
- private String contactOrganisation;
-
- private static final String INTERNAL_CLIENT_ORGANISATION_NAME = "D4Science";
-
- @JsonProperty("email")
- private String email;
- public List getRoles(){
- return contextAccess.get(this.context) == null ? MINIMAL_ROLES : contextAccess.get(this.context).roles;
- }
-
- public String getContext() {
- try {
- return URLDecoder.decode(context, StandardCharsets.UTF_8.toString());
- }catch (UnsupportedEncodingException e) {
- return context;
- }
- }
-
- public String getUsername() {
- return username;
- }
- public boolean isExternalService() {
- return contactOrganisation != null && contactOrganisation.equals(INTERNAL_CLIENT_ORGANISATION_NAME);
- }
-
- public String getFirstName() {
- return firstName;
- }
- public String getLastName() {
- return lastName;
- }
- public String getEmail() {
- return email;
- }
- @Override
- public String toString() {
- return "GcubeJwt [context=" + getContext() + ", roles=" + getRoles() + ", username=" + username
- + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]";
- }
-
-
- public String getClientName() {
- return clientName;
- }
-
- public String getContactPerson() {
- return contactPerson;
- }
-
- public String getContactOrganisation() {
- return contactOrganisation;
- }
-
-
-
- public static class Roles {
-
- @JsonProperty("roles")
- List roles = new ArrayList<>();
-
- }
-
-}
-
diff --git a/src/main/java/org/gcube/common/security/providers/ClientIDManager.java b/src/main/java/org/gcube/common/security/providers/ClientIDManager.java
deleted file mode 100644
index 1210cbf..0000000
--- a/src/main/java/org/gcube/common/security/providers/ClientIDManager.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.gcube.common.security.providers;
-
-import org.gcube.common.keycloak.KeycloakClientFactory;
-import org.gcube.common.keycloak.model.TokenResponse;
-import org.gcube.common.security.secrets.JWTSecret;
-import org.gcube.common.security.secrets.Secret;
-
-/**
- * @author Luca Frosini (ISTI - CNR)
- */
-public class ClientIDManager implements RenewalProvider {
-
- protected final String clientID;
- protected final String clientSecret;
-
- public ClientIDManager(String clientID, String clientSecret) {
- this.clientID = clientID;
- this.clientSecret = clientSecret;
- }
-
- public Secret getSecret() throws Exception {
- TokenResponse tokenResponse = KeycloakClientFactory.newInstance().queryUMAToken(clientID, clientSecret, null);
-
- JWTSecret jwtSecret = new JWTSecret(tokenResponse.getAccessToken());
- jwtSecret.setRenewalProvider(this);
-
- jwtSecret.setTokenResponse(tokenResponse);
-
- return jwtSecret;
- }
-
- public Secret getSecret(String context) throws Exception {
- TokenResponse tokenResponse = KeycloakClientFactory.newInstance().queryUMAToken(clientID, clientSecret, context, null);
-
- JWTSecret jwtSecret = new JWTSecret(tokenResponse.getAccessToken());
- jwtSecret.setRenewalProvider(this);
-
- jwtSecret.setTokenResponse(tokenResponse);
-
- return jwtSecret;
- }
-
- @Override
- public Secret renew() throws Exception {
- return getSecret();
- }
-
-}
diff --git a/src/main/java/org/gcube/common/security/providers/RenewalProvider.java b/src/main/java/org/gcube/common/security/providers/RenewalProvider.java
deleted file mode 100644
index de5b760..0000000
--- a/src/main/java/org/gcube/common/security/providers/RenewalProvider.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.gcube.common.security.providers;
-
-import org.gcube.common.security.secrets.Secret;
-
-/**
- * @author Luca Frosini (ISTI - CNR)
- */
-public interface RenewalProvider {
-
- public Secret renew() throws Exception;
-}
diff --git a/src/main/java/org/gcube/common/security/secrets/AccessTokenSecret.java b/src/main/java/org/gcube/common/security/secrets/AccessTokenSecret.java
deleted file mode 100644
index cc5deca..0000000
--- a/src/main/java/org/gcube/common/security/secrets/AccessTokenSecret.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.gcube.common.security.secrets;
-
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
-import org.gcube.common.security.GCubeJWTObject;
-import org.gcube.common.security.Owner;
-
-public class AccessTokenSecret extends Secret {
-
- private String encodedAccessToken;
-
- protected Owner owner;
- protected String context;
-
-
- private boolean initialised = false;
-
- public AccessTokenSecret(String encodedAccessToken) {
- this.encodedAccessToken = encodedAccessToken;
- }
-
- @Override
- public Owner getOwner() {
- init();
- return this.owner;
- }
-
- @Override
- public String getContext() {
- init();
- return this.context;
- }
-
- @Override
- public Map getHTTPAuthorizationHeaders() {
- Map authorizationHeaders = new HashMap<>();
- authorizationHeaders.put("Authorization", "Bearer " + this.encodedAccessToken.getBytes());
- return authorizationHeaders;
-
- }
-
- protected String getEncodedAccessToken() {
- return encodedAccessToken;
- }
-
- @Override
- public boolean isExpired() {
- return false;
- }
-
- @Override
- public boolean isRefreshable() {
- return false;
- }
-
- private synchronized void init() {
- if (!initialised)
- try {
-
- String realAccessTokenEncoded = encodedAccessToken.split("\\.")[1];
-
- String decodedAccessPart = new String(Base64.getDecoder().decode(realAccessTokenEncoded.getBytes()));
-
- ObjectMapper objectMapper = new ObjectMapper();
- GCubeJWTObject obj = objectMapper.readValue(decodedAccessPart, GCubeJWTObject.class);
- owner = new Owner(obj.getUsername(), obj.getRoles(), obj.getEmail(), obj.getFirstName(), obj.getLastName(), obj.isExternalService());
- owner.setClientName(obj.getClientName());
- owner.setContactOrganisation(obj.getContactOrganisation());
- owner.setClientName(obj.getClientName());
- context = obj.getContext();
- initialised = true;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- }
-
-}
diff --git a/src/main/java/org/gcube/common/security/secrets/GCubeSecret.java b/src/main/java/org/gcube/common/security/secrets/GCubeSecret.java
deleted file mode 100644
index ca5e68c..0000000
--- a/src/main/java/org/gcube/common/security/secrets/GCubeSecret.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.gcube.common.security.secrets;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.regex.Pattern;
-
-import org.gcube.common.authorization.client.Constants;
-import org.gcube.common.authorization.library.AuthorizationEntry;
-import org.gcube.common.authorization.library.ClientType;
-import org.gcube.common.security.Owner;
-
-/**
- * @author Luca Frosini (ISTI - CNR)
- */
-public class GCubeSecret extends Secret {
-
- public static final String GCUBE_TOKEN_REGEX = "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}-[a-fA-F0-9]{8,9}){1}$";
-
- private String gcubeToken;
- private Owner owner;
- private String context;
-
- public GCubeSecret(String gcubeToken) {
- Objects.requireNonNull(gcubeToken);
- if(!Pattern.matches(GCubeSecret.GCUBE_TOKEN_REGEX, gcubeToken))
- throw new RuntimeException("The GUCBE token must comply with the regex " + GCUBE_TOKEN_REGEX);
- this.gcubeToken = gcubeToken;
- }
-
- private void init() throws Exception{
- AuthorizationEntry authorizationEntry = Constants.authorizationService().get(gcubeToken);
- this.owner = new Owner(authorizationEntry.getClientInfo().getId(),
- authorizationEntry.getClientInfo().getRoles(), authorizationEntry.getClientInfo().getType()!=ClientType.USER);
- this.context = authorizationEntry.getContext();
- }
-
-
- @Override
- public Owner getOwner() {
- if (Objects.isNull(owner))
- try {
- init();
- } catch (Exception e) {
- throw new RuntimeException("error retrieving context",e);
- }
-
- return owner;
- }
-
- @Override
- public String getContext() {
- if (Objects.isNull(context))
- try {
- init();
- } catch (Exception e) {
- throw new RuntimeException("error retrieving context",e);
- }
-
- return context;
- }
-
- @Override
- public Map getHTTPAuthorizationHeaders() {
- Map authorizationHeaders = new HashMap<>();
- authorizationHeaders.put(org.gcube.common.authorization.client.Constants.TOKEN_HEADER_ENTRY, gcubeToken);
- return authorizationHeaders;
- }
-
- @Override
- public boolean isExpired() {
- return false;
- }
-
- @Override
- public boolean isRefreshable() {
- return false;
- }
-
-}
diff --git a/src/main/java/org/gcube/common/security/secrets/JWTSecret.java b/src/main/java/org/gcube/common/security/secrets/JWTSecret.java
deleted file mode 100644
index d093af4..0000000
--- a/src/main/java/org/gcube/common/security/secrets/JWTSecret.java
+++ /dev/null
@@ -1,164 +0,0 @@
-package org.gcube.common.security.secrets;
-
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
-import org.gcube.common.keycloak.KeycloakClientFactory;
-import org.gcube.common.keycloak.model.AccessToken;
-import org.gcube.common.keycloak.model.ModelUtils;
-import org.gcube.common.keycloak.model.RefreshToken;
-import org.gcube.common.keycloak.model.TokenResponse;
-import org.gcube.common.keycloak.model.util.Time;
-import org.gcube.common.security.GCubeJWTObject;
-import org.gcube.common.security.Owner;
-import org.gcube.common.security.providers.RenewalProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * @author Luca Frosini (ISTI - CNR)
- */
-public class JWTSecret extends Secret {
-
- private static final Logger logger = LoggerFactory.getLogger(JWTSecret.class);
-
- /**
- * The interval of time expressed in milliseconds used as guard to refresh the token before that it expires .
- * TimeUnit has been used to in place of just
- * using the number to have a clearer code
- */
- public static final long TOLERANCE = TimeUnit.MILLISECONDS.toMillis(200);
-
- protected String jwtToken;
-
- protected AccessToken accessToken;
- protected TokenResponse tokenResponse;
- protected RenewalProvider renewalProvider;
- protected Owner owner;
- protected String context;
-
- protected boolean initialised = false;
-
- public JWTSecret(String jwtToken) {
- this.jwtToken = jwtToken;
- }
-
- private String getTokenString() {
- try {
- boolean expired = false;
- getAccessToken();
-
- if(Time.currentTimeMillis()>=(accessToken.getExp()-TOLERANCE)) {
- expired = true;
- if(tokenResponse!=null) {
- try {
- KeycloakClientFactory.newInstance().refreshToken(this.getOwner().getId(), tokenResponse);
- expired = false;
- }catch (Exception e) {
- logger.warn("Unable to refresh the token with RefreshToken. Going to try to renew it if possible.", e);
- }
- }
- }
-
- if(expired && renewalProvider!=null) {
- try {
- JWTSecret renewed = (JWTSecret) renewalProvider.renew();
- this.jwtToken = renewed.jwtToken;
- this.accessToken = getAccessToken();
- }catch (Exception e) {
- logger.warn("Unable to renew the token with the RenewalProvider. I'll continue using the old token.", e);
- }
- }
- }catch (Exception e) {
- logger.error("Unexpected error in the procedure to evaluate/refresh the current token. I'll continue using the old token.", e);
- }
- return jwtToken;
- }
-
-
- protected AccessToken getAccessToken() {
- if(accessToken==null) {
- String realUmaTokenEncoded = jwtToken.split("\\.")[1];
- String realUmaToken = new String(Base64.getDecoder().decode(realUmaTokenEncoded.getBytes()));
- ObjectMapper mapper = new ObjectMapper();
- try {
- accessToken = mapper.readValue(realUmaToken, AccessToken.class);
- }catch(Exception e){
- logger.error("Error parsing JWT token",e);
- throw new RuntimeException("Error parsing JWT token", e);
- }
- }
- return accessToken;
- }
-
- private synchronized void init() {
- if (!initialised)
- try {
- ObjectMapper objectMapper = new ObjectMapper();
- String accessTokenString = objectMapper.writeValueAsString(getAccessToken());
- GCubeJWTObject obj = objectMapper.readValue(accessTokenString, GCubeJWTObject.class);
- Owner owner = new Owner(obj.getUsername(), obj.getRoles(), obj.getEmail(), obj.getFirstName(), obj.getLastName(), obj.isExternalService());
- owner.setClientName(obj.getClientName());
- owner.setContactOrganisation(obj.getContactOrganisation());
- owner.setClientName(obj.getClientName());
- context = obj.getContext();
- initialised = true;
- } catch (Exception e) {
- throw new RuntimeException();
- }
-
- }
-
- @Override
- public Owner getOwner() {
- init();
- return this.owner;
- }
-
- @Override
- public String getContext() {
- init();
- return this.context;
- }
-
- @Override
- public Map getHTTPAuthorizationHeaders() {
- Map authorizationHeaders = new HashMap<>();
- authorizationHeaders.put("Authorization", "Bearer " + getTokenString());
- return authorizationHeaders;
- }
-
- public void setRenewalProvider(RenewalProvider renewalProvider) {
- this.renewalProvider = renewalProvider;
- }
-
- public void setTokenResponse(TokenResponse tokenResponse) {
- this.tokenResponse = tokenResponse;
- }
-
- protected boolean isExpired(AccessToken accessToken) {
- return Time.currentTimeMillis()>accessToken.getExp();
- }
-
- @Override
- public boolean isExpired() {
- return isExpired(getAccessToken());
- }
-
- @Override
- public boolean isRefreshable() {
- if(tokenResponse!=null) {
- try {
- RefreshToken refreshToken = ModelUtils.getRefreshTokenFrom(tokenResponse);
- return isExpired(refreshToken);
- } catch (Exception e) {
- return false;
- }
- }
- return false;
- }
-
-}
\ No newline at end of file
diff --git a/src/main/java/org/gcube/common/security/secrets/Secret.java b/src/main/java/org/gcube/common/security/secrets/Secret.java
index 48c6668..7db3898 100644
--- a/src/main/java/org/gcube/common/security/secrets/Secret.java
+++ b/src/main/java/org/gcube/common/security/secrets/Secret.java
@@ -14,7 +14,7 @@ public abstract class Secret {
public abstract String getContext();
public abstract Map getHTTPAuthorizationHeaders();
-
+
public abstract boolean isExpired();
public abstract boolean isRefreshable();
diff --git a/src/main/java/org/gcube/common/security/secrets/SecretUtility.java b/src/main/java/org/gcube/common/security/secrets/SecretUtility.java
deleted file mode 100644
index e8cf4cf..0000000
--- a/src/main/java/org/gcube/common/security/secrets/SecretUtility.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.gcube.common.security.secrets;
-
-import java.util.regex.Pattern;
-
-/**
- * @author Luca Frosini (ISTI - CNR)
- */
-public class SecretUtility {
-
- public static final String UUID_REGEX = "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}-[a-fA-F0-9]{8,9}){1}$";
-
- public static Secret getSecretByTokenString(String token) {
- if(Pattern.matches(UUID_REGEX, token)) {
- return new GCubeSecret(token);
- }else {
- return new JWTSecret(token);
- }
- }
-
-}