net.shibboleth.idp.authn.principal.impl.InexactPrincipalEvalPredicateFactory.java Source code

Java tutorial

Introduction

Here is the source code for net.shibboleth.idp.authn.principal.impl.InexactPrincipalEvalPredicateFactory.java

Source

/*
 * Licensed to the University Corporation for Advanced Internet Development, 
 * Inc. (UCAID) under one or more contributor license agreements.  See the 
 * NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The UCAID licenses this file to You under the Apache 
 * License, Version 2.0 (the "License"); you may not use this file except in 
 * compliance with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.shibboleth.idp.authn.principal.impl;

import java.security.Principal;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import net.shibboleth.idp.authn.principal.PrincipalEvalPredicate;
import net.shibboleth.idp.authn.principal.PrincipalEvalPredicateFactory;
import net.shibboleth.idp.authn.principal.PrincipalSupportingComponent;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
import net.shibboleth.utilities.java.support.logic.Constraint;

import com.google.common.base.Predicates;
import com.google.common.base.Strings;
import com.google.common.collect.Collections2;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;

/**
 * {@link PrincipalEvalPredicateFactory} that implements inexact matching of principals,
 * based on an arbitrary set of "matches" configured at runtime.
 * 
 * <p>Matching is based on string equality between two principals via the {@link Principal#getName()}
 * method.</p>
 * 
 * <p>This component implements essentially arbitrary comparison rules by being unaware of
 * the actual semantics implied by a match. For example, a given instance of the component
 * could be configured with rules for matching principals that are "at least as good as"
 * or "better than" a candidate value, but the component doesn't know or care about that
 * meaning.</p>
 */
public class InexactPrincipalEvalPredicateFactory implements PrincipalEvalPredicateFactory {

    /** Rules for matching. */
    @Nonnull
    @NonnullElements
    private final HashMultimap<String, String> matchingRules;

    /** Constructor. */
    InexactPrincipalEvalPredicateFactory() {
        matchingRules = HashMultimap.create();
    }

    /**
     * Get the matching rules to apply.
     * 
     * @return  a mutable multimap of the matching rules to apply
     */
    @Nonnull
    @NonnullElements
    Multimap<String, String> getMatchingRules() {
        return matchingRules;
    }

    /**
     * Set the matching rules to apply.
     * 
     * <p>The input is a map of sets for bean compatibility.</p>
     * 
     * @param rules matching rules
     */
    public void setMatchingRules(@Nonnull @NonnullElements final Map<String, Collection<String>> rules) {
        Constraint.isNotNull(rules, "Map cannot be null");
        matchingRules.clear();

        for (Map.Entry<String, Collection<String>> e : rules.entrySet()) {
            if (!Strings.isNullOrEmpty(e.getKey()) && e.getValue() != null) {
                matchingRules.putAll(e.getKey(),
                        new HashSet(Collections2.filter(e.getValue(), Predicates.notNull())));
            }
        }
    }

    /** {@inheritDoc} */
    @Nonnull
    public PrincipalEvalPredicate getPredicate(@Nonnull final Principal candidate) {
        return new InexactMatchPredicate(candidate);
    }

    /** Implementation of an inexact-matching predicate. */
    private class InexactMatchPredicate implements PrincipalEvalPredicate {

        /** The principal object to compare against. */
        @Nonnull
        private final Principal principal;

        /** The principal object that matched. */
        @Nullable
        private Principal theMatch;

        /**
         * Constructor.
         *
         * @param candidate principal to compare against
         */
        public InexactMatchPredicate(@Nonnull final Principal candidate) {
            principal = Constraint.isNotNull(candidate, "Principal cannot be null");
        }

        /** {@inheritDoc} */
        public boolean apply(PrincipalSupportingComponent input) {
            Set<String> matches = matchingRules.get(principal.getName());
            Set<? extends Principal> inputs = input.getSupportedPrincipals(principal.getClass());

            for (Principal p : inputs) {
                if (matches.contains(p.getName())) {
                    theMatch = p;
                    return true;
                }
            }

            return false;
        }

        /** {@inheritDoc} */
        @Nullable
        public Principal getMatchingPrincipal() {
            return theMatch;
        }
    }

}