use of com.emc.storageos.db.client.model.Token in project coprhd-controller by CoprHD.
the class TokenManagerTests method testTokens.
/**
* main set of tests for tokens
*/
@Test
public void testTokens() throws Exception {
commonDefaultSetupForSingleNodeTests();
// Test - new ticket issue
StorageOSUserDAO userDAO = new StorageOSUserDAO();
userDAO.setUserName("user1");
userDAO.setIsLocal(true);
long now = System.currentTimeMillis() / (60 * 1000);
final String token = _tokenManager.getToken(userDAO);
Assert.assertNotNull(token);
TokenOnWire tw1 = _encoder.decode(token);
Token tokenObj = _dbClient.queryObject(Token.class, tw1.getTokenId());
Assert.assertNotNull(tokenObj);
Assert.assertNotNull(tokenObj.getUserId());
Assert.assertTrue(tokenObj.getExpirationTime() >= (now + 4));
final URI userId = tokenObj.getUserId();
// verify token
StorageOSUserDAO gotUser = _tokenManager.validateToken(token);
Assert.assertNotNull(gotUser);
Assert.assertEquals(userId, gotUser.getId());
// Test - update user info, reuse token
StringSet groups = new StringSet();
groups.add("gr1");
groups.add("gr2");
userDAO.setGroups(groups);
StringSet attributes = new StringSet();
attributes.add("atrr1");
attributes.add("attr2");
userDAO.setAttributes(attributes);
String token2 = _tokenManager.getToken(userDAO);
// different tokens for same user record
Assert.assertFalse(token.equals(token2));
TokenOnWire tw2 = _encoder.decode(token2);
Assert.assertFalse(tw1.getTokenId().equals(tw2.getTokenId()));
tokenObj = _dbClient.queryObject(Token.class, tw2.getTokenId());
Assert.assertNotNull(tokenObj);
Assert.assertNotNull(tokenObj.getUserId());
Assert.assertEquals(userId, tokenObj.getUserId());
StorageOSUserDAO userInfo = _dbClient.queryObject(StorageOSUserDAO.class, userId);
Assert.assertNotNull(userInfo);
Assert.assertEquals(userId, userInfo.getId());
Assert.assertFalse(userInfo.getInactive());
Assert.assertEquals(groups.size(), userInfo.getGroups().size());
Assert.assertEquals(attributes.size(), userInfo.getAttributes().size());
Assert.assertTrue(userInfo.getIsLocal());
// verify token
gotUser = _tokenManager.validateToken(token2);
Assert.assertNotNull(gotUser);
Assert.assertEquals(userId, gotUser.getId());
// Test - update user info, new token
userDAO = new StorageOSUserDAO();
userDAO.setUserName("user1");
groups = new StringSet();
groups.add("gr1");
userDAO.setGroups(groups);
attributes = new StringSet();
attributes.add("atrr1");
attributes.add("attr2");
attributes.add("attr3");
userDAO.setAttributes(attributes);
// new token
final String token3 = _tokenManager.getToken(userDAO);
Assert.assertFalse(token2.equals(token3));
TokenOnWire tw3 = _encoder.decode(token3);
tokenObj = _dbClient.queryObject(Token.class, tw3.getTokenId());
Assert.assertNotNull(tokenObj);
Assert.assertNotNull(tokenObj.getUserId());
Assert.assertEquals(userId, tokenObj.getUserId());
userInfo = _dbClient.queryObject(StorageOSUserDAO.class, userId);
Assert.assertNotNull(userInfo);
Assert.assertEquals(userId, userInfo.getId());
Assert.assertFalse(userInfo.getInactive());
Assert.assertEquals(groups.size(), userInfo.getGroups().size());
Assert.assertEquals(attributes.size(), userInfo.getAttributes().size());
Assert.assertTrue(userInfo.getIsLocal());
// verify token
gotUser = _tokenManager.validateToken(token3);
Assert.assertNotNull(gotUser);
Assert.assertEquals(userId, gotUser.getId());
// Test - idle time timeout
tokenObj = _dbClient.queryObject(Token.class, tw1.getTokenId());
// extend expiration by 10min, so that will not happen
now = (System.currentTimeMillis() / (60 * 1000));
tokenObj.setLastAccessTime(now);
tokenObj.setExpirationTime(now + 5);
_dbClient.persistObject(tokenObj);
int count = 8;
while (count-- > 0) {
// validate every 30 sec, for the next 4 min
Thread.sleep(30 * 1000);
gotUser = _tokenManager.validateToken(token);
Assert.assertNotNull(gotUser);
}
// set last access time back
tokenObj = _dbClient.queryObject(Token.class, tw1.getTokenId());
tokenObj.setLastAccessTime((System.currentTimeMillis() / (60 * 1000)) - 3);
_dbClient.persistObject(tokenObj);
// validate token on the old token - should fail
gotUser = _tokenManager.validateToken(token);
Assert.assertNull(gotUser);
// token object should be deleted from db,
// but user info should not be effected because we have another token pointing to it
tokenObj = _dbClient.queryObject(Token.class, tw1.getTokenId());
Assert.assertNull(tokenObj);
userInfo = _dbClient.queryObject(StorageOSUserDAO.class, userId);
Assert.assertNotNull(userInfo);
Assert.assertFalse(userInfo.getInactive());
// Test - deletion of token
// should set userinfo inactive - because this is the last token pointing to it
_tokenManager.deleteToken(token2);
_tokenManager.deleteToken(token3);
userInfo = _dbClient.queryObject(StorageOSUserDAO.class, userId);
Assert.assertNotNull(userInfo);
Assert.assertTrue(userInfo.getInactive());
// Test - with inactive user info - new token request
// new token and new user info created - with possible race condition to create more than one each
int numThreads = 5;
final List<String> tokens = Collections.synchronizedList(new ArrayList<String>());
final List<URI> userIds = Collections.synchronizedList(new ArrayList<URI>());
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
final CountDownLatch wait = new CountDownLatch(numThreads);
for (int index = 0; index < numThreads; index++) {
executor.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
wait.countDown();
wait.await();
StorageOSUserDAO userDAO = new StorageOSUserDAO();
userDAO.setUserName("user1");
String token4 = _tokenManager.getToken(userDAO);
TokenOnWire tw4 = _encoder.decode(token4);
Assert.assertFalse(token3.equals(token4));
Assert.assertFalse(token.equals(token4));
Token tokenObj = _dbClient.queryObject(Token.class, tw4.getTokenId());
Assert.assertNotNull(tokenObj);
Assert.assertNotNull(tokenObj.getUserId());
Assert.assertFalse(userId.equals(tokenObj.getUserId()));
StorageOSUserDAO userInfo = _dbClient.queryObject(StorageOSUserDAO.class, tokenObj.getUserId());
Assert.assertNotNull(userInfo);
Assert.assertEquals(userDAO.getUserName(), userInfo.getUserName());
Assert.assertFalse(userInfo.getInactive());
Assert.assertFalse(userInfo.getIsLocal());
tokens.add(token4);
userIds.add(userInfo.getId());
return null;
}
});
}
executor.shutdown();
Assert.assertTrue(executor.awaitTermination(60, TimeUnit.SECONDS));
Assert.assertTrue(!tokens.isEmpty());
Assert.assertTrue(!userIds.isEmpty());
// Test - delete all tokens
_tokenManager.deleteAllTokensForUser(userDAO.getUserName(), true);
List<URI> tokensURIs = new ArrayList<URI>();
for (String rawToken : tokens) {
tokensURIs.add(_encoder.decode(rawToken).getTokenId());
}
List<Token> allTokens = _dbClient.queryObject(Token.class, tokensURIs);
Assert.assertTrue(allTokens.isEmpty());
List<StorageOSUserDAO> users = _dbClient.queryObject(StorageOSUserDAO.class, userIds);
for (StorageOSUserDAO user : users) {
Assert.assertTrue(user.getInactive());
URIQueryResultList tokensForUser = new URIQueryResultList();
_dbClient.queryByConstraint(ContainmentConstraint.Factory.getUserIdTokenConstraint(userId), tokensForUser);
Assert.assertFalse(tokensForUser.iterator().hasNext());
}
// Test - expired token deleting
userDAO = new StorageOSUserDAO();
userDAO.setUserName("user1");
String dt1 = _tokenManager.getToken(userDAO);
TokenOnWire twdt1 = _encoder.decode(dt1);
tokenObj = _dbClient.queryObject(Token.class, twdt1.getTokenId());
Assert.assertNotNull(tokenObj);
Assert.assertNotNull(tokenObj.getUserId());
URI du1 = tokenObj.getUserId();
userDAO = new StorageOSUserDAO();
userDAO.setUserName("user2");
String dt2 = _tokenManager.getToken(userDAO);
TokenOnWire twdt2 = _encoder.decode(dt2);
tokenObj = _dbClient.queryObject(Token.class, twdt2.getTokenId());
Assert.assertNotNull(tokenObj);
Assert.assertNotNull(tokenObj.getUserId());
URI du2 = tokenObj.getUserId();
Thread.sleep(3 * 60 * 1000);
_tokenManager.runCleanupNow();
tokenObj = _dbClient.queryObject(Token.class, twdt1.getTokenId());
Assert.assertNull(tokenObj);
tokenObj = _dbClient.queryObject(Token.class, twdt2.getTokenId());
Assert.assertNull(tokenObj);
userDAO = _dbClient.queryObject(StorageOSUserDAO.class, du1);
Assert.assertTrue(userDAO.getInactive());
userDAO = _dbClient.queryObject(StorageOSUserDAO.class, du2);
Assert.assertTrue(userDAO.getInactive());
// test limits
userDAO = new StorageOSUserDAO();
userDAO.setUserName("user1");
for (int i = 0; i < 100; i++) {
dt1 = _tokenManager.getToken(userDAO);
twdt1 = _encoder.decode(dt1);
tokenObj = _dbClient.queryObject(Token.class, twdt1.getTokenId());
Assert.assertNotNull(tokenObj);
Assert.assertNotNull(tokenObj.getUserId());
}
// next get, will throw limit exception
try {
dt1 = _tokenManager.getToken(userDAO);
Assert.fail("The token limit is exceeded. The token for user1 should not be generated.");
} catch (UnauthorizedException ex) {
// this exception is an expected one.
Assert.assertTrue(true);
}
}
use of com.emc.storageos.db.client.model.Token in project coprhd-controller by CoprHD.
the class InterVDCTokenCacheHelper method cacheForeignTokenArtifacts.
/**
* Saves the token and user dao records to the db. Set the cache expiration time
* to 10 minutes or time left on the token, whichever is sooner.
* Note: this method assumes validity of the token (expiration) has been checked
*
* @param t
* @param user
* @param now current time in minutes
*/
private synchronized void cacheForeignTokenArtifacts(final Token token, final StorageOSUserDAO user) {
long now = System.currentTimeMillis() / (MIN_TO_MSECS);
InterProcessLock tokenLock = null;
try {
tokenLock = coordinator.getLock(token.getId().toString());
if (tokenLock == null) {
log.error("Could not acquire lock for token caching");
throw SecurityException.fatals.couldNotAcquireLockTokenCaching();
}
tokenLock.acquire();
StorageOSUserDAO userToPersist = dbClient.queryObject(StorageOSUserDAO.class, user.getId());
userToPersist = (userToPersist == null) ? new StorageOSUserDAO() : userToPersist;
userToPersist.setAttributes(user.getAttributes());
userToPersist.setCreationTime(user.getCreationTime());
userToPersist.setDistinguishedName(user.getDistinguishedName());
userToPersist.setGroups(user.getGroups());
userToPersist.setId(user.getId());
userToPersist.setIsLocal(user.getIsLocal());
userToPersist.setTenantId(user.getTenantId());
userToPersist.setUserName(user.getUserName());
dbClient.persistObject(userToPersist);
Token tokenToPersist = dbClient.queryObject(Token.class, token.getId());
tokenToPersist = (tokenToPersist == null) ? new Token() : tokenToPersist;
if ((token.getExpirationTime() - now) > maxLifeValuesHolder.getForeignTokenCacheExpirationInMins()) {
tokenToPersist.setCacheExpirationTime(now + maxLifeValuesHolder.getForeignTokenCacheExpirationInMins());
} else {
tokenToPersist.setCacheExpirationTime(token.getExpirationTime());
}
tokenToPersist.setId(token.getId());
// relative index, Id of the userDAO record
tokenToPersist.setUserId(user.getId());
tokenToPersist.setIssuedTime(token.getIssuedTime());
tokenToPersist.setLastAccessTime(now);
tokenToPersist.setExpirationTime(token.getExpirationTime());
tokenToPersist.setIndexed(true);
tokenToPersist.setZoneId(token.getZoneId());
dbClient.persistObject(tokenToPersist);
log.info("Cached user {} and token", user.getUserName());
} catch (Exception ex) {
log.error("Could not acquire lock while trying to get a proxy token.", ex);
} finally {
try {
if (tokenLock != null) {
tokenLock.release();
}
} catch (Exception ex) {
log.error("Unable to release token caching lock", ex);
}
}
}
use of com.emc.storageos.db.client.model.Token in project coprhd-controller by CoprHD.
the class InterVDCTokenCacheHelper method cacheForeignTokenAndKeys.
/**
* saves token artifacts to the cache. The artifacts can be the token & user record, and token key ids.
* Token key ids (TokenKeyBundle) goes to zk. Token and user record goes to cassandra.
*
* @param artifacts
* @param vdcID
*/
public void cacheForeignTokenAndKeys(TokenResponseArtifacts artifacts, String vdcID) {
Token token = artifacts.getToken();
StorageOSUserDAO user = artifacts.getUser();
TokenKeysBundle bundle = artifacts.getTokenKeysBundle();
if (token != null && user != null) {
cacheForeignTokenArtifacts(token, user);
}
if (bundle != null) {
saveTokenKeysBundle(vdcID, bundle);
}
}
use of com.emc.storageos.db.client.model.Token in project coprhd-controller by CoprHD.
the class TokenResponseBuilder method parseTokenResponse.
/**
* Creates a TokenResponseArtifacts holder for items retrieved in a TokenResponse.
* Today, Token and StorageOSUserDAO objects
*
* @param response
* @return
*/
public static TokenResponseArtifacts parseTokenResponse(TokenResponse response) {
String userEncoded = response.getUserDAO();
String tokenEncoded = response.getToken();
String tokenKeysBundleEncoded = response.getTokenKeysBundle();
StorageOSUserDAO user = null;
Token token = null;
TokenKeysBundle tokenKeysBundle = null;
if (StringUtils.isNotBlank(userEncoded)) {
try {
user = (StorageOSUserDAO) SerializerUtils.deserialize(userEncoded);
} catch (UnsupportedEncodingException e) {
log.error("Could not decode user: ", e);
} catch (Exception e) {
log.error("Could not deserialize user: ", e);
}
}
if (StringUtils.isNotBlank(tokenEncoded)) {
try {
token = (Token) SerializerUtils.deserialize(tokenEncoded);
} catch (UnsupportedEncodingException e) {
log.error("Could not decode token: ", e);
} catch (Exception e) {
log.error("Could not deserialize token: ", e);
}
}
if (StringUtils.isNotBlank(tokenKeysBundleEncoded)) {
try {
tokenKeysBundle = (TokenKeysBundle) SerializerUtils.deserialize(tokenKeysBundleEncoded);
} catch (UnsupportedEncodingException e) {
log.error("Could not decode token keys bundle: ", e);
} catch (Exception e) {
log.error("Could not deserialize token keys bundle: ", e);
}
}
return new TokenResponseBuilder.TokenResponseArtifacts(user, token, tokenKeysBundle);
}
use of com.emc.storageos.db.client.model.Token in project coprhd-controller by CoprHD.
the class TokenService method getToken.
/**
* Retrieves Token and UserDAO records from a passed in auth token (header)
* TokenKeysRequest can also contain key ids to look at. If they don't match the local
* TokenKeysBundle, send the updated bundle in the response
*
* @param httpRequest
* @return TokenResponse with token and userDAO records populated.
*/
@POST
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public TokenResponse getToken(@Context HttpServletRequest httpRequest, TokenKeysRequest req) {
String rawToken = httpRequest.getHeader(RequestProcessingUtils.AUTH_TOKEN_HEADER);
String firstKey = req.getFirstKeyId();
String secondKey = req.getSecondKeyId();
Token token = null;
StorageOSUserDAO user = null;
TokenKeysBundle updatedBundle = null;
// validate token if provided
if (StringUtils.isNotBlank(rawToken)) {
token = (Token) tokenValidator.verifyToken(rawToken);
if (token != null) {
user = tokenValidator.resolveUser(token);
}
if (user == null || token == null) {
throw APIException.unauthorized.noTokenFoundForUserFromForeignVDC();
}
if (user.getIsLocal()) {
throw APIException.forbidden.localUsersNotAllowedForSingleSignOn(user.getUserName());
}
}
// not has been a rotation yet.
if (StringUtils.isNotBlank(firstKey)) {
try {
updatedBundle = tokenKeyGenerator.readBundle();
} catch (Exception ex) {
log.error("Could not look at local token keys bundle");
}
if (updatedBundle != null) {
// if we found a bundle
log.debug("Read the local key bundle");
// look at its key ids
List<String> keyIds = updatedBundle.getKeyEntries();
if ((firstKey.equals(keyIds.get(0)) && secondKey == null && keyIds.size() == 1) || (firstKey.equals(keyIds.get(0)) && secondKey != null && secondKey.equals(keyIds.get(1)))) {
log.info("Key id match. Not returning a bundle");
// if they both match what was passed in, make the bundle null and
// return that. Caller has updated keys and does not need them.
updatedBundle = null;
} else {
log.info("Key ids do not match. Returning updated bundle");
}
}
}
if (token != null) {
tokenMapHelper.addOrRemoveRequestingVDC(Operation.ADD_VDC, token.getId().toString(), req.getRequestingVDC());
// update idle time on original token. Since it is being borrowed by another vdc,
// it just got accessed.
token.setLastAccessTime(CassandraTokenValidator.getCurrentTimeInMins());
try {
dbClient.persistObject(token);
} catch (DatabaseException ex) {
log.error("failed updating last access time for borrowed token {}", token.getId());
}
}
return TokenResponseBuilder.buildTokenResponse(token, user, updatedBundle);
}
Aggregations