diff options
author | 2016-05-24 17:13:17 +0200 | |
---|---|---|
committer | 2016-05-24 17:13:17 +0200 | |
commit | e63b03f3d7e4851e008e4bb4d184982c2c0bd229 (patch) | |
tree | 8364e8a9c56e214ac0fe248409d21f324b1e0f18 /odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org | |
parent | 3c1264562ec7949d008e2335b9eecc400436a70d (diff) |
odl/aaa clone
Change-Id: I2b72c16aa3245e02d985a2c6189aacee7caad36e
Signed-off-by: WuKong <rebirthmonkey@gmail.com>
Diffstat (limited to 'odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org')
8 files changed, 1529 insertions, 0 deletions
diff --git a/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/AuthNStore.java b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/AuthNStore.java new file mode 100644 index 00000000..09170182 --- /dev/null +++ b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/AuthNStore.java @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.aaa.authn.mdsal.store; + +import com.google.common.base.Optional; +import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import java.math.BigInteger; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.opendaylight.aaa.api.Authentication; +import org.opendaylight.aaa.api.TokenStore; +import org.opendaylight.aaa.authn.mdsal.store.util.AuthNStoreUtil; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.ReadTransaction; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.TokenCacheTimes; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.token_cache_times.TokenList; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.token_cache_times.TokenListKey; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.token_cache_times.token_list.UserTokens; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.tokencache.Claims; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AuthNStore implements AutoCloseable, TokenStore { + + private static final Logger LOG = LoggerFactory.getLogger(AuthNStore.class); + private DataBroker broker; + private static BigInteger timeToLive; + private static Integer timeToWait; + private final ExecutorService deleteExpiredTokenThread = Executors.newFixedThreadPool(1); + private final DataEncrypter dataEncrypter; + + public AuthNStore(final DataBroker dataBroker, final String config_key) { + this.broker = dataBroker; + this.dataEncrypter = new DataEncrypter(config_key); + LOG.info("Created MD-SAL AAA Token Cache Service..."); + } + + @Override + public void close() throws Exception { + deleteExpiredTokenThread.shutdown(); + LOG.info("MD-SAL AAA Token Cache closed..."); + + } + + @Override + public void put(String token, Authentication auth) { + token = dataEncrypter.encrypt(token); + Claims claims = AuthNStoreUtil.createClaimsRecord(token, auth); + + // create and insert parallel struct + UserTokens userTokens = AuthNStoreUtil.createUserTokens(token, timeToLive.longValue()); + TokenList tokenlist = AuthNStoreUtil.createTokenList(userTokens, auth.userId()); + + writeClaimAndTokenToStore(claims, userTokens, tokenlist); + deleteExpiredTokenThread.execute(deleteOldTokens(claims)); + } + + @Override + public Authentication get(String token) { + token = dataEncrypter.encrypt(token); + Authentication authentication = null; + Claims claims = readClaims(token); + if (claims != null) { + UserTokens userToken = readUserTokensFromDS(claims.getToken(), claims.getUserId()); + authentication = AuthNStoreUtil.convertClaimToAuthentication(claims, + userToken.getExpiration()); + } + deleteExpiredTokenThread.execute(deleteOldTokens(claims)); + return authentication; + } + + @Override + public boolean delete(String token) { + token = dataEncrypter.encrypt(token); + boolean result = false; + Claims claims = readClaims(token); + result = deleteClaims(token); + if (result) { + deleteUserTokenFromDS(token, claims.getUserId()); + } + deleteExpiredTokenThread.execute(deleteOldTokens(claims)); + return result; + } + + @Override + public long tokenExpiration() { + return timeToLive.longValue(); + } + + public void setTimeToLive(BigInteger timeToLive) { + this.timeToLive = timeToLive; + } + + public void setTimeToWait(Integer timeToWait) { + this.timeToWait = timeToWait; + } + + private void writeClaimAndTokenToStore(final Claims claims, UserTokens usertokens, + final TokenList tokenlist) { + + final InstanceIdentifier<Claims> claims_iid = AuthNStoreUtil.createInstIdentifierForTokencache(claims.getToken()); + WriteTransaction tx = broker.newWriteOnlyTransaction(); + tx.put(LogicalDatastoreType.OPERATIONAL, claims_iid, claims, true); + + final InstanceIdentifier<UserTokens> userTokens_iid = AuthNStoreUtil.createInstIdentifierUserTokens( + tokenlist.getUserId(), usertokens.getTokenid()); + tx.put(LogicalDatastoreType.OPERATIONAL, userTokens_iid, usertokens, true); + + CheckedFuture<Void, TransactionCommitFailedException> commitFuture = tx.submit(); + Futures.addCallback(commitFuture, new FutureCallback<Void>() { + + @Override + public void onSuccess(Void result) { + LOG.trace("Token {} was written to datastore.", claims.getToken()); + LOG.trace("Tokenlist for userId {} was written to datastore.", + tokenlist.getUserId()); + } + + @Override + public void onFailure(Throwable t) { + LOG.error("Inserting token {} to datastore failed.", claims.getToken()); + LOG.trace("Inserting for userId {} tokenlist to datastore failed.", + tokenlist.getUserId()); + } + + }); + } + + private Claims readClaims(String token) { + final InstanceIdentifier<Claims> claims_iid = AuthNStoreUtil.createInstIdentifierForTokencache(token); + Claims claims = null; + ReadTransaction rt = broker.newReadOnlyTransaction(); + CheckedFuture<Optional<Claims>, ReadFailedException> claimsFuture = rt.read( + LogicalDatastoreType.OPERATIONAL, claims_iid); + try { + Optional<Claims> maybeClaims = claimsFuture.checkedGet(); + if (maybeClaims.isPresent()) { + claims = maybeClaims.get(); + } + } catch (ReadFailedException e) { + LOG.error( + "Something wrong happened in DataStore. Getting Claim for token {} failed.", + token, e); + } + return claims; + } + + private TokenList readTokenListFromDS(String userId) { + InstanceIdentifier<TokenList> tokenList_iid = InstanceIdentifier.builder( + TokenCacheTimes.class).child(TokenList.class, new TokenListKey(userId)).build(); + TokenList tokenList = null; + ReadTransaction rt = broker.newReadOnlyTransaction(); + CheckedFuture<Optional<TokenList>, ReadFailedException> userTokenListFuture = rt.read( + LogicalDatastoreType.OPERATIONAL, tokenList_iid); + try { + Optional<TokenList> maybeTokenList = userTokenListFuture.checkedGet(); + if (maybeTokenList.isPresent()) { + tokenList = maybeTokenList.get(); + } + } catch (ReadFailedException e) { + LOG.error( + "Something wrong happened in DataStore. Getting TokenList for userId {} failed.", + userId, e); + } + return tokenList; + } + + private UserTokens readUserTokensFromDS(String token, String userId) { + final InstanceIdentifier<UserTokens> userTokens_iid = AuthNStoreUtil.createInstIdentifierUserTokens( + userId, token); + UserTokens userTokens = null; + + ReadTransaction rt = broker.newReadOnlyTransaction(); + CheckedFuture<Optional<UserTokens>, ReadFailedException> userTokensFuture = rt.read( + LogicalDatastoreType.OPERATIONAL, userTokens_iid); + + try { + Optional<UserTokens> maybeUserTokens = userTokensFuture.checkedGet(); + if (maybeUserTokens.isPresent()) { + userTokens = maybeUserTokens.get(); + } + } catch (ReadFailedException e) { + LOG.error( + "Something wrong happened in DataStore. Getting UserTokens for token {} failed.", + token, e); + } + + return userTokens; + } + + private boolean deleteClaims(String token) { + final InstanceIdentifier<Claims> claims_iid = AuthNStoreUtil.createInstIdentifierForTokencache(token); + boolean result = false; + WriteTransaction tx = broker.newWriteOnlyTransaction(); + tx.delete(LogicalDatastoreType.OPERATIONAL, claims_iid); + CheckedFuture<Void, TransactionCommitFailedException> commitFuture = tx.submit(); + + try { + commitFuture.checkedGet(); + result = true; + } catch (TransactionCommitFailedException e) { + LOG.error("Something wrong happened in DataStore. Claim " + + "deletion for token {} from DataStore failed.", token, e); + } + return result; + } + + private void deleteUserTokenFromDS(String token, String userId) { + final InstanceIdentifier<UserTokens> userTokens_iid = AuthNStoreUtil.createInstIdentifierUserTokens( + userId, token); + + WriteTransaction tx = broker.newWriteOnlyTransaction(); + tx.delete(LogicalDatastoreType.OPERATIONAL, userTokens_iid); + CheckedFuture<Void, TransactionCommitFailedException> commitFuture = tx.submit(); + try { + commitFuture.checkedGet(); + } catch (TransactionCommitFailedException e) { + LOG.error("Something wrong happened in DataStore. UserToken " + + "deletion for token {} from DataStore failed.", token, e); + } + } + + private Runnable deleteOldTokens(final Claims claims) { + return new Runnable() { + + @Override + public void run() { + TokenList tokenList = null; + if (claims != null) { + tokenList = readTokenListFromDS(claims.getUserId()); + } + if (tokenList != null) { + for (UserTokens currUserToken : tokenList.getUserTokens()) { + long diff = System.currentTimeMillis() + - currUserToken.getTimestamp().longValue(); + if (diff > currUserToken.getExpiration() + && currUserToken.getExpiration() != 0) { + if (deleteClaims(currUserToken.getTokenid())) { + deleteUserTokenFromDS(currUserToken.getTokenid(), + claims.getUserId()); + LOG.trace("Expired tokens for UserId {} deleted.", + claims.getUserId()); + } + } + } + } + } + }; + } +} diff --git a/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/DataEncrypter.java b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/DataEncrypter.java new file mode 100644 index 00000000..ca0a74be --- /dev/null +++ b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/DataEncrypter.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.aaa.authn.mdsal.store; + +import java.security.spec.KeySpec; +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.SecretKeySpec; +import javax.xml.bind.DatatypeConverter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author - Sharon Aicler (saichler@cisco.com) + **/ +public class DataEncrypter { + + final protected SecretKey k; + private static final Logger LOG = LoggerFactory.getLogger(DataEncrypter.class); + private static final byte[] iv = { 0, 5, 0, 0, 7, 81, 0, 3, 0, 0, 0, 0, 0, 43, 0, 1 }; + private static final IvParameterSpec ivspec = new IvParameterSpec(iv); + public static final String ENCRYPTED_TAG = "Encrypted:"; + + public DataEncrypter(final String ckey) { + SecretKey tmp = null; + if (ckey != null && !ckey.isEmpty()) { + + try { + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); + KeySpec spec = new PBEKeySpec(ckey.toCharArray(), iv, 32768, 128); + tmp = keyFactory.generateSecret(spec); + } catch (Exception e) { + LOG.error("Couldn't initialize key factory", e); + } + if (tmp != null) { + k = new SecretKeySpec(tmp.getEncoded(), "AES"); + } else { + throw new RuntimeException("Couldn't initalize encryption key"); + } + } else { + k = null; + LOG.warn("Void crypto key passed! AuthN Store Encryption disabled"); + } + + } + + protected String encrypt(String token) { + + if (k == null) { + return token; + } + + String cryptostring = null; + try { + Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); + c.init(Cipher.ENCRYPT_MODE, k, ivspec); + byte[] cryptobytes = c.doFinal(token.getBytes()); + cryptostring = DatatypeConverter.printBase64Binary(cryptobytes); + return ENCRYPTED_TAG + cryptostring; + } catch (Exception e) { + LOG.error("Couldn't encrypt token", e); + return null; + } + } + + protected String decrypt(String eToken) { + if (k == null) { + return eToken; + } + + if (eToken == null || eToken.length() == 0) { + return null; + } + + if (!eToken.startsWith(ENCRYPTED_TAG)) { + return eToken; + } + + try { + Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); + c.init(Cipher.DECRYPT_MODE, k, ivspec); + + byte[] cryptobytes = DatatypeConverter.parseBase64Binary(eToken.substring(ENCRYPTED_TAG.length())); + byte[] clearbytes = c.doFinal(cryptobytes); + return DatatypeConverter.printBase64Binary(clearbytes); + + } catch (Exception e) { + LOG.error("Couldn't decrypt token", e); + return null; + } + } +} diff --git a/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/IDMMDSALStore.java b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/IDMMDSALStore.java new file mode 100644 index 00000000..88fba0ba --- /dev/null +++ b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/IDMMDSALStore.java @@ -0,0 +1,483 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.aaa.authn.mdsal.store; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.CheckedFuture; +import java.util.List; +import java.util.concurrent.ExecutionException; +import org.opendaylight.aaa.api.IDMStoreException; +import org.opendaylight.aaa.api.IDMStoreUtil; +import org.opendaylight.aaa.api.SHA256Calculator; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.Authentication; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Domain; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.DomainBuilder; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.DomainKey; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Grant; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.GrantBuilder; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.GrantKey; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Role; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.RoleBuilder; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.RoleKey; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.User; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.UserBuilder; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.UserKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Sharon Aicler - saichler@cisco.com + * + */ +public class IDMMDSALStore { + + private static final Logger LOG = LoggerFactory.getLogger(IDMMDSALStore.class); + private final DataBroker dataBroker; + + public IDMMDSALStore(DataBroker dataBroker) { + this.dataBroker = dataBroker; + } + + public static final String getString(String aValue, String bValue) { + if (aValue != null) + return aValue; + return bValue; + } + + public static final Boolean getBoolean(Boolean aValue, Boolean bValue) { + if (aValue != null) + return aValue; + return bValue; + } + + public static boolean waitForSubmit(CheckedFuture<Void, TransactionCommitFailedException> submit) { + // This can happen only when testing + if (submit == null) + return false; + while (!submit.isDone() && !submit.isCancelled()) { + try { + Thread.sleep(1000); + } catch (Exception err) { + LOG.error("Interrupted", err); + } + } + return submit.isCancelled(); + } + + // Domain methods + public Domain writeDomain(Domain domain) { + Preconditions.checkNotNull(domain); + Preconditions.checkNotNull(domain.getName()); + Preconditions.checkNotNull(domain.isEnabled()); + DomainBuilder b = new DomainBuilder(); + b.setDescription(domain.getDescription()); + b.setDomainid(domain.getName()); + b.setEnabled(domain.isEnabled()); + b.setName(domain.getName()); + b.setKey(new DomainKey(b.getName())); + domain = b.build(); + InstanceIdentifier<Domain> ID = InstanceIdentifier.create(Authentication.class).child( + Domain.class, new DomainKey(domain.getDomainid())); + WriteTransaction wrt = dataBroker.newWriteOnlyTransaction(); + wrt.put(LogicalDatastoreType.CONFIGURATION, ID, domain, true); + CheckedFuture<Void, TransactionCommitFailedException> submit = wrt.submit(); + if (!waitForSubmit(submit)) { + return domain; + } else { + return null; + } + } + + public Domain readDomain(String domainid) { + Preconditions.checkNotNull(domainid); + InstanceIdentifier<Domain> ID = InstanceIdentifier.create(Authentication.class).child( + Domain.class, new DomainKey(domainid)); + ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction(); + CheckedFuture<Optional<Domain>, ReadFailedException> read = rot.read( + LogicalDatastoreType.CONFIGURATION, ID); + if (read == null) { + LOG.error("Failed to read domain from data store"); + return null; + } + Optional<Domain> optional = null; + try { + optional = read.get(); + } catch (InterruptedException | ExecutionException e1) { + LOG.error("Failed to read domain from data store", e1); + return null; + } + + if (optional == null) + return null; + + if (!optional.isPresent()) + return null; + + return optional.get(); + } + + public Domain deleteDomain(String domainid) { + Preconditions.checkNotNull(domainid); + Domain domain = readDomain(domainid); + if (domain == null) { + LOG.error("Failed to delete domain from data store, unknown domain"); + return null; + } + InstanceIdentifier<Domain> ID = InstanceIdentifier.create(Authentication.class).child( + Domain.class, new DomainKey(domainid)); + WriteTransaction wrt = dataBroker.newWriteOnlyTransaction(); + wrt.delete(LogicalDatastoreType.CONFIGURATION, ID); + wrt.submit(); + return domain; + } + + public Domain updateDomain(Domain domain) throws IDMStoreException { + Preconditions.checkNotNull(domain); + Preconditions.checkNotNull(domain.getDomainid()); + Domain existing = readDomain(domain.getDomainid()); + DomainBuilder b = new DomainBuilder(); + b.setDescription(getString(domain.getDescription(), existing.getDescription())); + b.setName(existing.getName()); + b.setEnabled(getBoolean(domain.isEnabled(), existing.isEnabled())); + return writeDomain(b.build()); + } + + public List<Domain> getAllDomains() { + InstanceIdentifier<Authentication> id = InstanceIdentifier.create(Authentication.class); + ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction(); + CheckedFuture<Optional<Authentication>, ReadFailedException> read = rot.read( + LogicalDatastoreType.CONFIGURATION, id); + if (read == null) + return null; + + try { + if (read.get() == null) + return null; + if (read.get().isPresent()) { + Authentication auth = read.get().get(); + return auth.getDomain(); + } + } catch (Exception err) { + LOG.error("Failed to read domains", err); + } + return null; + } + + public List<Role> getAllRoles() { + InstanceIdentifier<Authentication> id = InstanceIdentifier.create(Authentication.class); + ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction(); + CheckedFuture<Optional<Authentication>, ReadFailedException> read = rot.read( + LogicalDatastoreType.CONFIGURATION, id); + if (read == null) + return null; + + try { + if (read.get() == null) + return null; + if (read.get().isPresent()) { + Authentication auth = read.get().get(); + return auth.getRole(); + } + } catch (Exception err) { + LOG.error("Failed to read domains", err); + } + return null; + } + + public List<User> getAllUsers() { + InstanceIdentifier<Authentication> id = InstanceIdentifier.create(Authentication.class); + ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction(); + CheckedFuture<Optional<Authentication>, ReadFailedException> read = rot.read( + LogicalDatastoreType.CONFIGURATION, id); + if (read == null) + return null; + + try { + if (read.get() == null) + return null; + if (read.get().isPresent()) { + Authentication auth = read.get().get(); + return auth.getUser(); + } + } catch (Exception err) { + LOG.error("Failed to read domains", err); + } + return null; + } + + public List<Grant> getAllGrants() { + InstanceIdentifier<Authentication> id = InstanceIdentifier.create(Authentication.class); + ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction(); + CheckedFuture<Optional<Authentication>, ReadFailedException> read = rot.read( + LogicalDatastoreType.CONFIGURATION, id); + if (read == null) + return null; + + try { + if (read.get() == null) + return null; + if (read.get().isPresent()) { + Authentication auth = read.get().get(); + return auth.getGrant(); + } + } catch (Exception err) { + LOG.error("Failed to read domains", err); + } + return null; + } + + // Role methods + public Role writeRole(Role role) { + Preconditions.checkNotNull(role); + Preconditions.checkNotNull(role.getName()); + Preconditions.checkNotNull(role.getDomainid()); + Preconditions.checkNotNull(readDomain(role.getDomainid())); + RoleBuilder b = new RoleBuilder(); + b.setDescription(role.getDescription()); + b.setRoleid(IDMStoreUtil.createRoleid(role.getName(), role.getDomainid())); + b.setKey(new RoleKey(b.getRoleid())); + b.setName(role.getName()); + b.setDomainid(role.getDomainid()); + role = b.build(); + InstanceIdentifier<Role> ID = InstanceIdentifier.create(Authentication.class).child( + Role.class, new RoleKey(role.getRoleid())); + WriteTransaction wrt = dataBroker.newWriteOnlyTransaction(); + wrt.put(LogicalDatastoreType.CONFIGURATION, ID, role, true); + CheckedFuture<Void, TransactionCommitFailedException> submit = wrt.submit(); + if (!waitForSubmit(submit)) { + return role; + } else { + return null; + } + } + + public Role readRole(String roleid) { + Preconditions.checkNotNull(roleid); + InstanceIdentifier<Role> ID = InstanceIdentifier.create(Authentication.class).child( + Role.class, new RoleKey(roleid)); + ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction(); + CheckedFuture<Optional<Role>, ReadFailedException> read = rot.read( + LogicalDatastoreType.CONFIGURATION, ID); + if (read == null) { + LOG.error("Failed to read role from data store"); + return null; + } + Optional<Role> optional = null; + try { + optional = read.get(); + } catch (InterruptedException | ExecutionException e1) { + LOG.error("Failed to read role from data store", e1); + return null; + } + + if (optional == null) + return null; + + if (!optional.isPresent()) + return null; + + return optional.get(); + } + + public Role deleteRole(String roleid) { + Preconditions.checkNotNull(roleid); + Role role = readRole(roleid); + if (role == null) { + LOG.error("Failed to delete role from data store, unknown role"); + return null; + } + InstanceIdentifier<Role> ID = InstanceIdentifier.create(Authentication.class).child( + Role.class, new RoleKey(roleid)); + WriteTransaction wrt = dataBroker.newWriteOnlyTransaction(); + wrt.delete(LogicalDatastoreType.CONFIGURATION, ID); + wrt.submit(); + return role; + } + + public Role updateRole(Role role) { + Preconditions.checkNotNull(role); + Preconditions.checkNotNull(role.getRoleid()); + Role existing = readRole(role.getRoleid()); + RoleBuilder b = new RoleBuilder(); + b.setDescription(getString(role.getDescription(), existing.getDescription())); + b.setName(existing.getName()); + b.setDomainid(existing.getDomainid()); + return writeRole(b.build()); + } + + // User methods + public User writeUser(User user) throws IDMStoreException { + Preconditions.checkNotNull(user); + Preconditions.checkNotNull(user.getName()); + Preconditions.checkNotNull(user.getDomainid()); + Preconditions.checkNotNull(readDomain(user.getDomainid())); + UserBuilder b = new UserBuilder(); + if (user.getSalt() == null) { + b.setSalt(SHA256Calculator.generateSALT()); + } else { + b.setSalt(user.getSalt()); + } + b.setUserid(IDMStoreUtil.createUserid(user.getName(), user.getDomainid())); + b.setDescription(user.getDescription()); + b.setDomainid(user.getDomainid()); + b.setEmail(user.getEmail()); + b.setEnabled(user.isEnabled()); + b.setKey(new UserKey(b.getUserid())); + b.setName(user.getName()); + b.setPassword(SHA256Calculator.getSHA256(user.getPassword(), b.getSalt())); + user = b.build(); + InstanceIdentifier<User> ID = InstanceIdentifier.create(Authentication.class).child( + User.class, new UserKey(user.getUserid())); + WriteTransaction wrt = dataBroker.newWriteOnlyTransaction(); + wrt.put(LogicalDatastoreType.CONFIGURATION, ID, user, true); + CheckedFuture<Void, TransactionCommitFailedException> submit = wrt.submit(); + if (!waitForSubmit(submit)) { + return user; + } else { + return null; + } + } + + public User readUser(String userid) { + Preconditions.checkNotNull(userid); + InstanceIdentifier<User> ID = InstanceIdentifier.create(Authentication.class).child( + User.class, new UserKey(userid)); + ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction(); + CheckedFuture<Optional<User>, ReadFailedException> read = rot.read( + LogicalDatastoreType.CONFIGURATION, ID); + if (read == null) { + LOG.error("Failed to read user from data store"); + return null; + } + Optional<User> optional = null; + try { + optional = read.get(); + } catch (InterruptedException | ExecutionException e1) { + LOG.error("Failed to read domain from data store", e1); + return null; + } + + if (optional == null) + return null; + + if (!optional.isPresent()) + return null; + + return optional.get(); + } + + public User deleteUser(String userid) { + Preconditions.checkNotNull(userid); + User user = readUser(userid); + if (user == null) { + LOG.error("Failed to delete user from data store, unknown user"); + return null; + } + InstanceIdentifier<User> ID = InstanceIdentifier.create(Authentication.class).child( + User.class, new UserKey(userid)); + WriteTransaction wrt = dataBroker.newWriteOnlyTransaction(); + wrt.delete(LogicalDatastoreType.CONFIGURATION, ID); + wrt.submit(); + return user; + } + + public User updateUser(User user) throws IDMStoreException { + Preconditions.checkNotNull(user); + Preconditions.checkNotNull(user.getUserid()); + User existing = readUser(user.getUserid()); + UserBuilder b = new UserBuilder(); + b.setName(existing.getName()); + b.setDomainid(existing.getDomainid()); + b.setDescription(getString(user.getDescription(), existing.getDescription())); + b.setEmail(getString(user.getEmail(), existing.getEmail())); + b.setEnabled(getBoolean(user.isEnabled(), existing.isEnabled())); + b.setPassword(getString(user.getPassword(), existing.getPassword())); + b.setSalt(getString(user.getSalt(), existing.getSalt())); + return writeUser(b.build()); + } + + // Grant methods + public Grant writeGrant(Grant grant) throws IDMStoreException { + Preconditions.checkNotNull(grant); + Preconditions.checkNotNull(grant.getDomainid()); + Preconditions.checkNotNull(grant.getUserid()); + Preconditions.checkNotNull(grant.getRoleid()); + Preconditions.checkNotNull(readDomain(grant.getDomainid())); + Preconditions.checkNotNull(readUser(grant.getUserid())); + Preconditions.checkNotNull(readRole(grant.getRoleid())); + GrantBuilder b = new GrantBuilder(); + b.setDomainid(grant.getDomainid()); + b.setRoleid(grant.getRoleid()); + b.setUserid(grant.getUserid()); + b.setGrantid(IDMStoreUtil.createGrantid(grant.getUserid(), grant.getDomainid(), + grant.getRoleid())); + b.setKey(new GrantKey(b.getGrantid())); + grant = b.build(); + InstanceIdentifier<Grant> ID = InstanceIdentifier.create(Authentication.class).child( + Grant.class, new GrantKey(grant.getGrantid())); + WriteTransaction wrt = dataBroker.newWriteOnlyTransaction(); + wrt.put(LogicalDatastoreType.CONFIGURATION, ID, grant, true); + CheckedFuture<Void, TransactionCommitFailedException> submit = wrt.submit(); + if (!waitForSubmit(submit)) { + return grant; + } else { + return null; + } + } + + public Grant readGrant(String grantid) { + Preconditions.checkNotNull(grantid); + InstanceIdentifier<Grant> ID = InstanceIdentifier.create(Authentication.class).child( + Grant.class, new GrantKey(grantid)); + ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction(); + CheckedFuture<Optional<Grant>, ReadFailedException> read = rot.read( + LogicalDatastoreType.CONFIGURATION, ID); + if (read == null) { + LOG.error("Failed to read grant from data store"); + return null; + } + Optional<Grant> optional = null; + try { + optional = read.get(); + } catch (InterruptedException | ExecutionException e1) { + LOG.error("Failed to read domain from data store", e1); + return null; + } + + if (optional == null) + return null; + + if (!optional.isPresent()) + return null; + + return optional.get(); + } + + public Grant deleteGrant(String grantid) { + Preconditions.checkNotNull(grantid); + Grant grant = readGrant(grantid); + if (grant == null) { + LOG.error("Failed to delete grant from data store, unknown grant"); + return null; + } + InstanceIdentifier<Grant> ID = InstanceIdentifier.create(Authentication.class).child( + Grant.class, new GrantKey(grantid)); + WriteTransaction wrt = dataBroker.newWriteOnlyTransaction(); + wrt.delete(LogicalDatastoreType.CONFIGURATION, ID); + wrt.submit(); + return grant; + } +} diff --git a/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/IDMObject2MDSAL.java b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/IDMObject2MDSAL.java new file mode 100644 index 00000000..0b58ced7 --- /dev/null +++ b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/IDMObject2MDSAL.java @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.aaa.authn.mdsal.store; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.opendaylight.aaa.api.model.Domain; +import org.opendaylight.aaa.api.model.Grant; +import org.opendaylight.aaa.api.model.Role; +import org.opendaylight.aaa.api.model.User; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.DomainBuilder; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.GrantBuilder; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.RoleBuilder; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.UserBuilder; +import org.opendaylight.yangtools.yang.binding.DataObject; +/** + * + * @author saichler@gmail.com + * + * This class is a codec to convert between MDSAL objects and IDM model objects. It is doing so via reflection when it assumes that the MDSAL + * Object and the IDM model object has the same method names. + */ +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Sharon Aicler - saichler@cisco.com + * + */ +public abstract class IDMObject2MDSAL { + private static final Logger LOG = LoggerFactory.getLogger(IDMObject2MDSAL.class); + // this is a Map mapping between the class type of the IDM Model object to a + // structure containing the corresponding setters and getter methods + // in MDSAL object + private static Map<Class<?>, ConvertionMethods> typesMethods = new HashMap<Class<?>, ConvertionMethods>(); + + // This method generically via reflection receive a MDSAL object and the + // corresponding IDM model object class type and + // creates an IDM model element from the MDSAL element + private static Object fromMDSALObject(Object mdsalObject, Class<?> type) throws Exception { + if (mdsalObject == null) + return null; + Object result = type.newInstance(); + ConvertionMethods cm = typesMethods.get(type); + if (cm == null) { + cm = new ConvertionMethods(); + typesMethods.put(type, cm); + Method methods[] = type.getMethods(); + for (Method m : methods) { + if (m.getName().startsWith("set")) { + cm.setMethods.add(m); + Method gm = null; + if (m.getParameterTypes()[0].equals(Boolean.class) + || m.getParameterTypes()[0].equals(boolean.class)) + gm = ((DataObject) mdsalObject).getImplementedInterface().getMethod( + "is" + m.getName().substring(3), (Class[]) null); + else { + try { + gm = ((DataObject) mdsalObject).getImplementedInterface().getMethod( + "get" + m.getName().substring(3), (Class[]) null); + } catch (Exception err) { + LOG.error("Error associating get call", err); + } + } + cm.getMethods.put(m.getName(), gm); + } + } + } + for (Method m : cm.setMethods) { + try { + m.invoke( + result, + new Object[] { cm.getMethods.get(m.getName()).invoke(mdsalObject, + (Object[]) null) }); + } catch (Exception err) { + LOG.error("Error invoking reflection method", err); + } + } + return result; + } + + // This method generically use reflection to receive an IDM model object and + // the corresponsing MDSAL object and creates + // a MDSAL object out of the IDM model object + private static Object toMDSALObject(Object object, Class<?> mdSalBuilderType) throws Exception { + if (object == null) + return null; + Object result = mdSalBuilderType.newInstance(); + ConvertionMethods cm = typesMethods.get(mdSalBuilderType); + if (cm == null) { + cm = new ConvertionMethods(); + typesMethods.put(mdSalBuilderType, cm); + Method methods[] = mdSalBuilderType.getMethods(); + for (Method m : methods) { + if (m.getName().startsWith("set")) { + try { + Method gm = null; + if (m.getParameterTypes()[0].equals(Boolean.class) + || m.getParameterTypes()[0].equals(boolean.class)) + gm = object.getClass().getMethod("is" + m.getName().substring(3), + (Class[]) null); + else + gm = object.getClass().getMethod("get" + m.getName().substring(3), + (Class[]) null); + cm.getMethods.put(m.getName(), gm); + cm.setMethods.add(m); + } catch (NoSuchMethodException err) { + } + } + } + cm.builderMethod = mdSalBuilderType.getMethod("build", (Class[]) null); + } + for (Method m : cm.setMethods) { + m.invoke(result, + new Object[] { cm.getMethods.get(m.getName()).invoke(object, (Object[]) null) }); + } + + return cm.builderMethod.invoke(result, (Object[]) null); + } + + // A struccture class to hold the getters & setters of each type to speed + // things up + private static class ConvertionMethods { + private List<Method> setMethods = new ArrayList<Method>(); + private Map<String, Method> getMethods = new HashMap<String, Method>(); + private Method builderMethod = null; + } + + // Convert Domain + public static org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Domain toMDSALDomain( + Domain domain) { + try { + return (org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Domain) toMDSALObject( + domain, DomainBuilder.class); + } catch (Exception err) { + LOG.error("Error converting domain to MDSAL object", err); + return null; + } + } + + public static Domain toIDMDomain( + org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Domain domain) { + try { + return (Domain) fromMDSALObject(domain, Domain.class); + } catch (Exception err) { + LOG.error("Error converting domain from MDSAL to IDM object", err); + return null; + } + } + + // Convert Role + public static org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Role toMDSALRole( + Role role) { + try { + return (org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Role) toMDSALObject( + role, RoleBuilder.class); + } catch (Exception err) { + LOG.error("Error converting role to MDSAL object", err); + return null; + } + } + + public static Role toIDMRole( + org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Role role) { + try { + return (Role) fromMDSALObject(role, Role.class); + } catch (Exception err) { + LOG.error("Error converting role fom MDSAL to IDM object", err); + return null; + } + } + + // Convert User + public static org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.User toMDSALUser( + User user) { + try { + return (org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.User) toMDSALObject( + user, UserBuilder.class); + } catch (Exception err) { + LOG.error("Error converting user to MDSAL object", err); + return null; + } + } + + public static User toIDMUser( + org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.User user) { + try { + return (User) fromMDSALObject(user, User.class); + } catch (Exception err) { + LOG.error("Error converting user from MDSAL to IDM object", err); + return null; + } + } + + // Convert Grant + public static org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Grant toMDSALGrant( + Grant grant) { + try { + return (org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Grant) toMDSALObject( + grant, GrantBuilder.class); + } catch (Exception err) { + LOG.error("Error converting grant to MDSAL object", err); + return null; + } + } + + public static Grant toIDMGrant( + org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Grant grant) { + try { + return (Grant) fromMDSALObject(grant, Grant.class); + } catch (Exception err) { + LOG.error("Error converting grant from MDSAL to IDM object", err); + return null; + } + } +} diff --git a/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/IDMStore.java b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/IDMStore.java new file mode 100644 index 00000000..69bc1d52 --- /dev/null +++ b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/IDMStore.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.aaa.authn.mdsal.store; + +import java.util.List; +import org.opendaylight.aaa.api.IDMStoreException; +import org.opendaylight.aaa.api.IDMStoreUtil; +import org.opendaylight.aaa.api.IIDMStore; +import org.opendaylight.aaa.api.model.Domain; +import org.opendaylight.aaa.api.model.Domains; +import org.opendaylight.aaa.api.model.Grant; +import org.opendaylight.aaa.api.model.Grants; +import org.opendaylight.aaa.api.model.Role; +import org.opendaylight.aaa.api.model.Roles; +import org.opendaylight.aaa.api.model.User; +import org.opendaylight.aaa.api.model.Users; + +/** + * @author Sharon Aicler - saichler@cisco.com + * + */ +public class IDMStore implements IIDMStore { + private final IDMMDSALStore mdsalStore; + + public IDMStore(IDMMDSALStore mdsalStore) { + this.mdsalStore = mdsalStore; + } + + @Override + public Domain writeDomain(Domain domain) throws IDMStoreException { + return IDMObject2MDSAL.toIDMDomain(mdsalStore.writeDomain(IDMObject2MDSAL.toMDSALDomain(domain))); + } + + @Override + public Domain readDomain(String domainid) throws IDMStoreException { + return IDMObject2MDSAL.toIDMDomain(mdsalStore.readDomain(domainid)); + } + + @Override + public Domain deleteDomain(String domainid) throws IDMStoreException { + return IDMObject2MDSAL.toIDMDomain(mdsalStore.deleteDomain(domainid)); + } + + @Override + public Domain updateDomain(Domain domain) throws IDMStoreException { + return IDMObject2MDSAL.toIDMDomain(mdsalStore.updateDomain(IDMObject2MDSAL.toMDSALDomain(domain))); + } + + @Override + public Domains getDomains() throws IDMStoreException { + Domains domains = new Domains(); + List<org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Domain> mdSalDomains = mdsalStore.getAllDomains(); + for (org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Domain d : mdSalDomains) { + domains.getDomains().add(IDMObject2MDSAL.toIDMDomain(d)); + } + return domains; + } + + @Override + public Role writeRole(Role role) throws IDMStoreException { + return IDMObject2MDSAL.toIDMRole(mdsalStore.writeRole(IDMObject2MDSAL.toMDSALRole(role))); + } + + @Override + public Role readRole(String roleid) throws IDMStoreException { + return IDMObject2MDSAL.toIDMRole(mdsalStore.readRole(roleid)); + } + + @Override + public Role deleteRole(String roleid) throws IDMStoreException { + return IDMObject2MDSAL.toIDMRole(mdsalStore.deleteRole(roleid)); + } + + @Override + public Role updateRole(Role role) throws IDMStoreException { + return IDMObject2MDSAL.toIDMRole(mdsalStore.writeRole(IDMObject2MDSAL.toMDSALRole(role))); + } + + @Override + public User writeUser(User user) throws IDMStoreException { + return IDMObject2MDSAL.toIDMUser(mdsalStore.writeUser(IDMObject2MDSAL.toMDSALUser(user))); + } + + @Override + public User readUser(String userid) throws IDMStoreException { + return IDMObject2MDSAL.toIDMUser(mdsalStore.readUser(userid)); + } + + @Override + public User deleteUser(String userid) throws IDMStoreException { + return IDMObject2MDSAL.toIDMUser(mdsalStore.deleteUser(userid)); + } + + @Override + public User updateUser(User user) throws IDMStoreException { + return IDMObject2MDSAL.toIDMUser(mdsalStore.writeUser(IDMObject2MDSAL.toMDSALUser(user))); + } + + @Override + public Grant writeGrant(Grant grant) throws IDMStoreException { + return IDMObject2MDSAL.toIDMGrant(mdsalStore.writeGrant(IDMObject2MDSAL.toMDSALGrant(grant))); + } + + @Override + public Grant readGrant(String grantid) throws IDMStoreException { + return IDMObject2MDSAL.toIDMGrant(mdsalStore.readGrant(grantid)); + } + + @Override + public Grant deleteGrant(String grantid) throws IDMStoreException { + return IDMObject2MDSAL.toIDMGrant(mdsalStore.readGrant(grantid)); + } + + @Override + public Roles getRoles() throws IDMStoreException { + Roles roles = new Roles(); + List<org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Role> mdSalRoles = mdsalStore.getAllRoles(); + for (org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Role r : mdSalRoles) { + roles.getRoles().add(IDMObject2MDSAL.toIDMRole(r)); + } + return roles; + } + + @Override + public Users getUsers() throws IDMStoreException { + Users users = new Users(); + List<org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.User> mdSalUsers = mdsalStore.getAllUsers(); + for (org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.User u : mdSalUsers) { + users.getUsers().add(IDMObject2MDSAL.toIDMUser(u)); + } + return users; + } + + @Override + public Users getUsers(String username, String domain) throws IDMStoreException { + Users users = new Users(); + List<org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.User> mdSalUsers = mdsalStore.getAllUsers(); + for (org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.User u : mdSalUsers) { + if (u.getDomainid().equals(domain) && u.getName().equals(username)) { + users.getUsers().add(IDMObject2MDSAL.toIDMUser(u)); + } + } + return users; + } + + @Override + public Grants getGrants(String domainid, String userid) throws IDMStoreException { + Grants grants = new Grants(); + List<org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Grant> mdSalGrants = mdsalStore.getAllGrants(); + String currentGrantUserId, currentGrantDomainId; + for (org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Grant g : mdSalGrants) { + currentGrantUserId = g.getUserid(); + currentGrantDomainId = g.getDomainid(); + if (currentGrantUserId.equals(userid) && currentGrantDomainId.equals(domainid)) { + grants.getGrants().add(IDMObject2MDSAL.toIDMGrant(g)); + } + } + return grants; + } + + @Override + public Grants getGrants(String userid) throws IDMStoreException { + Grants grants = new Grants(); + List<org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Grant> mdSalGrants = mdsalStore.getAllGrants(); + for (org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Grant g : mdSalGrants) { + if (g.getUserid().equals(userid)) { + grants.getGrants().add(IDMObject2MDSAL.toIDMGrant(g)); + } + } + return grants; + } + + @Override + public Grant readGrant(String domainid, String userid, String roleid) throws IDMStoreException { + return readGrant(IDMStoreUtil.createGrantid(userid, domainid, roleid)); + } +} diff --git a/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/util/AuthNStoreUtil.java b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/util/AuthNStoreUtil.java new file mode 100644 index 00000000..6ef58109 --- /dev/null +++ b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/aaa/authn/mdsal/store/util/AuthNStoreUtil.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.aaa.authn.mdsal.store.util; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.opendaylight.aaa.AuthenticationBuilder; +import org.opendaylight.aaa.api.Authentication; +import org.opendaylight.aaa.api.Claim; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.TokenCacheTimes; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.Tokencache; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.token_cache_times.TokenList; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.token_cache_times.TokenListBuilder; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.token_cache_times.TokenListKey; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.token_cache_times.token_list.UserTokens; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.token_cache_times.token_list.UserTokensBuilder; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.token_cache_times.token_list.UserTokensKey; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.tokencache.Claims; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.tokencache.ClaimsBuilder; +import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.tokencache.ClaimsKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class AuthNStoreUtil { + + public static InstanceIdentifier<Claims> createInstIdentifierForTokencache(String token) { + if (token == null || token.length() == 0) + return null; + + InstanceIdentifier<Claims> claims_iid = InstanceIdentifier.builder(Tokencache.class) + .child(Claims.class, + new ClaimsKey(token)) + .build(); + return claims_iid; + } + + public static InstanceIdentifier<UserTokens> createInstIdentifierUserTokens(String userId, + String token) { + if (userId == null || userId.length() == 0 || token == null || token.length() == 0) + return null; + + InstanceIdentifier<UserTokens> userTokens_iid = InstanceIdentifier.builder( + TokenCacheTimes.class) + .child(TokenList.class, + new TokenListKey( + userId)) + .child(UserTokens.class, + new UserTokensKey( + token)) + .build(); + return userTokens_iid; + } + + public static Claims createClaimsRecord(String token, Authentication auth) { + if (auth == null || token == null || token.length() == 0) + return null; + + ClaimsKey claimsKey = new ClaimsKey(token); + ClaimsBuilder claimsBuilder = new ClaimsBuilder(); + claimsBuilder.setClientId(auth.clientId()); + claimsBuilder.setDomain(auth.domain()); + claimsBuilder.setKey(claimsKey); + List<String> roles = new ArrayList<String>(); + roles.addAll(auth.roles()); + claimsBuilder.setRoles(roles); + claimsBuilder.setToken(token); + claimsBuilder.setUser(auth.user()); + claimsBuilder.setUserId(auth.userId()); + return claimsBuilder.build(); + } + + public static UserTokens createUserTokens(String token, Long expiration) { + if (expiration == null || token == null || token.length() == 0) + return null; + + UserTokensBuilder userTokensBuilder = new UserTokensBuilder(); + userTokensBuilder.setTokenid(token); + BigInteger timestamp = BigInteger.valueOf(System.currentTimeMillis()); + userTokensBuilder.setTimestamp(timestamp); + userTokensBuilder.setExpiration(expiration); + userTokensBuilder.setKey(new UserTokensKey(token)); + return userTokensBuilder.build(); + } + + public static TokenList createTokenList(UserTokens tokens, String userId) { + if (tokens == null || userId == null || userId.length() == 0) + return null; + + TokenListBuilder tokenListBuilder = new TokenListBuilder(); + tokenListBuilder.setUserId(userId); + tokenListBuilder.setKey(new TokenListKey(userId)); + List<UserTokens> userTokens = new ArrayList<UserTokens>(); + userTokens.add(tokens); + tokenListBuilder.setUserTokens(userTokens); + return tokenListBuilder.build(); + } + + public static Authentication convertClaimToAuthentication(final Claims claims, Long expiration) { + if (claims == null) + return null; + + Claim claim = new Claim() { + @Override + public String clientId() { + return claims.getClientId(); + } + + @Override + public String userId() { + return claims.getUserId(); + } + + @Override + public String user() { + return claims.getUser(); + } + + @Override + public String domain() { + return claims.getDomain(); + } + + @Override + public Set<String> roles() { + return new HashSet<>(claims.getRoles()); + } + }; + AuthenticationBuilder authBuilder = new AuthenticationBuilder(claim); + authBuilder.setExpiration(expiration); + return authBuilder.build(); + } +} diff --git a/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/mdsal/store/rev141031/AuthNStoreModule.java b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/mdsal/store/rev141031/AuthNStoreModule.java new file mode 100644 index 00000000..0631170e --- /dev/null +++ b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/mdsal/store/rev141031/AuthNStoreModule.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + +package org.opendaylight.yang.gen.v1.config.aaa.authn.mdsal.store.rev141031; + +import org.opendaylight.aaa.api.IIDMStore; +import org.opendaylight.aaa.api.TokenStore; +import org.opendaylight.aaa.authn.mdsal.store.AuthNStore; +import org.opendaylight.aaa.authn.mdsal.store.IDMMDSALStore; +import org.opendaylight.aaa.authn.mdsal.store.IDMStore; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +public class AuthNStoreModule + extends + org.opendaylight.yang.gen.v1.config.aaa.authn.mdsal.store.rev141031.AbstractAuthNStoreModule { + private BundleContext bundleContext; + + public AuthNStoreModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, + org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + public AuthNStoreModule( + org.opendaylight.controller.config.api.ModuleIdentifier identifier, + org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, + org.opendaylight.yang.gen.v1.config.aaa.authn.mdsal.store.rev141031.AuthNStoreModule oldModule, + java.lang.AutoCloseable oldInstance) { + super(identifier, dependencyResolver, oldModule, oldInstance); + } + + @Override + public void customValidation() { + // add custom validation form module attributes here. + } + + @Override + public java.lang.AutoCloseable createInstance() { + + DataBroker dataBrokerService = getDataBrokerDependency(); + final AuthNStore authNStore = new AuthNStore(dataBrokerService, getPassword()); + final IDMMDSALStore mdsalStore = new IDMMDSALStore(dataBrokerService); + final IDMStore idmStore = new IDMStore(mdsalStore); + + authNStore.setTimeToLive(getTimeToLive()); + + // Register the MD-SAL Token store with OSGI + final ServiceRegistration<?> serviceRegistration = bundleContext.registerService( + TokenStore.class.getName(), authNStore, null); + final ServiceRegistration<?> idmServiceRegistration = bundleContext.registerService( + IIDMStore.class.getName(), idmStore, null); + final class AutoCloseableStore implements AutoCloseable { + + @Override + public void close() throws Exception { + serviceRegistration.unregister(); + idmServiceRegistration.unregister(); + authNStore.close(); + } + } + + return new AutoCloseableStore(); + + // return authNStore; + + // throw new java.lang.UnsupportedOperationException(); + } + + /** + * @param bundleContext + */ + public void setBundleContext(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } + + /** + * @return the bundleContext + */ + public BundleContext getBundleContext() { + return bundleContext; + } + +} diff --git a/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/mdsal/store/rev141031/AuthNStoreModuleFactory.java b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/mdsal/store/rev141031/AuthNStoreModuleFactory.java new file mode 100644 index 00000000..b1e278fa --- /dev/null +++ b/odl-aaa-moon/aaa-authn-mdsal-store/aaa-authn-mdsal-store-impl/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/mdsal/store/rev141031/AuthNStoreModuleFactory.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + +/* + * Generated file + * + * Generated from: yang module name: aaa-authn-mdsal-store-cfg yang module local name: aaa-authn-mdsal-store + * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator + * Generated at: Thu Mar 19 18:06:18 CET 2015 + * + * Do not modify this file unless it is present under src/main directory + */ +package org.opendaylight.yang.gen.v1.config.aaa.authn.mdsal.store.rev141031; + +import org.opendaylight.controller.config.api.DependencyResolver; +import org.osgi.framework.BundleContext; + +public class AuthNStoreModuleFactory + extends + org.opendaylight.yang.gen.v1.config.aaa.authn.mdsal.store.rev141031.AbstractAuthNStoreModuleFactory { + + @Override + public AuthNStoreModule instantiateModule(String instanceName, + DependencyResolver dependencyResolver, BundleContext bundleContext) { + AuthNStoreModule module = super.instantiateModule(instanceName, dependencyResolver, + bundleContext); + module.setBundleContext(bundleContext); + return module; + } + + @Override + public AuthNStoreModule instantiateModule(String instanceName, + DependencyResolver dependencyResolver, AuthNStoreModule oldModule, + AutoCloseable oldInstance, BundleContext bundleContext) { + AuthNStoreModule module = super.instantiateModule(instanceName, dependencyResolver, + oldModule, oldInstance, bundleContext); + module.setBundleContext(bundleContext); + return module; + } +} |