From e63b03f3d7e4851e008e4bb4d184982c2c0bd229 Mon Sep 17 00:00:00 2001 From: WuKong Date: Tue, 24 May 2016 17:13:17 +0200 Subject: odl/aaa clone Change-Id: I2b72c16aa3245e02d985a2c6189aacee7caad36e Signed-off-by: WuKong --- .../org/opendaylight/aaa/idm/IdmLightProxy.java | 208 +++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 odl-aaa-moon/aaa-idmlight/src/main/java/org/opendaylight/aaa/idm/IdmLightProxy.java (limited to 'odl-aaa-moon/aaa-idmlight/src/main/java/org/opendaylight/aaa/idm/IdmLightProxy.java') diff --git a/odl-aaa-moon/aaa-idmlight/src/main/java/org/opendaylight/aaa/idm/IdmLightProxy.java b/odl-aaa-moon/aaa-idmlight/src/main/java/org/opendaylight/aaa/idm/IdmLightProxy.java new file mode 100644 index 00000000..d17d2b13 --- /dev/null +++ b/odl-aaa-moon/aaa-idmlight/src/main/java/org/opendaylight/aaa/idm/IdmLightProxy.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2014, 2015 Hewlett-Packard Development Company, L.P. 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.idm; + +import com.google.common.base.Preconditions; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import org.opendaylight.aaa.ClaimBuilder; +import org.opendaylight.aaa.api.AuthenticationException; +import org.opendaylight.aaa.api.Claim; +import org.opendaylight.aaa.api.CredentialAuth; +import org.opendaylight.aaa.api.IDMStoreException; +import org.opendaylight.aaa.api.IIDMStore; +import org.opendaylight.aaa.api.IdMService; +import org.opendaylight.aaa.api.PasswordCredentials; +import org.opendaylight.aaa.api.SHA256Calculator; +import org.opendaylight.aaa.api.model.Domain; +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.User; +import org.opendaylight.aaa.api.model.Users; +import org.opendaylight.yang.gen.v1.config.aaa.authn.idmlight.rev151204.AAAIDMLightModule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * An OSGi proxy for the IdmLight server. + * + */ +public class IdmLightProxy implements CredentialAuth, IdMService { + + private static final Logger LOG = LoggerFactory.getLogger(IdmLightProxy.class); + + /** + * claimCache is responsible for storing the active claims per domain. The + * outer map is keyed by domain, and the inner map is keyed by + * PasswordCredentials. + */ + private static Map> claimCache = new ConcurrentHashMap<>(); + + // adds a store for the default "sdn" domain + static { + claimCache.put(IIDMStore.DEFAULT_DOMAIN, + new ConcurrentHashMap()); + } + + @Override + public Claim authenticate(PasswordCredentials creds) { + Preconditions.checkNotNull(creds); + Preconditions.checkNotNull(creds.username()); + Preconditions.checkNotNull(creds.password()); + String domain = creds.domain() == null ? IIDMStore.DEFAULT_DOMAIN : creds.domain(); + // FIXME: Add cache invalidation + Map cache = claimCache.get(domain); + if (cache == null) { + cache = new ConcurrentHashMap(); + claimCache.put(domain, cache); + } + Claim claim = cache.get(creds); + if (claim == null) { + synchronized (claimCache) { + claim = cache.get(creds); + if (claim == null) { + claim = dbAuthenticate(creds); + if (claim != null) { + cache.put(creds, claim); + } + } + } + } + return claim; + } + + /** + * Clears the cache of any active claims. + */ + public static synchronized void clearClaimCache() { + LOG.info("Clearing the claim cache"); + for (Map cache : claimCache.values()) { + cache.clear(); + } + } + + private static Claim dbAuthenticate(PasswordCredentials creds) { + Domain domain = null; + User user = null; + String credsDomain = creds.domain() == null ? IIDMStore.DEFAULT_DOMAIN : creds.domain(); + // check to see domain exists + // TODO: ensure domain names are unique change to 'getDomain' + LOG.debug("get domain"); + try { + domain = AAAIDMLightModule.getStore().readDomain(credsDomain); + if (domain == null) { + throw new AuthenticationException("Domain :" + credsDomain + " does not exist"); + } + } catch (IDMStoreException e) { + throw new AuthenticationException("Error while fetching domain", e); + } + + // check to see user exists and passes cred check + try { + LOG.debug("check user / pwd"); + Users users = AAAIDMLightModule.getStore().getUsers(creds.username(), credsDomain); + List userList = users.getUsers(); + if (userList.size() == 0) { + throw new AuthenticationException("User :" + creds.username() + + " does not exist in domain " + credsDomain); + } + user = userList.get(0); + if (!SHA256Calculator.getSHA256(creds.password(), user.getSalt()).equals( + user.getPassword())) { + throw new AuthenticationException("UserName / Password not found"); + } + + // get all grants & roles for this domain and user + LOG.debug("get grants"); + List roles = new ArrayList(); + Grants grants = AAAIDMLightModule.getStore().getGrants(domain.getDomainid(), + user.getUserid()); + List grantList = grants.getGrants(); + for (int z = 0; z < grantList.size(); z++) { + Grant grant = grantList.get(z); + Role role = AAAIDMLightModule.getStore().readRole(grant.getRoleid()); + if (role != null) { + roles.add(role.getName()); + } + } + + // build up the claim + LOG.debug("build a claim"); + ClaimBuilder claim = new ClaimBuilder(); + claim.setUserId(user.getUserid().toString()); + claim.setUser(creds.username()); + claim.setDomain(credsDomain); + for (int z = 0; z < roles.size(); z++) { + claim.addRole(roles.get(z)); + } + return claim.build(); + } catch (IDMStoreException se) { + throw new AuthenticationException("idm data store exception :" + se.toString() + se); + } + } + + @Override + public List listDomains(String userId) { + LOG.debug("list Domains for userId: {}", userId); + List domains = new ArrayList(); + try { + Grants grants = AAAIDMLightModule.getStore().getGrants(userId); + List grantList = grants.getGrants(); + for (int z = 0; z < grantList.size(); z++) { + Grant grant = grantList.get(z); + Domain domain = AAAIDMLightModule.getStore().readDomain(grant.getDomainid()); + domains.add(domain.getName()); + } + return domains; + } catch (IDMStoreException se) { + LOG.warn("error getting domains ", se.toString(), se); + return domains; + } + + } + + @Override + public List listRoles(String userId, String domainName) { + LOG.debug("listRoles"); + List roles = new ArrayList(); + + try { + // find domain name for specied domain name + String did = null; + try { + Domain domain = AAAIDMLightModule.getStore().readDomain(domainName); + if (domain == null) { + LOG.debug("DomainName: {}", domainName + " Not found!"); + return roles; + } + did = domain.getDomainid(); + } catch (IDMStoreException e) { + return roles; + } + + // find all grants for uid and did + Grants grants = AAAIDMLightModule.getStore().getGrants(did, userId); + List grantList = grants.getGrants(); + for (int z = 0; z < grantList.size(); z++) { + Grant grant = grantList.get(z); + Role role = AAAIDMLightModule.getStore().readRole(grant.getRoleid()); + roles.add(role.getName()); + } + + return roles; + } catch (IDMStoreException se) { + LOG.warn("error getting roles ", se.toString(), se); + return roles; + } + } +} -- cgit 1.2.3-korg