Search in sources :

Example 6 with Token

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);
    }
}
Also used : SignedToken(com.emc.storageos.security.authentication.Base64TokenEncoder.SignedToken) ProxyToken(com.emc.storageos.db.client.model.ProxyToken) Token(com.emc.storageos.db.client.model.Token) BaseToken(com.emc.storageos.db.client.model.BaseToken) URI(java.net.URI) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) UnauthorizedException(com.emc.storageos.svcs.errorhandling.resources.UnauthorizedException) IOException(java.io.IOException) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) StorageOSUserDAO(com.emc.storageos.db.client.model.StorageOSUserDAO) StringSet(com.emc.storageos.db.client.model.StringSet) UnauthorizedException(com.emc.storageos.svcs.errorhandling.resources.UnauthorizedException) TokenOnWire(com.emc.storageos.security.authentication.TokenOnWire) Test(org.junit.Test)

Example 7 with Token

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);
        }
    }
}
Also used : StorageOSUserDAO(com.emc.storageos.db.client.model.StorageOSUserDAO) InterProcessLock(org.apache.curator.framework.recipes.locks.InterProcessLock) Token(com.emc.storageos.db.client.model.Token) SecurityException(com.emc.storageos.security.exceptions.SecurityException)

Example 8 with Token

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);
    }
}
Also used : StorageOSUserDAO(com.emc.storageos.db.client.model.StorageOSUserDAO) TokenKeysBundle(com.emc.storageos.security.authentication.TokenKeyGenerator.TokenKeysBundle) Token(com.emc.storageos.db.client.model.Token)

Example 9 with Token

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);
}
Also used : StorageOSUserDAO(com.emc.storageos.db.client.model.StorageOSUserDAO) TokenKeysBundle(com.emc.storageos.security.authentication.TokenKeyGenerator.TokenKeysBundle) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Token(com.emc.storageos.db.client.model.Token) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException)

Example 10 with Token

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);
}
Also used : StorageOSUserDAO(com.emc.storageos.db.client.model.StorageOSUserDAO) TokenKeysBundle(com.emc.storageos.security.authentication.TokenKeyGenerator.TokenKeysBundle) Token(com.emc.storageos.db.client.model.Token) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) APIException(com.emc.storageos.svcs.errorhandling.resources.APIException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces)

Aggregations

Token (com.emc.storageos.db.client.model.Token)18 StorageOSUserDAO (com.emc.storageos.db.client.model.StorageOSUserDAO)15 ProxyToken (com.emc.storageos.db.client.model.ProxyToken)14 BaseToken (com.emc.storageos.db.client.model.BaseToken)10 SignedToken (com.emc.storageos.security.authentication.Base64TokenEncoder.SignedToken)7 URI (java.net.URI)7 Test (org.junit.Test)7 TokenOnWire (com.emc.storageos.security.authentication.TokenOnWire)6 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)4 TokenKeysBundle (com.emc.storageos.security.authentication.TokenKeyGenerator.TokenKeysBundle)4 CassandraTokenManager (com.emc.storageos.auth.impl.CassandraTokenManager)3 CoordinatorClient (com.emc.storageos.coordinator.client.service.CoordinatorClient)3 Base64TokenEncoder (com.emc.storageos.security.authentication.Base64TokenEncoder)3 TokenKeyGenerator (com.emc.storageos.security.authentication.TokenKeyGenerator)3 TokenMaxLifeValuesHolder (com.emc.storageos.security.authentication.TokenMaxLifeValuesHolder)3 SecurityException (com.emc.storageos.security.exceptions.SecurityException)3 DbClient (com.emc.storageos.db.client.DbClient)2 AlternateIdConstraint (com.emc.storageos.db.client.constraint.AlternateIdConstraint)2 ContainmentConstraint (com.emc.storageos.db.client.constraint.ContainmentConstraint)2 StringSet (com.emc.storageos.db.client.model.StringSet)2