Compare commits

...

22 Commits

Author SHA1 Message Date
Rahul Sharma
f203d9418c Fixing build 2020-11-25 21:18:05 -05:00
Rahul Sharma
45340227b3 Updated CacheConfiguration:
- to add a LongLived cache.
- change getCache to use Qualifier

Remove the CacheType
2020-11-25 20:26:14 -05:00
ralphlee3
b84cb8ee44 Merge pull request #6 from Telecominfraproject/PortalUserRole-RO-updates
Adding read only roles to PortalUserRole
2020-11-25 14:59:27 -05:00
ralphlee
21b2cfb58b Adding read only roles to PortalUserRole 2020-11-23 13:22:12 -05:00
Dmitry Toptygin
4ed520cd98 added base-tx-tests project with the TransactionManager for use in unit tests 2020-11-17 17:43:44 -05:00
Mike Hansen
c7deb7e74d WIFI-1068: Cloud Backend: Extend or replace existing base_model CountryCode 2020-11-16 13:54:57 -05:00
ralphlee3
a14a578c31 Merge pull request #5 from Telecominfraproject/WIFI-1054-rs256-decoding
* Adding RS256 decoding and JWK support
2020-11-13 10:41:58 -05:00
ralphlee
92e48ac120 Merge branch 'master' of github.com:Telecominfraproject/wlan-cloud-base into WIFI-1054-rs256-decoding 2020-11-13 10:40:59 -05:00
ralphlee
e2c1051717 Bringing jwksLocation into constructor Auth0Provider 2020-11-09 13:58:34 -05:00
Lynn Shi
5bf56e347a Add TransactionSynchronizationManager handler in BaseRemoteTest 2020-11-09 13:26:22 -05:00
ralphlee
b4dd6aa56b Adding refreshToken and id_token to WebToken transactions 2020-11-09 11:37:09 -05:00
ralphlee
26ad46c98d TokenHelper cleanup 2020-11-07 00:02:50 -05:00
ralphlee
0f6693b846 Code cleanup 2020-11-06 17:11:10 -05:00
ralphlee
c2220b8a8f Combine similar try/catch exceptions 2020-11-06 16:28:04 -05:00
ralphlee
aed826fb3a Defining jwks location with env property or default 2020-11-06 16:19:46 -05:00
ralphlee
41b92eb62e Change claims keys to constants 2020-11-06 14:29:42 -05:00
ralphlee
3e939d92ce Code cleanup 2020-11-06 12:05:19 -05:00
ralphlee
eb1a46c745 Updated Auth0TokenHelper to match provider 2020-11-06 11:55:40 -05:00
ralphlee
58573cd96e Adding RS256 decoding and JWK support 2020-11-06 11:30:24 -05:00
ralphlee
1af8228dc4 Adding SourceSelection classes 2020-10-20 15:31:49 -04:00
Dmitry Toptygin
3642cbcf9a added externallyVisiblePort, externallyVisibleHostName, externallyVisibleIpAddress to ConnectorProperties so that we can better deal with port mappers and external load balancers 2020-10-07 13:04:36 -04:00
AkshayJagadish-ne
236cf4f9c2 WIFI-846: Add component version and commit hash to application ping (#4)
* WIFI-846: Add component version and commit hash to application ping
response

* WIFI-846: Add component version and commit hash to application ping
response
2020-10-05 21:20:31 -04:00
26 changed files with 1173 additions and 228 deletions

View File

@@ -47,6 +47,7 @@
<module>../base-hierarchical-datastore</module>
<module>../base-jdbc</module>
<module>../base-jdbc-tests</module>
<module>../base-tx-tests</module>
<module>../base-cassandra</module>
<module>../base-cassandra-tests</module>
<module>../base-job</module>

View File

@@ -39,7 +39,13 @@
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>0.3</version>
<version>3.11.0</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>jwks-rsa</artifactId>
<version>0.14.0</version>
</dependency>
</dependencies>

View File

@@ -5,6 +5,7 @@ import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
@@ -13,16 +14,19 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.context.annotation.Primary;
@Configuration
public class CacheConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(CacheConfiguration.class);
@Autowired
ApplicationContext applicationContext;
ApplicationContext applicationContext;
@Bean
@Primary
@Qualifier("cacheManager")
public CacheManager cacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
Caffeine < Object, Object > cb = caffeineCacheBuilder();
@@ -37,17 +41,12 @@ public class CacheConfiguration {
.initialCapacity(100)
.maximumSize(10000)
.expireAfterAccess(10, TimeUnit.MINUTES)
.weakKeys()
// .weakKeys()
.recordStats();
}
public Cache getCache(CacheType cacheType, String cacheName){
CacheManager cm = applicationContext.getBean(CacheManager.class, cacheType.toString());
return cm.getCache(cacheName);
}
@Bean
@Qualifier("cacheManagerShortLived")
public CacheManager cacheManagerShortLived() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
Caffeine < Object, Object > cb = caffeineCacheBuilderShortLived();
@@ -62,8 +61,33 @@ public class CacheConfiguration {
.initialCapacity(100)
.maximumSize(10000)
.expireAfterAccess(1, TimeUnit.MINUTES)
.weakKeys()
// .weakKeys()
.recordStats();
}
}
@Bean
@Qualifier("cacheManagerLongLived")
public CacheManager cacheManagerLongLived() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
Caffeine<Object, Object> cb = caffeineCacheBuilderLongLived();
cacheManager.setCaffeine(cb);
LOG.info("Configured cache manager with expiry {}", cb);
return cacheManager;
}
Caffeine<Object, Object> caffeineCacheBuilderLongLived() {
return Caffeine.newBuilder()
.initialCapacity(100)
.maximumSize(10000)
.expireAfterAccess(2, TimeUnit.HOURS)
// .weakKeys() Do not use weak keys - garbage collection will remove our values when we still want them
.recordStats();
}
public Cache getCache(String cacheName, String cacheManagerQualifier) {
CacheManager cm = applicationContext.getBeansOfType(CacheManager.class).get(cacheManagerQualifier);
return cm.getCache(cacheName);
}
}

View File

@@ -1,5 +0,0 @@
package com.telecominfraproject.wlan.core.server.cache;
public enum CacheType {
}

View File

@@ -0,0 +1,44 @@
package com.telecominfraproject.wlan.core.server.container;
import java.io.InputStream;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CommitProperties {
private static final Logger LOG = LoggerFactory.getLogger(CommitProperties.class);
private static final String PROP_FILE = "commit.properties";
private final Properties prop = new Properties();
private final String date;
private final String commitId;
private final String version;
public CommitProperties() {
loadStream(prop);
this.date = prop.getProperty("date", "");
this.commitId = prop.getProperty("commitId", "");
this.version = prop.getProperty("projectVersion", "");
}
public String getCommitDate() {
return date;
}
public String getCommitID() {
return commitId;
}
public String getProjectVersion() {
return version;
}
private void loadStream(final Properties prop) {
try (final InputStream inputStream = getClass().getClassLoader().getResourceAsStream(PROP_FILE)) {
prop.load(inputStream);
} catch (final Exception e) {
LOG.info("Properties file not present");
}
}
}

View File

@@ -8,10 +8,51 @@ import java.net.InetAddress;
*/
public interface ConnectorProperties {
int getExternalPort();
/**
* @return port on which this server listens for internal API requests
*/
int getInternalPort();
InetAddress getExternalIpAddress();
InetAddress getInternalIpAddress();
String getExternalHostName();
/**
* @return host on which this server listens for internal API requests
*/
String getInternalHostName();
/**
* @return ip address on which this server listens for internal API requests
*/
InetAddress getInternalIpAddress();
/**
* @return port on which this server listens for API requests from the outside world
*/
int getExternalPort();
/**
* @return host on which this server listens for API requests from the outside world
*/
String getExternalHostName();
/**
* @return ip address on which this server listens for API requests from the outside world
*/
InetAddress getExternalIpAddress();
/**
* @return port which this server advertises to clients so that they can send API requests from the outside world, could be a load-balancer port, or a kubernetes-remapped port
*/
int getExternallyVisiblePort();
/**
* @return host which this server advertises to clients so that they can send API requests from the outside world, could be a load-balancer host, or a kubernetes-remapped host
*/
String getExternallyVisibleHostName();
/**
* @return ip address which this server advertises to clients so that they can send API requests from the outside world, could be a load-balancer ip address, or a kubernetes-remapped ip address
*/
InetAddress getExternallyVisibleIpAddress();
}

View File

@@ -17,14 +17,21 @@ public class ConnectorPropertiesImpl implements ConnectorProperties {
private static final Logger LOG = LoggerFactory.getLogger(ConnectorProperties.class);
private final int externalPort;
//host and port on which this server listens for internal API requests
private final int internalPort;
private final InetAddress externalIpAddress;
private final String internalHostName;
private final InetAddress internalIpAddress;
//host and port on which this server listens for API requests from the outside world
private final int externalPort;
private final String externalHostName;
private final String internalHostName;
private final InetAddress externalIpAddress;
//host and port which this server advertises to clients so that they can send API requests from the outside world, could be a load-balancer host and port, or a kubernetes-remapped host/port
private final int externallyVisiblePort;
private final String externallyVisibleHostName;
private final InetAddress externallyVisibleIpAddress;
public ConnectorPropertiesImpl(Environment environment){
int _externalPort = Integer.parseInt(environment.getProperty("server.port").trim());
@@ -72,26 +79,46 @@ public class ConnectorPropertiesImpl implements ConnectorProperties {
_internalHostName = _internalIpAddress.getCanonicalHostName();
}
//Populate externally-visible properties, if any
int _externallyVisiblePort = Integer.parseInt(environment.getProperty("tip.wlan.externallyVisiblePort", "0").trim());
if(_externallyVisiblePort == 0) {
_externallyVisiblePort = _externalPort;
}
String _externallyVisibleHostName = environment.getProperty("tip.wlan.externallyVisibleHostName");
if(_externallyVisibleHostName == null || _externallyVisibleHostName.trim().isEmpty()) {
_externallyVisibleHostName = _externalHostName;
}
InetAddress _externallyVisibleIpAddress;
String externallyVisibleIpAddrStr = environment.getProperty("tip.wlan.externallyVisibleIpAddress");
if(externallyVisibleIpAddrStr == null) {
_externallyVisibleIpAddress = _externalIpAddress;
} else {
try {
_externallyVisibleIpAddress = InetAddress.getByName(externallyVisibleIpAddrStr.trim());
} catch (UnknownHostException e) {
throw new ConfigurationException("Cannot get externally visible address of the system", e);
}
}
this.externalIpAddress = _externalIpAddress;
this.externalHostName = _externalHostName;
this.externalPort = _externalPort;
this.internalIpAddress = _internalIpAddress;
this.internalHostName = _internalHostName;
this.internalPort = _internalPort;
this.externallyVisibleIpAddress = _externallyVisibleIpAddress;
this.externallyVisibleHostName = _externallyVisibleHostName;
this.externallyVisiblePort = _externallyVisiblePort;
LOG.info("connectorProperties {}", this);
}
public ConnectorPropertiesImpl(String externalHostName, InetAddress externalIpAddress, int externalPort,
String internalHostName, InetAddress internalIpAddress, int internalPort) {
this.externalIpAddress = externalIpAddress;
this.externalHostName = externalHostName;
this.externalPort = externalPort;
this.internalIpAddress = internalIpAddress;
this.internalHostName = internalHostName;
this.internalPort = internalPort;
}
public int getExternalPort() {
return externalPort;
@@ -117,24 +144,24 @@ public class ConnectorPropertiesImpl implements ConnectorProperties {
return internalHostName;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("ConnectorProperties [externalHostName=");
builder.append(externalHostName);
builder.append(", externalIpAddress=");
builder.append(externalIpAddress);
builder.append(", externalPort=");
builder.append(externalPort);
builder.append(", internalHostName=");
builder.append(internalHostName);
builder.append(", internalIpAddress=");
builder.append(internalIpAddress);
builder.append(", internalPort=");
builder.append(internalPort);
builder.append("]");
return builder.toString();
public int getExternallyVisiblePort() {
return externallyVisiblePort;
}
public String getExternallyVisibleHostName() {
return externallyVisibleHostName;
}
public InetAddress getExternallyVisibleIpAddress() {
return externallyVisibleIpAddress;
}
@Override
public String toString() {
return String.format(
"ConnectorPropertiesImpl [internalPort=%s, internalHostName=%s, internalIpAddress=%s, externalPort=%s, externalHostName=%s, externalIpAddress=%s, externallyVisiblePort=%s, externallyVisibleHostName=%s, externallyVisibleIpAddress=%s]",
internalPort, internalHostName, internalIpAddress, externalPort, externalHostName, externalIpAddress,
externallyVisiblePort, externallyVisibleHostName, externallyVisibleIpAddress);
}
}

View File

@@ -33,6 +33,12 @@ public abstract class ServletContainerCustomizer implements WebServerFactoryCust
@Bean ConnectorProperties connectorProperties(){
return new ConnectorPropertiesImpl(appContext.getEnvironment());
}
@Bean
CommitProperties commitProperties(){
return new CommitProperties();
}
private static final Logger LOG = LoggerFactory.getLogger(ServletContainerCustomizer.class);

View File

@@ -7,6 +7,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.telecominfraproject.wlan.core.server.container.CommitProperties;
import com.telecominfraproject.wlan.core.server.container.ConnectorProperties;
@@ -21,19 +22,26 @@ public class PingController {
private static final Logger LOG = LoggerFactory.getLogger(PingController.class);
@Autowired private ApplicationContext applicationContext;
@Autowired private ConnectorProperties connectorProperties;
@Autowired private CommitProperties commitProperties;
@GetMapping("/ping")
public @ResponseBody PingResponse ping() {
PingResponse ret = new PingResponse(
applicationContext.getStartupDate(),
System.currentTimeMillis(),
applicationContext.getEnvironment().getProperty("app.name"),
applicationContext.getEnvironment().getProperty("elb", connectorProperties.getExternalHostName()));
applicationContext.getEnvironment().getProperty("elb", connectorProperties.getExternalHostName()),
commitProperties.getCommitID(),
commitProperties.getCommitDate(),
commitProperties.getProjectVersion()
);
LOG.debug("ping: {} / {}", ret.getStartupTime(), ret.getCurrentTime());
return ret;
}
}

View File

@@ -13,7 +13,13 @@ public class PingResponse extends BaseJsonModel {
private long currentTime;
private String applicationName;
private String hostName;
private String commitID;
private String commitDate;
private String projectVersion;
protected PingResponse()
{
super();
@@ -23,7 +29,14 @@ public class PingResponse extends BaseJsonModel {
this.startupTime = startupTime;
this.currentTime = currentTime;
this.applicationName = applicationName;
this.hostName = hostName;
this.hostName = hostName;
}
public PingResponse(long startupTime, long currentTime, String applicationName, String hostName, String commitID, String commitDate, String projectVersion){
this(startupTime, currentTime, applicationName, hostName);
this.commitID = commitID;
this.commitDate = commitDate;
this.projectVersion = projectVersion;
}
public long getStartupTime() {
@@ -39,5 +52,18 @@ public class PingResponse extends BaseJsonModel {
public String getHostName() {
return hostName;
}
public String getCommitID() {
return commitID;
}
public String getCommitDate() {
return commitDate;
}
public String getProjectVersion() {
return projectVersion;
}
}

View File

@@ -871,21 +871,23 @@ public abstract class WebSecurityConfig extends WebSecurityConfigurerAdapter {
protected Auth0AuthenticationProvider createAuth0AuthenticationProvider(int providerIndex) throws Exception {
String clientId;
String clientSecret;
String securedRoute;
String issuer;
String accessTypeValue;
String jwksLocation;
if (0 == providerIndex) {
clientId = environment.getProperty("tip.wlan.auth0.clientId", DEFAULT_AUTH0_PROPERTY);
clientSecret = environment.getProperty("tip.wlan.auth0.clientSecret", DEFAULT_AUTH0_PROPERTY);
securedRoute = environment.getProperty("tip.wlan.auth0.securedRoute", DEFAULT_AUTH0_PROPERTY);
issuer = environment.getProperty("tip.wlan.auth0.issuerUri", DEFAULT_AUTH0_PROPERTY);
accessTypeValue = environment.getProperty("tip.wlan.auth0.accessType",
getDefaultAccessType(providerIndex));
jwksLocation = environment.getProperty("tip.wlan.auth0.jwksLocation", DEFAULT_AUTH0_PROPERTY);
} else {
clientId = environment.getProperty("tip.wlan.auth0.clientId" + providerIndex);
clientSecret = environment.getProperty("tip.wlan.auth0.clientSecret" + providerIndex);
securedRoute = environment.getProperty("tip.wlan.auth0.securedRoute" + providerIndex,
DEFAULT_AUTH0_PROPERTY);
issuer = environment.getProperty("tip.wlan.auth0.issuer" + providerIndex);
accessTypeValue = environment.getProperty("tip.wlan.auth0.accessType" + providerIndex,
getDefaultAccessType(providerIndex));
jwksLocation = environment.getProperty("tip.wlan.auth0.jwksLocation" + providerIndex);
}
if (null == clientId) {
return null;
@@ -896,7 +898,8 @@ public abstract class WebSecurityConfig extends WebSecurityConfigurerAdapter {
Auth0AuthenticationProvider auth0Provider = new Auth0AuthenticationProvider(accessType);
auth0Provider.setClientId(clientId);
auth0Provider.setClientSecret(clientSecret);
auth0Provider.setSecuredRoute(securedRoute);
auth0Provider.setIssuer(issuer);
auth0Provider.setJwksLocation(jwksLocation);
auth0Provider.afterPropertiesSet();
LOG.info("Loaded configuration for auth0 provider {}", providerIndex);
return auth0Provider;

View File

@@ -1,9 +1,12 @@
package com.telecominfraproject.wlan.core.server.security.auth0;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.interfaces.RSAPublicKey;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
@@ -13,8 +16,20 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.util.ResourceUtils;
import com.auth0.jwk.Jwk;
import com.auth0.jwk.JwkException;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.telecominfraproject.wlan.core.server.security.AccessType;
import com.telecominfraproject.wlan.server.exceptions.ConfigurationException;
@@ -23,18 +38,21 @@ import com.telecominfraproject.wlan.server.exceptions.ConfigurationException;
* the userdetails in the authentication object
*
* @author Daniel Teixeira
* @author rlee
*/
public class Auth0AuthenticationProvider implements AuthenticationProvider, InitializingBean {
private static final Logger LOG = LoggerFactory.getLogger(Auth0AuthenticationProvider.class);
private ObjectMapper mapper = new ObjectMapper();
private JWTVerifier jwtVerifier = null;
private String clientSecret = null;
private String clientId = null;
private String securedRoute = null;
private String issuer = null;
private String jwksLocation = null;
private final AccessType accessType;
private static final AuthenticationException AUTH_ERROR = new Auth0TokenException("Authentication error occured");
public Auth0AuthenticationProvider(AccessType accessType) {
this.accessType = accessType;
}
@@ -42,35 +60,52 @@ public class Auth0AuthenticationProvider implements AuthenticationProvider, Init
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String token = ((Auth0JWTToken) authentication).getJwt();
LOG.trace("Auth0 trying to authenticate with token: {} ", token);
Map<String, Object> decoded;
try {
Auth0JWTToken tokenAuth = ((Auth0JWTToken) authentication);
decoded = jwtVerifier.verify(token);
LOG.trace("Decoded JWT token {}", decoded);
DecodedJWT jwt = JWT.decode(token);
String alg = jwt.getAlgorithm();
// Get jwks file
Jwk jwk = getJwk(jwt.getKeyId());
if (jwk == null) {
throw new JwkException("jwk could not be found");
}
Algorithm algorithm;
if (alg.equals("RS256")) {
// create RS256 key decoder
algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey(), null);
} else {
// create HS256 key decoder
algorithm = Algorithm.HMAC256(clientSecret);
}
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer(issuer)
.build();
jwt = verifier.verify(token);
LOG.trace("Decoded JWT token {}", jwt);
tokenAuth.setAuthenticated(true);
tokenAuth.setPrincipal(new Auth0UserDetails(decoded, this.accessType));
tokenAuth.setDetails(decoded);
tokenAuth.setPrincipal(new Auth0UserDetails(jwt, this.accessType));
tokenAuth.setDetails(jwt);
return authentication;
} catch (InvalidKeyException e) {
LOG.error("InvalidKeyException thrown while decoding JWT token", e);
} catch (JWTDecodeException e) {
LOG.error("JWTDecodeException thrown while decoding JWT token", e);
throw AUTH_ERROR;
} catch (NoSuchAlgorithmException e) {
LOG.error("NoSuchAlgorithmException thrown while decoding JWT token", e);
} catch (JWTVerificationException e) {
LOG.error("JWTVerificationException thrown while decoding JWT token", e);
throw AUTH_ERROR;
} catch (JwkException e) {
LOG.error("JwkException thrown while decoding JWT token", e);
throw AUTH_ERROR;
} catch (IllegalStateException e) {
LOG.error("IllegalStateException thrown while decoding JWT token", e);
throw AUTH_ERROR;
} catch (SignatureException e) {
LOG.debug("SignatureException thrown while decoding JWT token", e);
throw AUTH_ERROR;
} catch (IOException e) {
LOG.error("IOException thrown while decoding JWT token", e);
throw AUTH_ERROR;
}
}
@@ -79,21 +114,84 @@ public class Auth0AuthenticationProvider implements AuthenticationProvider, Init
}
public void afterPropertiesSet() throws Exception {
if ((clientSecret == null) || (clientId == null)) {
throw new ConfigurationException("Client secret or client id is not set for Auth0AuthenticationProvider");
if ((clientSecret == null) || (clientId == null) || (issuer == null)) {
throw new ConfigurationException("Client secret, client id, or issuer URI is not set for Auth0AuthenticationProvider");
}
if (securedRoute == null) {
throw new ConfigurationException("SecureRoute is not set for Auth0AuthenticationProvider");
}
jwtVerifier = new JWTVerifier(clientSecret, clientId);
}
public String getSecuredRoute() {
return securedRoute;
private Jwk getJwk(String keyId) {
try {
String jwksSource = getJwksString();
if (jwksSource == null) {
throw new FileNotFoundException("jwks could not be found");
}
List<Jwk> jwks = Lists.newArrayList();
@SuppressWarnings("unchecked")
List<Map<String, Object>> keys = (List<Map<String, Object>>) mapper.readValue(jwksSource, Map.class).get("keys");
for (Map<String, Object> values : keys) {
jwks.add(Jwk.fromValues(values));
}
if (keyId == null && jwks.size() == 1) {
return jwks.get(0);
}
if (keyId != null) {
for (Jwk jwk : jwks) {
if (keyId.equals(jwk.getId())) {
// Can only contain 1 matching jwk
return jwk;
}
}
}
} catch (JsonMappingException e) {
LOG.error("JsonMappingException thrown while decoding JWT token", e);
throw AUTH_ERROR;
} catch (JsonProcessingException e) {
LOG.error("JsonProcessingException thrown while decoding JWT token", e);
throw AUTH_ERROR;
} catch (FileNotFoundException e) {
LOG.error("FileNotFoundException thrown while decoding JWT token", e);
throw AUTH_ERROR;
}
return null;
}
public void setSecuredRoute(String securedRoute) {
this.securedRoute = securedRoute;
private String getJwksString() {
LOG.debug("Loading jwks from {}", jwksLocation);
String ret = null;
try {
Object jwksObj = ResourceUtils.getURL(jwksLocation).getContent();
if (jwksObj instanceof InputStream) {
ret = readFromInputStream((InputStream) jwksObj);
}
} catch (FileNotFoundException e) {
LOG.error("FileNotFoundException thrown while getting jwks", e);
throw AUTH_ERROR;
} catch (IOException e) {
LOG.error("IOException thrown while getting jwks", e);
throw AUTH_ERROR;
}
return ret;
}
private String readFromInputStream(InputStream inputStream) {
StringBuilder resultStringBuilder = new StringBuilder();
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = br.readLine()) != null) {
resultStringBuilder.append(line).append("\n");
}
} catch (IOException e) {
LOG.error("IOException thrown while getting jwks", e);
throw AUTH_ERROR;
}
return resultStringBuilder.toString();
}
public String getClientSecret() {
@@ -111,6 +209,22 @@ public class Auth0AuthenticationProvider implements AuthenticationProvider, Init
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getIssuer() {
return issuer;
}
public void setIssuer(String issuer) {
this.issuer = issuer;
}
public String getJwksLocation() {
return jwksLocation;
}
public void setJwksLocation(String jwksLocation) {
this.jwksLocation = jwksLocation;
}
/**
* Use to encode raw secret to Base 64 URL safe string

View File

@@ -2,7 +2,6 @@ package com.telecominfraproject.wlan.core.server.security.auth0;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -10,6 +9,7 @@ import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.telecominfraproject.wlan.core.server.security.AccessType;
import com.telecominfraproject.wlan.core.server.security.AuthProviderInfo;
@@ -24,42 +24,46 @@ public class Auth0UserDetails implements UserDetails, AuthProviderInfo {
private static final long serialVersionUID = 2058797193125711681L;
private Map<String, Object> details;
private DecodedJWT details;
private String username;
private boolean emailVerified = false;
private Collection<GrantedAuthority> authorities = null;
private final AccessType accessType;
private static final String EMAIL_CLAIM = "email";
private static final String EMAIL_VERIFIED_CLAIM = "email_verified";
private static final String NICKNAME_CLAIM = "nickname";
private static final String ROLES_CLAIM = "roles";
private static final Log LOGGER = LogFactory.getLog(Auth0UserDetails.class);
@SuppressWarnings("unchecked")
public Auth0UserDetails(Map<String, Object> map, AccessType accessType) {
public Auth0UserDetails(DecodedJWT jwt, AccessType accessType) {
this.accessType = accessType;
if (map.containsKey("email")) {
this.username = map.get("email").toString();
} else if (map.containsKey("username")) {
this.username = map.get("username").toString();
} else if (map.containsKey("user_id")) {
this.username = map.get("user_id").toString();
if (!jwt.getClaim(EMAIL_CLAIM).isNull()) {
this.username = jwt.getClaim(EMAIL_CLAIM).asString();
} else if (!jwt.getClaim(NICKNAME_CLAIM).isNull()) {
this.username = jwt.getClaim(NICKNAME_CLAIM).asString();
} else if (jwt.getId() != null) {
this.username = jwt.getId();
} else if (jwt.getSubject() != null) {
this.username = jwt.getSubject();
} else {
this.username = "UNKNOWN_USER";
}
if (map.containsKey("email")) {
this.emailVerified = Boolean.valueOf(map.get("email_verified").toString());
if (!jwt.getClaim(EMAIL_CLAIM).isNull()) {
this.emailVerified = Boolean.valueOf(jwt.getClaim(EMAIL_VERIFIED_CLAIM).toString());
}
// set authorities
authorities = new ArrayList<>();
if (map.containsKey("roles")) {
if (!jwt.getClaim(ROLES_CLAIM).isNull()) {
ArrayList<String> roles = null;
try {
roles = (ArrayList<String>) map.get("roles");
roles = (ArrayList<String>) jwt.getClaim(ROLES_CLAIM).asList(String.class);
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
}
} catch (java.lang.ClassCastException e) {
// e.printStackTrace();
LOGGER.error("Error in casting the roles object", e);
}
}
@@ -69,7 +73,7 @@ public class Auth0UserDetails implements UserDetails, AuthProviderInfo {
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
}
this.details = map;
this.details = jwt;
}
@@ -128,7 +132,11 @@ public class Auth0UserDetails implements UserDetails, AuthProviderInfo {
* otherwise
*/
public Object getAuth0Attribute(String attributeName) {
return details.get(attributeName);
if (details.getClaim(attributeName).isNull()) {
LOGGER.debug("No attribute was found : " + attributeName);
return null;
}
return details.getClaim(attributeName);
}
@Override

View File

@@ -1,21 +1,23 @@
package com.telecominfraproject.wlan.core.server.security.auth0.impl;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.security.interfaces.RSAPublicKey;
import java.util.Date;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import com.auth0.jwt.Algorithm;
import com.auth0.jwt.ClaimSet;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwk.Jwk;
import com.auth0.jwk.JwkException;
import com.auth0.jwk.JwkProvider;
import com.auth0.jwk.UrlJwkProvider;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.JwtSigner;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.telecominfraproject.wlan.core.server.security.auth0.Auth0TokenHelper;
@@ -25,26 +27,23 @@ public class Auth0TokenHelperImpl implements Auth0TokenHelper<Object>, Initializ
private static final Log Logger = LogFactory.getLog(Auth0TokenHelperImpl.class);
private String clientSecret = null;
private String clientId = null;
private String issuer = null;
@Override
public String generateToken(Object object, int expiration) {
String payload, token;
String token;
try {
JwtSigner jwtSigner = new JwtSigner();
payload = new ObjectMapper().writeValueAsString(object);
ClaimSet claimSet = new ClaimSet();
claimSet.setExp(expiration); // expire in 1 year
token = jwtSigner.encode(Algorithm.HS256, payload, "payload", new String(Base64.decodeBase64(clientSecret)), claimSet);
Algorithm hsEncoded = Algorithm.HMAC256(clientSecret);
token = JWT.create()
.withIssuer(issuer)
.withExpiresAt(new Date(expiration))
.withClaim("payload", new ObjectMapper().writeValueAsString(object))
.sign(hsEncoded);
} catch (JsonProcessingException e) {
throw new Auth0RuntimeException(e);
} catch (Exception e) {
throw new Auth0RuntimeException(e);
}
return token;
@@ -53,39 +52,43 @@ public class Auth0TokenHelperImpl implements Auth0TokenHelper<Object>, Initializ
@Override
public Object decodeToken(String token) {
JWTVerifier jwtVerifier = new JWTVerifier(clientSecret, clientId);
Map<String, Object> verify;
JwkProvider jwkProvider = new UrlJwkProvider(issuer);
try {
verify = jwtVerifier.verify(token);
String payload = (String) verify.get("$");
DecodedJWT jwt = JWT.decode(token);
String alg = jwt.getAlgorithm();
// Get jwk
Jwk jwk = jwkProvider.get(jwt.getKeyId());
Algorithm algorithm;
if (alg.equals("RS256")) {
// create RS256 key decoder
algorithm = Algorithm.RSA256((RSAPublicKey) jwk.getPublicKey(), null);
} else {
// create HS256 key decoder
algorithm = Algorithm.HMAC256(clientSecret);
}
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer(issuer)
.build();
jwt = verifier.verify(token);
@SuppressWarnings("unchecked")
Map<String, String> map = new ObjectMapper().readValue(payload, Map.class);
Map<String, String> map = new ObjectMapper().readValue(jwt.getPayload(), Map.class);
return map;
} catch (InvalidKeyException e) {
throw new Auth0RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
throw new Auth0RuntimeException(e);
} catch (IllegalStateException e) {
throw new Auth0RuntimeException(e);
} catch (SignatureException e) {
throw new Auth0RuntimeException(e);
} catch (IOException e) {
} catch (IllegalStateException|IOException|JwkException e) {
throw new Auth0RuntimeException(e);
}
}
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(clientSecret, "The client secret is not set for " + this.getClass());
Assert.notNull(clientId, "The client id is not set for " + this.getClass());
}
public String getClientSecret() {
@@ -96,12 +99,4 @@ public class Auth0TokenHelperImpl implements Auth0TokenHelper<Object>, Initializ
this.clientSecret = clientSecret;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
}

View File

@@ -1,49 +1,369 @@
package com.telecominfraproject.wlan.core.model.entity;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.telecominfraproject.wlan.core.model.json.JsonDeserializationUtils;
import com.telecominfraproject.wlan.core.model.extensibleenum.EnumWithId;
import com.telecominfraproject.wlan.core.model.json.BaseJsonModel;
public enum CountryCode {
public class CountryCode implements EnumWithId {
usa(0),
ca(1),
integration(1000),
UNSUPPORTED(-1);
private static final Logger LOG = LoggerFactory.getLogger(CountryCode.class);
private final int id;
private static final Map<Integer, CountryCode> ELEMENTS = new HashMap<>();
private static Object lock = new Object();
private static final Map<Integer, CountryCode> ELEMENTS = new ConcurrentHashMap<>();
private static final Map<String, CountryCode> ELEMENTS_BY_NAME = new ConcurrentHashMap<>();
private CountryCode(int id) {
this.id = id;
}
public static final CountryCode AD = new CountryCode(1, "AD"),
AE = new CountryCode(2, "AE"),
AF = new CountryCode(3, "AF"),
AG = new CountryCode(4, "AG"),
AI = new CountryCode(5, "AI"),
AL = new CountryCode(6, "AL"),
AM = new CountryCode(7, "AM"),
AO = new CountryCode(8, "AO"),
AQ = new CountryCode(9, "AQ"),
AR = new CountryCode(10, "AR"),
AS = new CountryCode(11, "AS"),
AT = new CountryCode(12, "AT"),
AU = new CountryCode(13, "AU"),
AW = new CountryCode(14, "AW"),
AX = new CountryCode(15, "AX"),
AZ = new CountryCode(16, "AZ"),
BA = new CountryCode(17, "BA"),
BB = new CountryCode(18, "BB"),
BD = new CountryCode(19, "BD"),
BE = new CountryCode(20, "BE"),
BF = new CountryCode(21, "BF"),
BG = new CountryCode(22, "BG"),
BH = new CountryCode(23, "BH"),
BI = new CountryCode(24, "BI"),
BJ = new CountryCode(25, "BJ"),
BL = new CountryCode(26, "BL"),
BM = new CountryCode(27, "BM"),
BN = new CountryCode(28, "BN"),
BO = new CountryCode(29, "BO"),
BQ = new CountryCode(30, "BQ"),
BR = new CountryCode(31, "BR"),
BS = new CountryCode(32, "BS"),
BT = new CountryCode(33, "BT"),
BV = new CountryCode(34, "BV"),
BW = new CountryCode(35, "BW"),
BY = new CountryCode(36, "BY"),
BZ = new CountryCode(37, "BZ"),
CA = new CountryCode(38, "CA"),
CC = new CountryCode(39, "CC"),
CD = new CountryCode(40, "CD"),
CF = new CountryCode(41, "CF"),
CG = new CountryCode(42, "CG"),
CH = new CountryCode(43, "CH"),
CI = new CountryCode(44, "CI"),
CK = new CountryCode(45, "CK"),
CL = new CountryCode(46, "CL"),
CM = new CountryCode(47, "CM"),
CN = new CountryCode(48, "CN"),
CO = new CountryCode(49, "CO"),
CR = new CountryCode(50, "CR"),
CU = new CountryCode(51, "CU"),
CV = new CountryCode(52, "CV"),
CW = new CountryCode(53, "CW"),
CX = new CountryCode(54, "CX"),
CY = new CountryCode(55, "CY"),
CZ = new CountryCode(56, "CZ"),
DE = new CountryCode(57, "DE"),
DJ = new CountryCode(58, "DJ"),
DK = new CountryCode(59, "DK"),
DM = new CountryCode(60, "DM"),
DO = new CountryCode(61, "DO"),
DZ = new CountryCode(62, "DZ"),
EC = new CountryCode(63, "EC"),
EE = new CountryCode(64, "EE"),
EG = new CountryCode(65, "EG"),
EH = new CountryCode(66, "EH"),
ER = new CountryCode(67, "ER"),
ES = new CountryCode(68, "ES"),
ET = new CountryCode(69, "ET"),
FI = new CountryCode(70, "FI"),
FJ = new CountryCode(71, "FJ"),
FK = new CountryCode(72, "FK"),
FM = new CountryCode(73, "FM"),
FO = new CountryCode(74, "FO"),
FR = new CountryCode(75, "FR"),
GA = new CountryCode(76, "GA"),
GB = new CountryCode(77, "GB"),
GD = new CountryCode(78, "GD"),
GE = new CountryCode(79, "GE"),
GF = new CountryCode(80, "GF"),
GG = new CountryCode(81, "GG"),
GH = new CountryCode(82, "GH"),
GI = new CountryCode(83, "GI"),
GL = new CountryCode(84, "GL"),
GM = new CountryCode(85, "GM"),
GN = new CountryCode(86, "GN"),
GP = new CountryCode(87, "GP"),
GQ = new CountryCode(88, "GQ"),
GR = new CountryCode(89, "GR"),
GS = new CountryCode(90, "GS"),
GT = new CountryCode(91, "GT"),
GU = new CountryCode(92, "GU"),
GW = new CountryCode(93, "GW"),
GY = new CountryCode(94, "GY"),
HK = new CountryCode(95, "HK"),
HM = new CountryCode(96, "HM"),
HN = new CountryCode(97, "HN"),
HR = new CountryCode(98, "HR"),
HT = new CountryCode(99, "HT"),
HU = new CountryCode(100, "HU"),
ID = new CountryCode(101, "ID"),
IE = new CountryCode(102, "IE"),
IL = new CountryCode(103, "IL"),
IM = new CountryCode(104, "IM"),
IN = new CountryCode(105, "IN"),
IO = new CountryCode(106, "IO"),
IQ = new CountryCode(107, "IQ"),
IR = new CountryCode(108, "IR"),
IS = new CountryCode(109, "IS"),
IT = new CountryCode(110, "IT"),
JE = new CountryCode(111, "JE"),
JM = new CountryCode(112, "JM"),
JO = new CountryCode(113, "JO"),
JP = new CountryCode(114, "JP"),
KE = new CountryCode(115, "KE"),
KG = new CountryCode(116, "KG"),
KH = new CountryCode(117, "KH"),
KI = new CountryCode(118, "KI"),
KM = new CountryCode(119, "KM"),
KN = new CountryCode(120, "KN"),
KP = new CountryCode(121, "KP"),
KR = new CountryCode(122, "KR"),
KW = new CountryCode(123, "KW"),
KY = new CountryCode(124, "KY"),
KZ = new CountryCode(125, "KZ"),
LA = new CountryCode(126, "LA"),
LB = new CountryCode(127, "LB"),
LC = new CountryCode(128, "LC"),
LI = new CountryCode(129, "LI"),
LK = new CountryCode(130, "LK"),
LR = new CountryCode(131, "LR"),
LS = new CountryCode(132, "LS"),
LT = new CountryCode(133, "LT"),
LU = new CountryCode(134, "LU"),
LV = new CountryCode(135, "LV"),
LY = new CountryCode(136, "LY"),
MA = new CountryCode(137, "MA"),
MC = new CountryCode(138, "MC"),
MD = new CountryCode(139, "MD"),
ME = new CountryCode(140, "ME"),
MF = new CountryCode(141, "MF"),
MG = new CountryCode(142, "MG"),
MH = new CountryCode(143, "MH"),
MK = new CountryCode(144, "MK"),
ML = new CountryCode(145, "ML"),
MM = new CountryCode(146, "MM"),
MN = new CountryCode(147, "MN"),
MO = new CountryCode(148, "MO"),
MP = new CountryCode(149, "MP"),
MQ = new CountryCode(150, "MQ"),
MR = new CountryCode(151, "MR"),
MS = new CountryCode(152, "MS"),
MT = new CountryCode(153, "MT"),
MU = new CountryCode(154, "MU"),
MV = new CountryCode(155, "MV"),
MW = new CountryCode(156, "MW"),
MX = new CountryCode(157, "MX"),
MY = new CountryCode(158, "MY"),
MZ = new CountryCode(159, "MZ"),
NA = new CountryCode(160, "NA"),
NC = new CountryCode(161, "NC"),
NE = new CountryCode(162, "NE"),
NF = new CountryCode(163, "NF"),
NG = new CountryCode(164, "NG"),
NI = new CountryCode(165, "NI"),
NL = new CountryCode(166, "NL"),
NO = new CountryCode(167, "NO"),
NP = new CountryCode(168, "NP"),
NR = new CountryCode(169, "NR"),
NU = new CountryCode(170, "NU"),
NZ = new CountryCode(171, "NZ"),
OM = new CountryCode(172, "OM"),
PA = new CountryCode(173, "PA"),
PE = new CountryCode(174, "PE"),
PF = new CountryCode(175, "PF"),
PG = new CountryCode(176, "PG"),
PH = new CountryCode(177, "PH"),
PK = new CountryCode(178, "PK"),
PL = new CountryCode(179, "PL"),
PM = new CountryCode(180, "PM"),
PN = new CountryCode(181, "PN"),
PR = new CountryCode(182, "PR"),
PS = new CountryCode(183, "PS"),
PT = new CountryCode(184, "PT"),
PW = new CountryCode(185, "PW"),
PY = new CountryCode(186, "PY"),
QA = new CountryCode(187, "QA"),
RE = new CountryCode(188, "RE"),
RO = new CountryCode(189, "RO"),
RS = new CountryCode(190, "RS"),
RU = new CountryCode(191, "RU"),
RW = new CountryCode(192, "RW"),
SA = new CountryCode(193, "SA"),
SB = new CountryCode(194, "SB"),
SC = new CountryCode(195, "SC"),
SD = new CountryCode(196, "SD"),
SE = new CountryCode(197, "SE"),
SG = new CountryCode(198, "SG"),
SH = new CountryCode(199, "SH"),
SI = new CountryCode(200, "SI"),
SJ = new CountryCode(201, "SJ"),
SK = new CountryCode(202, "SK"),
SL = new CountryCode(203, "SL"),
SM = new CountryCode(204, "SM"),
SN = new CountryCode(205, "SN"),
SO = new CountryCode(206, "SO"),
SR = new CountryCode(207, "SR"),
SS = new CountryCode(208, "SS"),
ST = new CountryCode(209, "ST"),
SV = new CountryCode(210, "SV"),
SX = new CountryCode(211, "SX"),
SY = new CountryCode(212, "SY"),
SZ = new CountryCode(213, "SZ"),
TC = new CountryCode(214, "TC"),
TD = new CountryCode(215, "TD"),
TF = new CountryCode(216, "TF"),
TG = new CountryCode(217, "TG"),
TH = new CountryCode(218, "TH"),
TJ = new CountryCode(219, "TJ"),
TK = new CountryCode(220, "TK"),
TL = new CountryCode(221, "TL"),
TM = new CountryCode(222, "TM"),
TN = new CountryCode(223, "TN"),
TO = new CountryCode(224, "TO"),
TR = new CountryCode(225, "TR"),
TT = new CountryCode(226, "TT"),
TV = new CountryCode(227, "TV"),
TW = new CountryCode(228, "TW"),
TZ = new CountryCode(229, "TZ"),
UA = new CountryCode(230, "UA"),
UG = new CountryCode(231, "UG"),
UM = new CountryCode(232, "UM"),
US = new CountryCode(233, "US"),
UY = new CountryCode(234, "UY"),
UZ = new CountryCode(235, "UZ"),
VA = new CountryCode(236, "VA"),
VC = new CountryCode(237, "VC"),
VE = new CountryCode(238, "VE"),
VG = new CountryCode(239, "VG"),
VI = new CountryCode(240, "VI"),
VN = new CountryCode(241, "VN"),
VU = new CountryCode(242, "VU"),
WF = new CountryCode(243, "WF"),
WS = new CountryCode(244, "WS"),
YE = new CountryCode(245, "YE"),
YT = new CountryCode(246, "YT"),
ZA = new CountryCode(247, "ZA"),
ZM = new CountryCode(248, "ZM"),
ZW = new CountryCode(249, "ZW"),
public int getId() {
return this.id;
}
UNSUPPORTED = new CountryCode(-1, "UNSUPPORTED");
public static CountryCode getById(int enumId) {
if (ELEMENTS.isEmpty()) {
synchronized (ELEMENTS) {
if (ELEMENTS.isEmpty()) {
//initialize elements map
for(CountryCode met : CountryCode.values()) {
ELEMENTS.put(met.getId(), met);
}
}
static {
//try to load all the subclasses explicitly - to avoid timing issues when items coming from subclasses may be registered some time later, after the parent class is loaded
Set<Class<? extends CountryCode>> subclasses = BaseJsonModel.getReflections().getSubTypesOf(CountryCode.class);
for(Class<?> cls: subclasses) {
try {
Class.forName(cls.getName());
} catch (ClassNotFoundException e) {
LOG.warn("Cannot load class {} : {}", cls.getName(), e);
}
}
}
private final int id;
private final String name;
protected CountryCode(int id, String name) {
synchronized(lock) {
LOG.debug("Registering CountryCode by {} : {}", this.getClass().getSimpleName(), name);
this.id = id;
this.name = name;
ELEMENTS_BY_NAME.values().forEach(s -> {
if(s.getName().equals(name)) {
throw new IllegalStateException("CountryCode item for "+ name + " is already defined, cannot have more than one of them");
}
});
if(ELEMENTS.containsKey(id)) {
throw new IllegalStateException("CountryCode item "+ name + "("+id+") is already defined, cannot have more than one of them");
}
ELEMENTS.put(id, this);
ELEMENTS_BY_NAME.put(name, this);
}
}
@Override
public int getId() {
return id;
}
@Override
public String getName() {
return name;
}
public static CountryCode getById(int enumId){
return ELEMENTS.get(enumId);
}
@JsonCreator
public static CountryCode getByName(String value) {
return JsonDeserializationUtils.deserializEnum(value, CountryCode.class, UNSUPPORTED);
CountryCode ret = ELEMENTS_BY_NAME.get(value);
if (ret == null) {
ret = UNSUPPORTED;
}
return ret;
}
public static List<CountryCode> getValues() {
return new ArrayList<>(ELEMENTS.values());
}
public static boolean isUnsupported(CountryCode value) {
return UNSUPPORTED.equals(value);
return (UNSUPPORTED.equals(value));
}
@Override
public int hashCode() {
return id;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof CountryCode)) {
return false;
}
CountryCode other = (CountryCode) obj;
return id == other.id;
}
@Override
public String toString() {
return name;
}
}

View File

@@ -0,0 +1,57 @@
package com.telecominfraproject.wlan.core.model.equipment;
import java.util.Objects;
import com.telecominfraproject.wlan.core.model.json.BaseJsonModel;
public abstract class AbstractSource<T> extends BaseJsonModel {
private static final long serialVersionUID = 2761981826629575941L;
protected SourceType source;
protected T value;
public AbstractSource(SourceType source, T manualValue) {
this.source = source;
this.value = manualValue;
}
protected AbstractSource() {
// json construct
}
public SourceType getSource() {
return source;
}
public void setSource(SourceType source) {
this.source = source;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
@Override
public int hashCode() {
return Objects.hash(source, value);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof AbstractSource)) {
return false;
}
AbstractSource<T> other = (AbstractSource<T>) obj;
return this.source == other.source && Objects.equals(value, other.value);
}
}

View File

@@ -0,0 +1,41 @@
package com.telecominfraproject.wlan.core.model.equipment;
public class SourceSelectionSteering extends AbstractSource<RadioBestApSettings>{
/**
*
*/
private static final long serialVersionUID = 4631172351117490997L;
private SourceSelectionSteering() {
}
private SourceSelectionSteering(SourceType source, RadioBestApSettings value) {
super(source, value);
}
public static SourceSelectionSteering createAutomaticInstance(RadioBestApSettings value) {
return new SourceSelectionSteering(SourceType.auto, value);
}
public static SourceSelectionSteering createManualInstance(RadioBestApSettings value) {
return new SourceSelectionSteering(SourceType.manual, value);
}
public static SourceSelectionSteering createProfileInstance(RadioBestApSettings value) {
return new SourceSelectionSteering(SourceType.profile, value);
}
@Override
public boolean hasUnsupportedValue() {
if (SourceType.isUnsupported(source)) {
return true;
}
if ((null != value) && value.hasUnsupportedValue()) {
return true;
}
return false;
}
}

View File

@@ -0,0 +1,50 @@
package com.telecominfraproject.wlan.core.model.equipment;
public class SourceSelectionValue extends AbstractSource<Integer>{
/**
*
*/
private static final long serialVersionUID = 4631172351117490997L;
private SourceSelectionValue() {
}
private SourceSelectionValue(SourceType source, int value) {
super(source, value);
}
public static SourceSelectionValue createAutomaticInstance(int value) {
return new SourceSelectionValue(SourceType.auto, value);
}
public static SourceSelectionValue createManualInstance(int value) {
return new SourceSelectionValue(SourceType.manual, value);
}
public static SourceSelectionValue createProfileInstance(int value) {
return new SourceSelectionValue(SourceType.profile, value);
}
public static AutoOrManualValue getAutoOrManualFromSourcedValue(SourceSelectionValue param) {
AutoOrManualValue ret = null;
if (param.getSource() == SourceType.auto) {
ret = AutoOrManualValue.createAutomaticInstance(param.getValue());
} else if (param.getSource() == SourceType.profile) {
ret = AutoOrManualValue.createManualInstance(param.getValue());
} else { // else param.getSource == SourceType.manual
ret = AutoOrManualValue.createManualInstance(param.getValue());
}
return ret;
}
@Override
public boolean hasUnsupportedValue() {
if (SourceType.isUnsupported(source)) {
return true;
}
return false;
}
}

View File

@@ -0,0 +1,50 @@
package com.telecominfraproject.wlan.core.model.equipment;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.telecominfraproject.wlan.core.model.json.JsonDeserializationUtils;
public enum SourceType {
auto(0L),
manual(1L),
profile(2L),
UNSUPPORTED(-1L);
private final long id;
private static final Map<Long, SourceType> ELEMENTS = new HashMap<>();
private SourceType(long id) {
this.id = id;
}
public long getId() {
return this.id;
}
public static SourceType getById(long enumId) {
if (ELEMENTS.isEmpty()) {
synchronized (ELEMENTS) {
if (ELEMENTS.isEmpty()) {
//initialize elements map
for(SourceType met : SourceType.values()) {
ELEMENTS.put(met.getId(), met);
}
}
}
}
return ELEMENTS.get(enumId);
}
@JsonCreator
public static SourceType getByName(String value) {
return JsonDeserializationUtils.deserializEnum(value, SourceType.class, UNSUPPORTED);
}
public static boolean isUnsupported(SourceType value) {
return UNSUPPORTED.equals(value);
}
}

View File

@@ -17,29 +17,49 @@ import com.telecominfraproject.wlan.core.model.json.JsonDeserializationUtils;
*/
public enum PortalUserRole {
/**
* Public user
* Public user - Read Only
*/
Public(0, 0),
/**
* Customer
* Customer - Read Write
*/
CustomerIT(1, 10),
/**
* MSP
* MSP - Read Write
*/
ManagedServiceProvider(2, 20),
/**
* Service Distributor
* Service Distributor - Read Write
*/
Distributor(3, 30),
/**
* Technical Support
* Technical Support - Read Write
*/
TechSupport(4, 40),
/**
* Super User
* Super User - Read Write
*/
SuperUser(Integer.MAX_VALUE, Integer.MAX_VALUE),
/**
* Customer - Read Only
*/
CustomerIT_RO(5, 5),
/**
* MSP - Read Only
*/
ManagedServiceProvider_RO(6, 15),
/**
* Service Distributor - Read Only
*/
Distributor_RO(7, 25),
/**
* Technical Support - Read Only
*/
TechSupport_RO(8, 35),
/**
* Super User - Read Only
*/
SuperUser_RO(Integer.MAX_VALUE - 1, Integer.MAX_VALUE - 5),
/**
* Unknown
*/

View File

@@ -13,6 +13,7 @@ public class WebTokenRequest extends BaseJsonModel {
private String grantType;
private String userId;
private String password;
private String refreshToken;
private String scope;
public String getGrantType() {
@@ -39,5 +40,11 @@ public class WebTokenRequest extends BaseJsonModel {
public void setScope(String scope) {
this.scope = scope;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
}

View File

@@ -14,6 +14,7 @@ public class WebTokenResult extends BaseJsonModel {
private boolean resetPassword;
private String access_token;
private String refresh_token;
private String id_token;
private String token_type;
private int expires_in;
private int idle_timeout;
@@ -43,6 +44,12 @@ public class WebTokenResult extends BaseJsonModel {
public void setRefresh_token(String refresh_token) {
this.refresh_token = refresh_token;
}
public String getId_token() {
return id_token;
}
public void setId_token(String id_token) {
this.id_token = id_token;
}
public String getToken_type() {
return token_type;
}

View File

@@ -13,9 +13,11 @@
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<artifactId>base-tx-tests</artifactId>
<version>${tip-wlan-cloud.release.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

View File

@@ -1,6 +1,7 @@
package com.telecominfraproject.wlan.remote.tests;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
@@ -28,7 +29,10 @@ import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.SimpleTransactionStatus;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import com.telecominfraproject.wlan.core.server.tx.test.TxTestConfig;
import com.telecominfraproject.wlan.server.RemoteTestServer;
/**
@@ -72,6 +76,7 @@ import com.telecominfraproject.wlan.server.RemoteTestServer;
"tip.wlan.csrf-enabled=false" })
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
@Import(value = {
TxTestConfig.class
})
public abstract class BaseRemoteTest {
@@ -127,37 +132,6 @@ public abstract class BaseRemoteTest {
// @PropertySource({ "classpath:persistence-${envTarget:dev}.properties" })
public static class Config {
@Bean
@Primary
public PlatformTransactionManager transactionManager() {
PlatformTransactionManager ptm = new PlatformTransactionManager() {
{
LOG.info("*** Using simulated PlatformTransactionManager");
}
@Override
public void rollback(TransactionStatus status) throws TransactionException {
LOG.info("Simulating Rollback for {}", status);
}
@Override
public void commit(TransactionStatus status) throws TransactionException {
LOG.info("Simulating Commit for {}", status);
}
@Override
public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
LOG.info("Simulating getTransaction for {}", definition);
TransactionStatus ts = new SimpleTransactionStatus();
return ts;
}
};
return ptm;
}
}
protected int getNextCustomerId() {

21
base-tx-tests/pom.xml Normal file
View File

@@ -0,0 +1,21 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.telecominfraproject.wlan</groupId>
<artifactId>tip-wlan-cloud-root-pom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../wlan-cloud-root</relativePath>
</parent>
<artifactId>base-tx-tests</artifactId>
<name>base-tx-tests</name>
<description>Common classes used by the unit tests that require transaction support.</description>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,98 @@
package com.telecominfraproject.wlan.core.server.tx.test;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.SimpleTransactionStatus;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
/**
* @author dtop
*
*/
@Configuration
public class TxTestConfig {
private static final Logger LOG = LoggerFactory.getLogger(TxTestConfig.class);
@Bean
@Primary
public PlatformTransactionManager transactionManager() {
PlatformTransactionManager ptm = new PlatformTransactionManager() {
private ThreadLocal<List<TransactionStatus>> currentTx = new ThreadLocal<>() ;
{
LOG.info("*** Using simulated PlatformTransactionManager");
}
@Override
public void rollback(TransactionStatus status) throws TransactionException {
LOG.debug("Simulating Rollback for {}", status);
if(currentTx.get().size() == 1 ) {
if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.clearSynchronization();
}
currentTx.remove();
} else {
currentTx.get().remove(currentTx.get().size() - 1 );
}
}
@Override
public void commit(TransactionStatus status) throws TransactionException {
LOG.debug("Simulating Commit for {}", status);
if(currentTx.get().size() == 1 ) {
if (TransactionSynchronizationManager.isSynchronizationActive()) {
List<TransactionSynchronization> synchronizations = TransactionSynchronizationManager
.getSynchronizations();
if (synchronizations != null) {
for (TransactionSynchronization synchronization : synchronizations) {
synchronization.afterCommit();
}
}
TransactionSynchronizationManager.clearSynchronization();
}
currentTx.remove();
} else {
currentTx.get().remove(currentTx.get().size() - 1 );
}
}
@Override
public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
LOG.debug("Simulating getTransaction for {}", definition);
if (!TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.initSynchronization();
}
if (currentTx.get() == null) {
List<TransactionStatus> txList = new ArrayList<>();
TransactionStatus ts = new SimpleTransactionStatus(true);
txList.add(ts);
currentTx.set(txList);
return ts;
} else {
List<TransactionStatus> txList = currentTx.get();
TransactionStatus ts = new SimpleTransactionStatus(false);
txList.add(ts);
return ts;
}
}
};
return ptm;
}
}