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 --- odl-aaa-moon/aaa-authn-sssd/pom.xml | 88 +++++++++ .../java/org/opendaylight/aaa/sssd/Activator.java | 28 +++ .../org/opendaylight/aaa/sssd/SssdClaimAuth.java | 220 +++++++++++++++++++++ 3 files changed, 336 insertions(+) create mode 100644 odl-aaa-moon/aaa-authn-sssd/pom.xml create mode 100644 odl-aaa-moon/aaa-authn-sssd/src/main/java/org/opendaylight/aaa/sssd/Activator.java create mode 100644 odl-aaa-moon/aaa-authn-sssd/src/main/java/org/opendaylight/aaa/sssd/SssdClaimAuth.java (limited to 'odl-aaa-moon/aaa-authn-sssd') diff --git a/odl-aaa-moon/aaa-authn-sssd/pom.xml b/odl-aaa-moon/aaa-authn-sssd/pom.xml new file mode 100644 index 00000000..b70c2466 --- /dev/null +++ b/odl-aaa-moon/aaa-authn-sssd/pom.xml @@ -0,0 +1,88 @@ + + + 4.0.0 + + org.opendaylight.aaa + aaa-parent + 0.3.1-Beryllium-SR1 + ../parent + + + aaa-authn-sssd + bundle + + + + org.opendaylight.aaa + aaa-authn + + + org.opendaylight.aaa + aaa-authn-api + + + org.glassfish + javax.json + + + org.opendaylight.aaa + aaa-authn-idpmapping + + + org.slf4j + slf4j-api + + + com.sun.jersey + jersey-server + provided + + + javax.servlet + javax.servlet-api + provided + + + org.osgi + org.osgi.core + provided + + + org.apache.felix + org.apache.felix.dependencymanager + provided + + + + com.sun.jersey.jersey-test-framework + jersey-test-framework-grizzly2 + test + + + junit + junit + test + + + org.slf4j + slf4j-simple + test + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + org.opendaylight.aaa.sssd.Activator + + ${project.basedir}/META-INF + + + + + diff --git a/odl-aaa-moon/aaa-authn-sssd/src/main/java/org/opendaylight/aaa/sssd/Activator.java b/odl-aaa-moon/aaa-authn-sssd/src/main/java/org/opendaylight/aaa/sssd/Activator.java new file mode 100644 index 00000000..b6d5259f --- /dev/null +++ b/odl-aaa-moon/aaa-authn-sssd/src/main/java/org/opendaylight/aaa/sssd/Activator.java @@ -0,0 +1,28 @@ +/* + * 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.sssd; + +import org.apache.felix.dm.DependencyActivatorBase; +import org.apache.felix.dm.DependencyManager; +import org.opendaylight.aaa.api.ClaimAuth; +import org.osgi.framework.BundleContext; + +public class Activator extends DependencyActivatorBase { + + @Override + public void init(BundleContext context, DependencyManager manager) throws Exception { + manager.add(createComponent().setInterface(new String[] { ClaimAuth.class.getName() }, null) + .setImplementation(SssdClaimAuth.class)); + } + + @Override + public void destroy(BundleContext context, DependencyManager manager) throws Exception { + } + +} diff --git a/odl-aaa-moon/aaa-authn-sssd/src/main/java/org/opendaylight/aaa/sssd/SssdClaimAuth.java b/odl-aaa-moon/aaa-authn-sssd/src/main/java/org/opendaylight/aaa/sssd/SssdClaimAuth.java new file mode 100644 index 00000000..0ae23b48 --- /dev/null +++ b/odl-aaa-moon/aaa-authn-sssd/src/main/java/org/opendaylight/aaa/sssd/SssdClaimAuth.java @@ -0,0 +1,220 @@ +/* + * 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.sssd; + +import java.io.StringWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.json.Json; +import javax.json.JsonValue; +import javax.json.stream.JsonGenerator; +import javax.json.stream.JsonGeneratorFactory; +import org.apache.felix.dm.Component; +import org.opendaylight.aaa.ClaimBuilder; +import org.opendaylight.aaa.api.Claim; +import org.opendaylight.aaa.api.ClaimAuth; +import org.opendaylight.aaa.idpmapping.RuleProcessor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * An SSSD {@link ClaimAuth} implementation. + * + * @author John Dennis <jdennis@redhat.com> + */ +public class SssdClaimAuth implements ClaimAuth { + private static final Logger LOG = LoggerFactory.getLogger(SssdClaimAuth.class); + + private static final String DEFAULT_MAPPING_RULES_PATHNAME = "etc/idp_mapping_rules.json"; + private JsonGeneratorFactory generatorFactory = null; + private RuleProcessor ruleProcessor = null; + + // Called by DM when all required dependencies are satisfied. + void init(Component c) { + LOG.info("Initializing SSSD Plugin"); + Map properties = new HashMap(1); + properties.put(JsonGenerator.PRETTY_PRINTING, true); + generatorFactory = Json.createGeneratorFactory(properties); + + String mappingRulesFile = DEFAULT_MAPPING_RULES_PATHNAME; + if (mappingRulesFile == null || mappingRulesFile.isEmpty()) { + LOG.warn("mapping rules file is not configured, " + "SssdClaimAuth will be disabled"); + return; + } + + Path mappingRulesPath = Paths.get(mappingRulesFile); + + if (!Files.exists(mappingRulesPath)) { + LOG.warn(String.format("mapping rules file (%s) " + + "does not exist, SssdClaimAuth will be disabled", mappingRulesFile)); + return; + } + + try { + ruleProcessor = new RuleProcessor(mappingRulesPath, null); + } catch (Exception e) { + LOG.error(String.format("mapping rules file (%s) " + + "could not be loaded, SssdClaimAuth will be disabled. " + "error = %s", + mappingRulesFile, e)); + } + } + + /** + * Transform a Map of assertions into a {@link Claim} via a set of mapping + * rules. + * + * A set of mapping rules have been previously loaded. the incoming + * assertion is converted to a JSON document and presented to the + * {@link RuleProcessor}. If the RuleProcessor can successfully transform + * the assertion given the site specific set of rules it will return a Map + * of values which will then be used to build a {@link Claim}. The rule + * should return one or more of the following which will be used to populate + * the Claim. + * + *
+ *
ClientId
+ *
A string. + * + * @see org.opendaylight.aaa.api.Claim#clientId()
+ * + *
UserId
A string. + * @see org.opendaylight.aaa.api.Claim#userId()
+ * + *
User
A string. + * @see org.opendaylight.aaa.api.Claim#user()
+ * + *
Domain
A string. + * @see org.opendaylight.aaa.api.Claim#domain()
+ * + *
Roles
An array of strings. + * @see org.opendaylight.aaa.api.Claim#roles()
+ * + *
+ * + * @param assertion + * A Map of name/value assertions provided by an external IdP + * @return A {@link Claim} if successful, null otherwise. + */ + + @Override + public Claim transform(Map assertion) { + String assertionJson; + Map mapped; + assertionJson = claimToJson(assertion); + + if (ruleProcessor == null) { + LOG.debug("ruleProcessor not configured"); + return null; + } + + if (LOG.isDebugEnabled()) { + LOG.debug("assertionJson=\n{}", assertionJson); + } + + mapped = ruleProcessor.process(assertionJson); + if (mapped == null) { + if (LOG.isDebugEnabled()) { + LOG.debug("RuleProcessor returned null"); + } + return null; + } + + if (LOG.isDebugEnabled()) { + LOG.debug("RuleProcessor returned: {}", mapped); + } + + ClaimBuilder cb = new ClaimBuilder(); + if (mapped.containsKey("ClientId")) { + cb.setClientId((String) mapped.get("ClientId")); + } + if (mapped.containsKey("UserId")) { + cb.setUserId((String) mapped.get("UserId")); + } + if (mapped.containsKey("User")) { + cb.setUser((String) mapped.get("User")); + } + if (mapped.containsKey("Domain")) { + cb.setDomain((String) mapped.get("Domain")); + } + if (mapped.containsKey("Roles")) { + @SuppressWarnings("unchecked") + List roles = (List) mapped.get("roles"); + for (String role : roles) { + cb.addRole(role); + } + } + Claim claim = cb.build(); + + if (LOG.isDebugEnabled()) { + LOG.debug("returns claim = {}", claim.toString()); + } + + return claim; + } + + /** + * Convert a Claim Map into a JSON object. + * + * Given a Map of name/value pairs convert it into a JSON object and return + * it as a string. This is not a general purpose routine used to convert any + * Map into JSON because a claim has the restriction that each value must be + * a scalar and those scalars are restricted to the following types: + * + *
    + *
  • String
  • + *
  • Integer
  • + *
  • Long
  • + *
  • Double
  • + *
  • Boolean
  • + *
  • null
  • + *
+ * + * See also {@link ClaimAuth}. + * + * @param claim + * The Map containing assertion claims to be converted into a + * JSON assertion document. + * @return A string formatted as a JSON object. + */ + + public String claimToJson(Map claim) { + StringWriter stringWriter = new StringWriter(); + JsonGenerator generator = generatorFactory.createGenerator(stringWriter); + + generator.writeStartObject(); + for (Map.Entry entry : claim.entrySet()) { + String name = entry.getKey(); + Object value = entry.getValue(); + + if (value instanceof String) { + generator.write(name, (String) value); + } else if (value instanceof Integer) { + generator.write(name, ((Integer) value).intValue()); + } else if (value instanceof Long) { + generator.write(name, ((Long) value).longValue()); + } else if (value instanceof Double) { + generator.write(name, ((Double) value).doubleValue()); + } else if (value instanceof Boolean) { + generator.write(name, ((Boolean) value).booleanValue()); + } else if (value == null) { + generator.write(name, JsonValue.NULL); + } else { + LOG.warn(String.format("ignoring claim unsupported value type " + + "entry %s has type %s", name, value.getClass().getSimpleName())); + } + } + generator.writeEnd(); + generator.close(); + return stringWriter.toString(); + } +} -- cgit 1.2.3-korg