103928aee4356845252ac6b662d5c72c29903813eJake Slack//
203928aee4356845252ac6b662d5c72c29903813eJake Slack//  ========================================================================
303928aee4356845252ac6b662d5c72c29903813eJake Slack//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
403928aee4356845252ac6b662d5c72c29903813eJake Slack//  ------------------------------------------------------------------------
503928aee4356845252ac6b662d5c72c29903813eJake Slack//  All rights reserved. This program and the accompanying materials
603928aee4356845252ac6b662d5c72c29903813eJake Slack//  are made available under the terms of the Eclipse Public License v1.0
703928aee4356845252ac6b662d5c72c29903813eJake Slack//  and Apache License v2.0 which accompanies this distribution.
803928aee4356845252ac6b662d5c72c29903813eJake Slack//
903928aee4356845252ac6b662d5c72c29903813eJake Slack//      The Eclipse Public License is available at
1003928aee4356845252ac6b662d5c72c29903813eJake Slack//      http://www.eclipse.org/legal/epl-v10.html
1103928aee4356845252ac6b662d5c72c29903813eJake Slack//
1203928aee4356845252ac6b662d5c72c29903813eJake Slack//      The Apache License v2.0 is available at
1303928aee4356845252ac6b662d5c72c29903813eJake Slack//      http://www.opensource.org/licenses/apache2.0.php
1403928aee4356845252ac6b662d5c72c29903813eJake Slack//
1503928aee4356845252ac6b662d5c72c29903813eJake Slack//  You may elect to redistribute this code under either of these licenses.
1603928aee4356845252ac6b662d5c72c29903813eJake Slack//  ========================================================================
1703928aee4356845252ac6b662d5c72c29903813eJake Slack//
1803928aee4356845252ac6b662d5c72c29903813eJake Slack
1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.security;
2003928aee4356845252ac6b662d5c72c29903813eJake Slack
2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.IOException;
2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.ArrayList;
2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Arrays;
2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Collection;
2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Collections;
2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.HashSet;
2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.List;
2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Map;
2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Map.Entry;
3003928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Set;
3103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.concurrent.CopyOnWriteArrayList;
3203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.concurrent.CopyOnWriteArraySet;
3303928aee4356845252ac6b662d5c72c29903813eJake Slack
3403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.http.HttpSchemes;
3503928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.HttpConstraintElement;
3603928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.HttpMethodConstraintElement;
3703928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.ServletSecurityElement;
3803928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.annotation.ServletSecurity.EmptyRoleSemantic;
3903928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.annotation.ServletSecurity.TransportGuarantee;
4003928aee4356845252ac6b662d5c72c29903813eJake Slack
4103928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.http.PathMap;
4203928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.AbstractHttpConnection;
4303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.Connector;
4403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.Request;
4503928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.Response;
4603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.UserIdentity;
4703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.StringMap;
4803928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.TypeUtil;
4903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.security.Constraint;
5003928aee4356845252ac6b662d5c72c29903813eJake Slack
5103928aee4356845252ac6b662d5c72c29903813eJake Slack/* ------------------------------------------------------------ */
5203928aee4356845252ac6b662d5c72c29903813eJake Slack/**
5303928aee4356845252ac6b662d5c72c29903813eJake Slack * Handler to enforce SecurityConstraints. This implementation is servlet spec
5403928aee4356845252ac6b662d5c72c29903813eJake Slack * 3.0 compliant and precomputes the constraint combinations for runtime
5503928aee4356845252ac6b662d5c72c29903813eJake Slack * efficiency.
5603928aee4356845252ac6b662d5c72c29903813eJake Slack *
5703928aee4356845252ac6b662d5c72c29903813eJake Slack */
5803928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class ConstraintSecurityHandler extends SecurityHandler implements ConstraintAware
5903928aee4356845252ac6b662d5c72c29903813eJake Slack{
6003928aee4356845252ac6b662d5c72c29903813eJake Slack    private static final String OMISSION_SUFFIX = ".omission";
6103928aee4356845252ac6b662d5c72c29903813eJake Slack
6203928aee4356845252ac6b662d5c72c29903813eJake Slack    private final List<ConstraintMapping> _constraintMappings= new CopyOnWriteArrayList<ConstraintMapping>();
6303928aee4356845252ac6b662d5c72c29903813eJake Slack    private final Set<String> _roles = new CopyOnWriteArraySet<String>();
6403928aee4356845252ac6b662d5c72c29903813eJake Slack    private final PathMap _constraintMap = new PathMap();
6503928aee4356845252ac6b662d5c72c29903813eJake Slack    private boolean _strict = true;
6603928aee4356845252ac6b662d5c72c29903813eJake Slack
6703928aee4356845252ac6b662d5c72c29903813eJake Slack
6803928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
6903928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
7003928aee4356845252ac6b662d5c72c29903813eJake Slack     * @return
7103928aee4356845252ac6b662d5c72c29903813eJake Slack     */
7203928aee4356845252ac6b662d5c72c29903813eJake Slack    public static Constraint createConstraint()
7303928aee4356845252ac6b662d5c72c29903813eJake Slack    {
7403928aee4356845252ac6b662d5c72c29903813eJake Slack        return new Constraint();
7503928aee4356845252ac6b662d5c72c29903813eJake Slack    }
7603928aee4356845252ac6b662d5c72c29903813eJake Slack
7703928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
7803928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
7903928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param constraint
8003928aee4356845252ac6b662d5c72c29903813eJake Slack     * @return
8103928aee4356845252ac6b662d5c72c29903813eJake Slack     */
8203928aee4356845252ac6b662d5c72c29903813eJake Slack    public static Constraint createConstraint(Constraint constraint)
8303928aee4356845252ac6b662d5c72c29903813eJake Slack    {
8403928aee4356845252ac6b662d5c72c29903813eJake Slack        try
8503928aee4356845252ac6b662d5c72c29903813eJake Slack        {
8603928aee4356845252ac6b662d5c72c29903813eJake Slack            return (Constraint)constraint.clone();
8703928aee4356845252ac6b662d5c72c29903813eJake Slack        }
8803928aee4356845252ac6b662d5c72c29903813eJake Slack        catch (CloneNotSupportedException e)
8903928aee4356845252ac6b662d5c72c29903813eJake Slack        {
9003928aee4356845252ac6b662d5c72c29903813eJake Slack            throw new IllegalStateException (e);
9103928aee4356845252ac6b662d5c72c29903813eJake Slack        }
9203928aee4356845252ac6b662d5c72c29903813eJake Slack    }
9303928aee4356845252ac6b662d5c72c29903813eJake Slack
9403928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
9503928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
9603928aee4356845252ac6b662d5c72c29903813eJake Slack     * Create a security constraint
9703928aee4356845252ac6b662d5c72c29903813eJake Slack     *
9803928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param name
9903928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param authenticate
10003928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param roles
10103928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param dataConstraint
10203928aee4356845252ac6b662d5c72c29903813eJake Slack     * @return
10303928aee4356845252ac6b662d5c72c29903813eJake Slack     */
10403928aee4356845252ac6b662d5c72c29903813eJake Slack    public static Constraint createConstraint (String name, boolean authenticate, String[] roles, int dataConstraint)
10503928aee4356845252ac6b662d5c72c29903813eJake Slack    {
10603928aee4356845252ac6b662d5c72c29903813eJake Slack        Constraint constraint = createConstraint();
10703928aee4356845252ac6b662d5c72c29903813eJake Slack        if (name != null)
10803928aee4356845252ac6b662d5c72c29903813eJake Slack            constraint.setName(name);
10903928aee4356845252ac6b662d5c72c29903813eJake Slack        constraint.setAuthenticate(authenticate);
11003928aee4356845252ac6b662d5c72c29903813eJake Slack        constraint.setRoles(roles);
11103928aee4356845252ac6b662d5c72c29903813eJake Slack        constraint.setDataConstraint(dataConstraint);
11203928aee4356845252ac6b662d5c72c29903813eJake Slack        return constraint;
11303928aee4356845252ac6b662d5c72c29903813eJake Slack    }
11403928aee4356845252ac6b662d5c72c29903813eJake Slack
11503928aee4356845252ac6b662d5c72c29903813eJake Slack
11603928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
11703928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
11803928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param name
11903928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param element
12003928aee4356845252ac6b662d5c72c29903813eJake Slack     * @return
12103928aee4356845252ac6b662d5c72c29903813eJake Slack     */
12203928aee4356845252ac6b662d5c72c29903813eJake Slack    public static Constraint createConstraint (String name, HttpConstraintElement element)
12303928aee4356845252ac6b662d5c72c29903813eJake Slack    {
12403928aee4356845252ac6b662d5c72c29903813eJake Slack        return createConstraint(name, element.getRolesAllowed(), element.getEmptyRoleSemantic(), element.getTransportGuarantee());
12503928aee4356845252ac6b662d5c72c29903813eJake Slack    }
12603928aee4356845252ac6b662d5c72c29903813eJake Slack
12703928aee4356845252ac6b662d5c72c29903813eJake Slack
12803928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
12903928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
13003928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param name
13103928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param rolesAllowed
13203928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param permitOrDeny
13303928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param transport
13403928aee4356845252ac6b662d5c72c29903813eJake Slack     * @return
13503928aee4356845252ac6b662d5c72c29903813eJake Slack     */
13603928aee4356845252ac6b662d5c72c29903813eJake Slack    public static Constraint createConstraint (String name, String[] rolesAllowed, EmptyRoleSemantic permitOrDeny, TransportGuarantee transport)
13703928aee4356845252ac6b662d5c72c29903813eJake Slack    {
13803928aee4356845252ac6b662d5c72c29903813eJake Slack        Constraint constraint = createConstraint();
13903928aee4356845252ac6b662d5c72c29903813eJake Slack
14003928aee4356845252ac6b662d5c72c29903813eJake Slack        if (rolesAllowed == null || rolesAllowed.length==0)
14103928aee4356845252ac6b662d5c72c29903813eJake Slack        {
14203928aee4356845252ac6b662d5c72c29903813eJake Slack            if (permitOrDeny.equals(EmptyRoleSemantic.DENY))
14303928aee4356845252ac6b662d5c72c29903813eJake Slack            {
14403928aee4356845252ac6b662d5c72c29903813eJake Slack                //Equivalent to <auth-constraint> with no roles
14503928aee4356845252ac6b662d5c72c29903813eJake Slack                constraint.setName(name+"-Deny");
14603928aee4356845252ac6b662d5c72c29903813eJake Slack                constraint.setAuthenticate(true);
14703928aee4356845252ac6b662d5c72c29903813eJake Slack            }
14803928aee4356845252ac6b662d5c72c29903813eJake Slack            else
14903928aee4356845252ac6b662d5c72c29903813eJake Slack            {
15003928aee4356845252ac6b662d5c72c29903813eJake Slack                //Equivalent to no <auth-constraint>
15103928aee4356845252ac6b662d5c72c29903813eJake Slack                constraint.setName(name+"-Permit");
15203928aee4356845252ac6b662d5c72c29903813eJake Slack                constraint.setAuthenticate(false);
15303928aee4356845252ac6b662d5c72c29903813eJake Slack            }
15403928aee4356845252ac6b662d5c72c29903813eJake Slack        }
15503928aee4356845252ac6b662d5c72c29903813eJake Slack        else
15603928aee4356845252ac6b662d5c72c29903813eJake Slack        {
15703928aee4356845252ac6b662d5c72c29903813eJake Slack            //Equivalent to <auth-constraint> with list of <security-role-name>s
15803928aee4356845252ac6b662d5c72c29903813eJake Slack            constraint.setAuthenticate(true);
15903928aee4356845252ac6b662d5c72c29903813eJake Slack            constraint.setRoles(rolesAllowed);
16003928aee4356845252ac6b662d5c72c29903813eJake Slack            constraint.setName(name+"-RolesAllowed");
16103928aee4356845252ac6b662d5c72c29903813eJake Slack        }
16203928aee4356845252ac6b662d5c72c29903813eJake Slack
16303928aee4356845252ac6b662d5c72c29903813eJake Slack        //Equivalent to //<user-data-constraint><transport-guarantee>CONFIDENTIAL</transport-guarantee></user-data-constraint>
16403928aee4356845252ac6b662d5c72c29903813eJake Slack        constraint.setDataConstraint((transport.equals(TransportGuarantee.CONFIDENTIAL)?Constraint.DC_CONFIDENTIAL:Constraint.DC_NONE));
16503928aee4356845252ac6b662d5c72c29903813eJake Slack        return constraint;
16603928aee4356845252ac6b662d5c72c29903813eJake Slack    }
16703928aee4356845252ac6b662d5c72c29903813eJake Slack
16803928aee4356845252ac6b662d5c72c29903813eJake Slack
16903928aee4356845252ac6b662d5c72c29903813eJake Slack
17003928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
17103928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
17203928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param pathSpec
17303928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param constraintMappings
17403928aee4356845252ac6b662d5c72c29903813eJake Slack     * @return
17503928aee4356845252ac6b662d5c72c29903813eJake Slack     */
17603928aee4356845252ac6b662d5c72c29903813eJake Slack    public static List<ConstraintMapping> getConstraintMappingsForPath(String pathSpec, List<ConstraintMapping> constraintMappings)
17703928aee4356845252ac6b662d5c72c29903813eJake Slack    {
17803928aee4356845252ac6b662d5c72c29903813eJake Slack        if (pathSpec == null || "".equals(pathSpec.trim()) || constraintMappings == null || constraintMappings.size() == 0)
17903928aee4356845252ac6b662d5c72c29903813eJake Slack            return Collections.emptyList();
18003928aee4356845252ac6b662d5c72c29903813eJake Slack
18103928aee4356845252ac6b662d5c72c29903813eJake Slack        List<ConstraintMapping> mappings = new ArrayList<ConstraintMapping>();
18203928aee4356845252ac6b662d5c72c29903813eJake Slack        for (ConstraintMapping mapping:constraintMappings)
18303928aee4356845252ac6b662d5c72c29903813eJake Slack        {
18403928aee4356845252ac6b662d5c72c29903813eJake Slack            if (pathSpec.equals(mapping.getPathSpec()))
18503928aee4356845252ac6b662d5c72c29903813eJake Slack            {
18603928aee4356845252ac6b662d5c72c29903813eJake Slack               mappings.add(mapping);
18703928aee4356845252ac6b662d5c72c29903813eJake Slack            }
18803928aee4356845252ac6b662d5c72c29903813eJake Slack        }
18903928aee4356845252ac6b662d5c72c29903813eJake Slack        return mappings;
19003928aee4356845252ac6b662d5c72c29903813eJake Slack    }
19103928aee4356845252ac6b662d5c72c29903813eJake Slack
19203928aee4356845252ac6b662d5c72c29903813eJake Slack
19303928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
19403928aee4356845252ac6b662d5c72c29903813eJake Slack    /** Take out of the constraint mappings those that match the
19503928aee4356845252ac6b662d5c72c29903813eJake Slack     * given path.
19603928aee4356845252ac6b662d5c72c29903813eJake Slack     *
19703928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param pathSpec
19803928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param constraintMappings a new list minus the matching constraints
19903928aee4356845252ac6b662d5c72c29903813eJake Slack     * @return
20003928aee4356845252ac6b662d5c72c29903813eJake Slack     */
20103928aee4356845252ac6b662d5c72c29903813eJake Slack    public static List<ConstraintMapping> removeConstraintMappingsForPath(String pathSpec, List<ConstraintMapping> constraintMappings)
20203928aee4356845252ac6b662d5c72c29903813eJake Slack    {
20303928aee4356845252ac6b662d5c72c29903813eJake Slack        if (pathSpec == null || "".equals(pathSpec.trim()) || constraintMappings == null || constraintMappings.size() == 0)
20403928aee4356845252ac6b662d5c72c29903813eJake Slack            return Collections.emptyList();
20503928aee4356845252ac6b662d5c72c29903813eJake Slack
20603928aee4356845252ac6b662d5c72c29903813eJake Slack        List<ConstraintMapping> mappings = new ArrayList<ConstraintMapping>();
20703928aee4356845252ac6b662d5c72c29903813eJake Slack        for (ConstraintMapping mapping:constraintMappings)
20803928aee4356845252ac6b662d5c72c29903813eJake Slack        {
20903928aee4356845252ac6b662d5c72c29903813eJake Slack            //Remove the matching mappings by only copying in non-matching mappings
21003928aee4356845252ac6b662d5c72c29903813eJake Slack            if (!pathSpec.equals(mapping.getPathSpec()))
21103928aee4356845252ac6b662d5c72c29903813eJake Slack            {
21203928aee4356845252ac6b662d5c72c29903813eJake Slack               mappings.add(mapping);
21303928aee4356845252ac6b662d5c72c29903813eJake Slack            }
21403928aee4356845252ac6b662d5c72c29903813eJake Slack        }
21503928aee4356845252ac6b662d5c72c29903813eJake Slack        return mappings;
21603928aee4356845252ac6b662d5c72c29903813eJake Slack    }
21703928aee4356845252ac6b662d5c72c29903813eJake Slack
21803928aee4356845252ac6b662d5c72c29903813eJake Slack
21903928aee4356845252ac6b662d5c72c29903813eJake Slack
22003928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
22103928aee4356845252ac6b662d5c72c29903813eJake Slack    /** Generate Constraints and ContraintMappings for the given url pattern and ServletSecurityElement
22203928aee4356845252ac6b662d5c72c29903813eJake Slack     *
22303928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param name
22403928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param pathSpec
22503928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param securityElement
22603928aee4356845252ac6b662d5c72c29903813eJake Slack     * @return
22703928aee4356845252ac6b662d5c72c29903813eJake Slack     */
22803928aee4356845252ac6b662d5c72c29903813eJake Slack    public static List<ConstraintMapping> createConstraintsWithMappingsForPath (String name, String pathSpec, ServletSecurityElement securityElement)
22903928aee4356845252ac6b662d5c72c29903813eJake Slack    {
23003928aee4356845252ac6b662d5c72c29903813eJake Slack        List<ConstraintMapping> mappings = new ArrayList<ConstraintMapping>();
23103928aee4356845252ac6b662d5c72c29903813eJake Slack
23203928aee4356845252ac6b662d5c72c29903813eJake Slack        //Create a constraint that will describe the default case (ie if not overridden by specific HttpMethodConstraints)
23303928aee4356845252ac6b662d5c72c29903813eJake Slack        Constraint constraint = ConstraintSecurityHandler.createConstraint(name, securityElement);
23403928aee4356845252ac6b662d5c72c29903813eJake Slack
23503928aee4356845252ac6b662d5c72c29903813eJake Slack        //Create a mapping for the pathSpec for the default case
23603928aee4356845252ac6b662d5c72c29903813eJake Slack        ConstraintMapping defaultMapping = new ConstraintMapping();
23703928aee4356845252ac6b662d5c72c29903813eJake Slack        defaultMapping.setPathSpec(pathSpec);
23803928aee4356845252ac6b662d5c72c29903813eJake Slack        defaultMapping.setConstraint(constraint);
23903928aee4356845252ac6b662d5c72c29903813eJake Slack        mappings.add(defaultMapping);
24003928aee4356845252ac6b662d5c72c29903813eJake Slack
24103928aee4356845252ac6b662d5c72c29903813eJake Slack
24203928aee4356845252ac6b662d5c72c29903813eJake Slack        //See Spec 13.4.1.2 p127
24303928aee4356845252ac6b662d5c72c29903813eJake Slack        List<String> methodOmissions = new ArrayList<String>();
24403928aee4356845252ac6b662d5c72c29903813eJake Slack
24503928aee4356845252ac6b662d5c72c29903813eJake Slack        //make constraint mappings for this url for each of the HttpMethodConstraintElements
24603928aee4356845252ac6b662d5c72c29903813eJake Slack        Collection<HttpMethodConstraintElement> methodConstraints = securityElement.getHttpMethodConstraints();
24703928aee4356845252ac6b662d5c72c29903813eJake Slack        if (methodConstraints != null)
24803928aee4356845252ac6b662d5c72c29903813eJake Slack        {
24903928aee4356845252ac6b662d5c72c29903813eJake Slack            for (HttpMethodConstraintElement methodConstraint:methodConstraints)
25003928aee4356845252ac6b662d5c72c29903813eJake Slack            {
25103928aee4356845252ac6b662d5c72c29903813eJake Slack                //Make a Constraint that captures the <auth-constraint> and <user-data-constraint> elements supplied for the HttpMethodConstraintElement
25203928aee4356845252ac6b662d5c72c29903813eJake Slack                Constraint mconstraint = ConstraintSecurityHandler.createConstraint(name, methodConstraint);
25303928aee4356845252ac6b662d5c72c29903813eJake Slack                ConstraintMapping mapping = new ConstraintMapping();
25403928aee4356845252ac6b662d5c72c29903813eJake Slack                mapping.setConstraint(mconstraint);
25503928aee4356845252ac6b662d5c72c29903813eJake Slack                mapping.setPathSpec(pathSpec);
25603928aee4356845252ac6b662d5c72c29903813eJake Slack                if (methodConstraint.getMethodName() != null)
25703928aee4356845252ac6b662d5c72c29903813eJake Slack                {
25803928aee4356845252ac6b662d5c72c29903813eJake Slack                    mapping.setMethod(methodConstraint.getMethodName());
25903928aee4356845252ac6b662d5c72c29903813eJake Slack                    //See spec 13.4.1.2 p127 - add an omission for every method name to the default constraint
26003928aee4356845252ac6b662d5c72c29903813eJake Slack                    methodOmissions.add(methodConstraint.getMethodName());
26103928aee4356845252ac6b662d5c72c29903813eJake Slack                }
26203928aee4356845252ac6b662d5c72c29903813eJake Slack                mappings.add(mapping);
26303928aee4356845252ac6b662d5c72c29903813eJake Slack            }
26403928aee4356845252ac6b662d5c72c29903813eJake Slack        }
26503928aee4356845252ac6b662d5c72c29903813eJake Slack        //See spec 13.4.1.2 p127 - add an omission for every method name to the default constraint
26603928aee4356845252ac6b662d5c72c29903813eJake Slack        if (methodOmissions.size() > 0)
26703928aee4356845252ac6b662d5c72c29903813eJake Slack            defaultMapping.setMethodOmissions(methodOmissions.toArray(new String[methodOmissions.size()]));
26803928aee4356845252ac6b662d5c72c29903813eJake Slack
26903928aee4356845252ac6b662d5c72c29903813eJake Slack        return mappings;
27003928aee4356845252ac6b662d5c72c29903813eJake Slack    }
27103928aee4356845252ac6b662d5c72c29903813eJake Slack
27203928aee4356845252ac6b662d5c72c29903813eJake Slack
27303928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
27403928aee4356845252ac6b662d5c72c29903813eJake Slack    /** Get the strict mode.
27503928aee4356845252ac6b662d5c72c29903813eJake Slack     * @return true if the security handler is running in strict mode.
27603928aee4356845252ac6b662d5c72c29903813eJake Slack     */
27703928aee4356845252ac6b662d5c72c29903813eJake Slack    public boolean isStrict()
27803928aee4356845252ac6b662d5c72c29903813eJake Slack    {
27903928aee4356845252ac6b662d5c72c29903813eJake Slack        return _strict;
28003928aee4356845252ac6b662d5c72c29903813eJake Slack    }
28103928aee4356845252ac6b662d5c72c29903813eJake Slack
28203928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
28303928aee4356845252ac6b662d5c72c29903813eJake Slack    /** Set the strict mode of the security handler.
28403928aee4356845252ac6b662d5c72c29903813eJake Slack     * <p>
28503928aee4356845252ac6b662d5c72c29903813eJake Slack     * When in strict mode (the default), the full servlet specification
28603928aee4356845252ac6b662d5c72c29903813eJake Slack     * will be implemented.
28703928aee4356845252ac6b662d5c72c29903813eJake Slack     * If not in strict mode, some additional flexibility in configuration
28803928aee4356845252ac6b662d5c72c29903813eJake Slack     * is allowed:<ul>
28903928aee4356845252ac6b662d5c72c29903813eJake Slack     * <li>All users do not need to have a role defined in the deployment descriptor
29003928aee4356845252ac6b662d5c72c29903813eJake Slack     * <li>The * role in a constraint applies to ANY role rather than all roles defined in
29103928aee4356845252ac6b662d5c72c29903813eJake Slack     * the deployment descriptor.
29203928aee4356845252ac6b662d5c72c29903813eJake Slack     * </ul>
29303928aee4356845252ac6b662d5c72c29903813eJake Slack     *
29403928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param strict the strict to set
29503928aee4356845252ac6b662d5c72c29903813eJake Slack     * @see #setRoles(Set)
29603928aee4356845252ac6b662d5c72c29903813eJake Slack     * @see #setConstraintMappings(List, Set)
29703928aee4356845252ac6b662d5c72c29903813eJake Slack     */
29803928aee4356845252ac6b662d5c72c29903813eJake Slack    public void setStrict(boolean strict)
29903928aee4356845252ac6b662d5c72c29903813eJake Slack    {
30003928aee4356845252ac6b662d5c72c29903813eJake Slack        _strict = strict;
30103928aee4356845252ac6b662d5c72c29903813eJake Slack    }
30203928aee4356845252ac6b662d5c72c29903813eJake Slack
30303928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
30403928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
30503928aee4356845252ac6b662d5c72c29903813eJake Slack     * @return Returns the constraintMappings.
30603928aee4356845252ac6b662d5c72c29903813eJake Slack     */
30703928aee4356845252ac6b662d5c72c29903813eJake Slack    public List<ConstraintMapping> getConstraintMappings()
30803928aee4356845252ac6b662d5c72c29903813eJake Slack    {
30903928aee4356845252ac6b662d5c72c29903813eJake Slack        return _constraintMappings;
31003928aee4356845252ac6b662d5c72c29903813eJake Slack    }
31103928aee4356845252ac6b662d5c72c29903813eJake Slack
31203928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
31303928aee4356845252ac6b662d5c72c29903813eJake Slack    public Set<String> getRoles()
31403928aee4356845252ac6b662d5c72c29903813eJake Slack    {
31503928aee4356845252ac6b662d5c72c29903813eJake Slack        return _roles;
31603928aee4356845252ac6b662d5c72c29903813eJake Slack    }
31703928aee4356845252ac6b662d5c72c29903813eJake Slack
31803928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
31903928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
32003928aee4356845252ac6b662d5c72c29903813eJake Slack     * Process the constraints following the combining rules in Servlet 3.0 EA
32103928aee4356845252ac6b662d5c72c29903813eJake Slack     * spec section 13.7.1 Note that much of the logic is in the RoleInfo class.
32203928aee4356845252ac6b662d5c72c29903813eJake Slack     *
32303928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param constraintMappings
32403928aee4356845252ac6b662d5c72c29903813eJake Slack     *            The constraintMappings to set, from which the set of known roles
32503928aee4356845252ac6b662d5c72c29903813eJake Slack     *            is determined.
32603928aee4356845252ac6b662d5c72c29903813eJake Slack     */
32703928aee4356845252ac6b662d5c72c29903813eJake Slack    public void setConstraintMappings(List<ConstraintMapping> constraintMappings)
32803928aee4356845252ac6b662d5c72c29903813eJake Slack    {
32903928aee4356845252ac6b662d5c72c29903813eJake Slack        setConstraintMappings(constraintMappings,null);
33003928aee4356845252ac6b662d5c72c29903813eJake Slack    }
33103928aee4356845252ac6b662d5c72c29903813eJake Slack
33203928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
33303928aee4356845252ac6b662d5c72c29903813eJake Slack     * Process the constraints following the combining rules in Servlet 3.0 EA
33403928aee4356845252ac6b662d5c72c29903813eJake Slack     * spec section 13.7.1 Note that much of the logic is in the RoleInfo class.
33503928aee4356845252ac6b662d5c72c29903813eJake Slack     *
33603928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param constraintMappings
33703928aee4356845252ac6b662d5c72c29903813eJake Slack     *            The constraintMappings to set as array, from which the set of known roles
33803928aee4356845252ac6b662d5c72c29903813eJake Slack     *            is determined.  Needed to retain API compatibility for 7.x
33903928aee4356845252ac6b662d5c72c29903813eJake Slack     */
34003928aee4356845252ac6b662d5c72c29903813eJake Slack    public void setConstraintMappings( ConstraintMapping[] constraintMappings )
34103928aee4356845252ac6b662d5c72c29903813eJake Slack    {
34203928aee4356845252ac6b662d5c72c29903813eJake Slack        setConstraintMappings( Arrays.asList(constraintMappings), null);
34303928aee4356845252ac6b662d5c72c29903813eJake Slack    }
34403928aee4356845252ac6b662d5c72c29903813eJake Slack
34503928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
34603928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
34703928aee4356845252ac6b662d5c72c29903813eJake Slack     * Process the constraints following the combining rules in Servlet 3.0 EA
34803928aee4356845252ac6b662d5c72c29903813eJake Slack     * spec section 13.7.1 Note that much of the logic is in the RoleInfo class.
34903928aee4356845252ac6b662d5c72c29903813eJake Slack     *
35003928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param constraintMappings
35103928aee4356845252ac6b662d5c72c29903813eJake Slack     *            The constraintMappings to set.
35203928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param roles The known roles (or null to determine them from the mappings)
35303928aee4356845252ac6b662d5c72c29903813eJake Slack     */
35403928aee4356845252ac6b662d5c72c29903813eJake Slack    public void setConstraintMappings(List<ConstraintMapping> constraintMappings, Set<String> roles)
35503928aee4356845252ac6b662d5c72c29903813eJake Slack    {
35603928aee4356845252ac6b662d5c72c29903813eJake Slack        _constraintMappings.clear();
35703928aee4356845252ac6b662d5c72c29903813eJake Slack        _constraintMappings.addAll(constraintMappings);
35803928aee4356845252ac6b662d5c72c29903813eJake Slack
35903928aee4356845252ac6b662d5c72c29903813eJake Slack        if (roles==null)
36003928aee4356845252ac6b662d5c72c29903813eJake Slack        {
36103928aee4356845252ac6b662d5c72c29903813eJake Slack            roles = new HashSet<String>();
36203928aee4356845252ac6b662d5c72c29903813eJake Slack            for (ConstraintMapping cm : constraintMappings)
36303928aee4356845252ac6b662d5c72c29903813eJake Slack            {
36403928aee4356845252ac6b662d5c72c29903813eJake Slack                String[] cmr = cm.getConstraint().getRoles();
36503928aee4356845252ac6b662d5c72c29903813eJake Slack                if (cmr!=null)
36603928aee4356845252ac6b662d5c72c29903813eJake Slack                {
36703928aee4356845252ac6b662d5c72c29903813eJake Slack                    for (String r : cmr)
36803928aee4356845252ac6b662d5c72c29903813eJake Slack                        if (!"*".equals(r))
36903928aee4356845252ac6b662d5c72c29903813eJake Slack                            roles.add(r);
37003928aee4356845252ac6b662d5c72c29903813eJake Slack                }
37103928aee4356845252ac6b662d5c72c29903813eJake Slack            }
37203928aee4356845252ac6b662d5c72c29903813eJake Slack        }
37303928aee4356845252ac6b662d5c72c29903813eJake Slack        setRoles(roles);
37403928aee4356845252ac6b662d5c72c29903813eJake Slack
37503928aee4356845252ac6b662d5c72c29903813eJake Slack        if (isStarted())
37603928aee4356845252ac6b662d5c72c29903813eJake Slack        {
37703928aee4356845252ac6b662d5c72c29903813eJake Slack            for (ConstraintMapping mapping : _constraintMappings)
37803928aee4356845252ac6b662d5c72c29903813eJake Slack            {
37903928aee4356845252ac6b662d5c72c29903813eJake Slack                processConstraintMapping(mapping);
38003928aee4356845252ac6b662d5c72c29903813eJake Slack            }
38103928aee4356845252ac6b662d5c72c29903813eJake Slack        }
38203928aee4356845252ac6b662d5c72c29903813eJake Slack    }
38303928aee4356845252ac6b662d5c72c29903813eJake Slack
38403928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
38503928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
38603928aee4356845252ac6b662d5c72c29903813eJake Slack     * Set the known roles.
38703928aee4356845252ac6b662d5c72c29903813eJake Slack     * This may be overridden by a subsequent call to {@link #setConstraintMappings(ConstraintMapping[])} or
38803928aee4356845252ac6b662d5c72c29903813eJake Slack     * {@link #setConstraintMappings(List, Set)}.
38903928aee4356845252ac6b662d5c72c29903813eJake Slack     * @see #setStrict(boolean)
39003928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param roles The known roles (or null to determine them from the mappings)
39103928aee4356845252ac6b662d5c72c29903813eJake Slack     */
39203928aee4356845252ac6b662d5c72c29903813eJake Slack    public void setRoles(Set<String> roles)
39303928aee4356845252ac6b662d5c72c29903813eJake Slack    {
39403928aee4356845252ac6b662d5c72c29903813eJake Slack        _roles.clear();
39503928aee4356845252ac6b662d5c72c29903813eJake Slack        _roles.addAll(roles);
39603928aee4356845252ac6b662d5c72c29903813eJake Slack    }
39703928aee4356845252ac6b662d5c72c29903813eJake Slack
39803928aee4356845252ac6b662d5c72c29903813eJake Slack
39903928aee4356845252ac6b662d5c72c29903813eJake Slack
40003928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
40103928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
40203928aee4356845252ac6b662d5c72c29903813eJake Slack     * @see org.eclipse.jetty.security.ConstraintAware#addConstraintMapping(org.eclipse.jetty.security.ConstraintMapping)
40303928aee4356845252ac6b662d5c72c29903813eJake Slack     */
40403928aee4356845252ac6b662d5c72c29903813eJake Slack    public void addConstraintMapping(ConstraintMapping mapping)
40503928aee4356845252ac6b662d5c72c29903813eJake Slack    {
40603928aee4356845252ac6b662d5c72c29903813eJake Slack        _constraintMappings.add(mapping);
40703928aee4356845252ac6b662d5c72c29903813eJake Slack        if (mapping.getConstraint()!=null && mapping.getConstraint().getRoles()!=null)
40803928aee4356845252ac6b662d5c72c29903813eJake Slack            for (String role :  mapping.getConstraint().getRoles())
40903928aee4356845252ac6b662d5c72c29903813eJake Slack                addRole(role);
41003928aee4356845252ac6b662d5c72c29903813eJake Slack
41103928aee4356845252ac6b662d5c72c29903813eJake Slack        if (isStarted())
41203928aee4356845252ac6b662d5c72c29903813eJake Slack        {
41303928aee4356845252ac6b662d5c72c29903813eJake Slack            processConstraintMapping(mapping);
41403928aee4356845252ac6b662d5c72c29903813eJake Slack        }
41503928aee4356845252ac6b662d5c72c29903813eJake Slack    }
41603928aee4356845252ac6b662d5c72c29903813eJake Slack
41703928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
41803928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
41903928aee4356845252ac6b662d5c72c29903813eJake Slack     * @see org.eclipse.jetty.security.ConstraintAware#addRole(java.lang.String)
42003928aee4356845252ac6b662d5c72c29903813eJake Slack     */
42103928aee4356845252ac6b662d5c72c29903813eJake Slack    public void addRole(String role)
42203928aee4356845252ac6b662d5c72c29903813eJake Slack    {
42303928aee4356845252ac6b662d5c72c29903813eJake Slack        boolean modified = _roles.add(role);
42403928aee4356845252ac6b662d5c72c29903813eJake Slack        if (isStarted() && modified && _strict)
42503928aee4356845252ac6b662d5c72c29903813eJake Slack        {
42603928aee4356845252ac6b662d5c72c29903813eJake Slack            // Add the new role to currently defined any role role infos
42703928aee4356845252ac6b662d5c72c29903813eJake Slack            for (Map<String,RoleInfo> map : (Collection<Map<String,RoleInfo>>)_constraintMap.values())
42803928aee4356845252ac6b662d5c72c29903813eJake Slack            {
42903928aee4356845252ac6b662d5c72c29903813eJake Slack                for (RoleInfo info : map.values())
43003928aee4356845252ac6b662d5c72c29903813eJake Slack                {
43103928aee4356845252ac6b662d5c72c29903813eJake Slack                    if (info.isAnyRole())
43203928aee4356845252ac6b662d5c72c29903813eJake Slack                        info.addRole(role);
43303928aee4356845252ac6b662d5c72c29903813eJake Slack                }
43403928aee4356845252ac6b662d5c72c29903813eJake Slack            }
43503928aee4356845252ac6b662d5c72c29903813eJake Slack        }
43603928aee4356845252ac6b662d5c72c29903813eJake Slack    }
43703928aee4356845252ac6b662d5c72c29903813eJake Slack
43803928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
43903928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
44003928aee4356845252ac6b662d5c72c29903813eJake Slack     * @see org.eclipse.jetty.security.SecurityHandler#doStart()
44103928aee4356845252ac6b662d5c72c29903813eJake Slack     */
44203928aee4356845252ac6b662d5c72c29903813eJake Slack    @Override
44303928aee4356845252ac6b662d5c72c29903813eJake Slack    protected void doStart() throws Exception
44403928aee4356845252ac6b662d5c72c29903813eJake Slack    {
44503928aee4356845252ac6b662d5c72c29903813eJake Slack        _constraintMap.clear();
44603928aee4356845252ac6b662d5c72c29903813eJake Slack        if (_constraintMappings!=null)
44703928aee4356845252ac6b662d5c72c29903813eJake Slack        {
44803928aee4356845252ac6b662d5c72c29903813eJake Slack            for (ConstraintMapping mapping : _constraintMappings)
44903928aee4356845252ac6b662d5c72c29903813eJake Slack            {
45003928aee4356845252ac6b662d5c72c29903813eJake Slack                processConstraintMapping(mapping);
45103928aee4356845252ac6b662d5c72c29903813eJake Slack            }
45203928aee4356845252ac6b662d5c72c29903813eJake Slack        }
45303928aee4356845252ac6b662d5c72c29903813eJake Slack        super.doStart();
45403928aee4356845252ac6b662d5c72c29903813eJake Slack    }
45503928aee4356845252ac6b662d5c72c29903813eJake Slack
45603928aee4356845252ac6b662d5c72c29903813eJake Slack
45703928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
45803928aee4356845252ac6b662d5c72c29903813eJake Slack    @Override
45903928aee4356845252ac6b662d5c72c29903813eJake Slack    protected void doStop() throws Exception
46003928aee4356845252ac6b662d5c72c29903813eJake Slack    {
46103928aee4356845252ac6b662d5c72c29903813eJake Slack        _constraintMap.clear();
46203928aee4356845252ac6b662d5c72c29903813eJake Slack        _constraintMappings.clear();
46303928aee4356845252ac6b662d5c72c29903813eJake Slack        _roles.clear();
46403928aee4356845252ac6b662d5c72c29903813eJake Slack        super.doStop();
46503928aee4356845252ac6b662d5c72c29903813eJake Slack    }
46603928aee4356845252ac6b662d5c72c29903813eJake Slack
46703928aee4356845252ac6b662d5c72c29903813eJake Slack
46803928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
46903928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
47003928aee4356845252ac6b662d5c72c29903813eJake Slack     * Create and combine the constraint with the existing processed
47103928aee4356845252ac6b662d5c72c29903813eJake Slack     * constraints.
47203928aee4356845252ac6b662d5c72c29903813eJake Slack     *
47303928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param mapping
47403928aee4356845252ac6b662d5c72c29903813eJake Slack     */
47503928aee4356845252ac6b662d5c72c29903813eJake Slack    protected void processConstraintMapping(ConstraintMapping mapping)
47603928aee4356845252ac6b662d5c72c29903813eJake Slack    {
47703928aee4356845252ac6b662d5c72c29903813eJake Slack        Map<String, RoleInfo> mappings = (Map<String, RoleInfo>)_constraintMap.get(mapping.getPathSpec());
47803928aee4356845252ac6b662d5c72c29903813eJake Slack        if (mappings == null)
47903928aee4356845252ac6b662d5c72c29903813eJake Slack        {
48003928aee4356845252ac6b662d5c72c29903813eJake Slack            mappings = new StringMap();
48103928aee4356845252ac6b662d5c72c29903813eJake Slack            _constraintMap.put(mapping.getPathSpec(),mappings);
48203928aee4356845252ac6b662d5c72c29903813eJake Slack        }
48303928aee4356845252ac6b662d5c72c29903813eJake Slack        RoleInfo allMethodsRoleInfo = mappings.get(null);
48403928aee4356845252ac6b662d5c72c29903813eJake Slack        if (allMethodsRoleInfo != null && allMethodsRoleInfo.isForbidden())
48503928aee4356845252ac6b662d5c72c29903813eJake Slack            return;
48603928aee4356845252ac6b662d5c72c29903813eJake Slack
48703928aee4356845252ac6b662d5c72c29903813eJake Slack        if (mapping.getMethodOmissions() != null && mapping.getMethodOmissions().length > 0)
48803928aee4356845252ac6b662d5c72c29903813eJake Slack        {
48903928aee4356845252ac6b662d5c72c29903813eJake Slack
49003928aee4356845252ac6b662d5c72c29903813eJake Slack            processConstraintMappingWithMethodOmissions(mapping, mappings);
49103928aee4356845252ac6b662d5c72c29903813eJake Slack            return;
49203928aee4356845252ac6b662d5c72c29903813eJake Slack        }
49303928aee4356845252ac6b662d5c72c29903813eJake Slack
49403928aee4356845252ac6b662d5c72c29903813eJake Slack        String httpMethod = mapping.getMethod();
49503928aee4356845252ac6b662d5c72c29903813eJake Slack        RoleInfo roleInfo = mappings.get(httpMethod);
49603928aee4356845252ac6b662d5c72c29903813eJake Slack        if (roleInfo == null)
49703928aee4356845252ac6b662d5c72c29903813eJake Slack        {
49803928aee4356845252ac6b662d5c72c29903813eJake Slack            roleInfo = new RoleInfo();
49903928aee4356845252ac6b662d5c72c29903813eJake Slack            mappings.put(httpMethod,roleInfo);
50003928aee4356845252ac6b662d5c72c29903813eJake Slack            if (allMethodsRoleInfo != null)
50103928aee4356845252ac6b662d5c72c29903813eJake Slack            {
50203928aee4356845252ac6b662d5c72c29903813eJake Slack                roleInfo.combine(allMethodsRoleInfo);
50303928aee4356845252ac6b662d5c72c29903813eJake Slack            }
50403928aee4356845252ac6b662d5c72c29903813eJake Slack        }
50503928aee4356845252ac6b662d5c72c29903813eJake Slack        if (roleInfo.isForbidden())
50603928aee4356845252ac6b662d5c72c29903813eJake Slack            return;
50703928aee4356845252ac6b662d5c72c29903813eJake Slack
50803928aee4356845252ac6b662d5c72c29903813eJake Slack        //add in info from the constraint
50903928aee4356845252ac6b662d5c72c29903813eJake Slack        configureRoleInfo(roleInfo, mapping);
51003928aee4356845252ac6b662d5c72c29903813eJake Slack
51103928aee4356845252ac6b662d5c72c29903813eJake Slack        if (roleInfo.isForbidden())
51203928aee4356845252ac6b662d5c72c29903813eJake Slack        {
51303928aee4356845252ac6b662d5c72c29903813eJake Slack            if (httpMethod == null)
51403928aee4356845252ac6b662d5c72c29903813eJake Slack            {
51503928aee4356845252ac6b662d5c72c29903813eJake Slack                mappings.clear();
51603928aee4356845252ac6b662d5c72c29903813eJake Slack                mappings.put(null,roleInfo);
51703928aee4356845252ac6b662d5c72c29903813eJake Slack            }
51803928aee4356845252ac6b662d5c72c29903813eJake Slack        }
51903928aee4356845252ac6b662d5c72c29903813eJake Slack        else
52003928aee4356845252ac6b662d5c72c29903813eJake Slack        {
52103928aee4356845252ac6b662d5c72c29903813eJake Slack            //combine with any entry that covers all methods
52203928aee4356845252ac6b662d5c72c29903813eJake Slack            if (httpMethod == null)
52303928aee4356845252ac6b662d5c72c29903813eJake Slack            {
52403928aee4356845252ac6b662d5c72c29903813eJake Slack                for (Map.Entry<String, RoleInfo> entry : mappings.entrySet())
52503928aee4356845252ac6b662d5c72c29903813eJake Slack                {
52603928aee4356845252ac6b662d5c72c29903813eJake Slack                    if (entry.getKey() != null)
52703928aee4356845252ac6b662d5c72c29903813eJake Slack                    {
52803928aee4356845252ac6b662d5c72c29903813eJake Slack                        RoleInfo specific = entry.getValue();
52903928aee4356845252ac6b662d5c72c29903813eJake Slack                        specific.combine(roleInfo);
53003928aee4356845252ac6b662d5c72c29903813eJake Slack                    }
53103928aee4356845252ac6b662d5c72c29903813eJake Slack                }
53203928aee4356845252ac6b662d5c72c29903813eJake Slack            }
53303928aee4356845252ac6b662d5c72c29903813eJake Slack        }
53403928aee4356845252ac6b662d5c72c29903813eJake Slack    }
53503928aee4356845252ac6b662d5c72c29903813eJake Slack
53603928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
53703928aee4356845252ac6b662d5c72c29903813eJake Slack    /** Constraints that name method omissions are dealt with differently.
53803928aee4356845252ac6b662d5c72c29903813eJake Slack     * We create an entry in the mappings with key "method.omission". This entry
53903928aee4356845252ac6b662d5c72c29903813eJake Slack     * is only ever combined with other omissions for the same method to produce a
54003928aee4356845252ac6b662d5c72c29903813eJake Slack     * consolidated RoleInfo. Then, when we wish to find the relevant constraints for
54103928aee4356845252ac6b662d5c72c29903813eJake Slack     *  a given Request (in prepareConstraintInfo()), we consult 3 types of entries in
54203928aee4356845252ac6b662d5c72c29903813eJake Slack     * the mappings: an entry that names the method of the Request specifically, an
54303928aee4356845252ac6b662d5c72c29903813eJake Slack     * entry that names constraints that apply to all methods, entries of the form
54403928aee4356845252ac6b662d5c72c29903813eJake Slack     * method.omission, where the method of the Request is not named in the omission.
54503928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param mapping
54603928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param mappings
54703928aee4356845252ac6b662d5c72c29903813eJake Slack     */
54803928aee4356845252ac6b662d5c72c29903813eJake Slack    protected void processConstraintMappingWithMethodOmissions (ConstraintMapping mapping, Map<String, RoleInfo> mappings)
54903928aee4356845252ac6b662d5c72c29903813eJake Slack    {
55003928aee4356845252ac6b662d5c72c29903813eJake Slack        String[] omissions = mapping.getMethodOmissions();
55103928aee4356845252ac6b662d5c72c29903813eJake Slack
55203928aee4356845252ac6b662d5c72c29903813eJake Slack        for (String omission:omissions)
55303928aee4356845252ac6b662d5c72c29903813eJake Slack        {
55403928aee4356845252ac6b662d5c72c29903813eJake Slack            //for each method omission, see if there is already a RoleInfo for it in mappings
55503928aee4356845252ac6b662d5c72c29903813eJake Slack            RoleInfo ri = mappings.get(omission+OMISSION_SUFFIX);
55603928aee4356845252ac6b662d5c72c29903813eJake Slack            if (ri == null)
55703928aee4356845252ac6b662d5c72c29903813eJake Slack            {
55803928aee4356845252ac6b662d5c72c29903813eJake Slack                //if not, make one
55903928aee4356845252ac6b662d5c72c29903813eJake Slack                ri = new RoleInfo();
56003928aee4356845252ac6b662d5c72c29903813eJake Slack                mappings.put(omission+OMISSION_SUFFIX, ri);
56103928aee4356845252ac6b662d5c72c29903813eJake Slack            }
56203928aee4356845252ac6b662d5c72c29903813eJake Slack
56303928aee4356845252ac6b662d5c72c29903813eJake Slack            //initialize RoleInfo or combine from ConstraintMapping
56403928aee4356845252ac6b662d5c72c29903813eJake Slack            configureRoleInfo(ri, mapping);
56503928aee4356845252ac6b662d5c72c29903813eJake Slack        }
56603928aee4356845252ac6b662d5c72c29903813eJake Slack    }
56703928aee4356845252ac6b662d5c72c29903813eJake Slack
56803928aee4356845252ac6b662d5c72c29903813eJake Slack
56903928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
57003928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
57103928aee4356845252ac6b662d5c72c29903813eJake Slack     * Initialize or update the RoleInfo from the constraint
57203928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param ri
57303928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param mapping
57403928aee4356845252ac6b662d5c72c29903813eJake Slack     */
57503928aee4356845252ac6b662d5c72c29903813eJake Slack    protected void configureRoleInfo (RoleInfo ri, ConstraintMapping mapping)
57603928aee4356845252ac6b662d5c72c29903813eJake Slack    {
57703928aee4356845252ac6b662d5c72c29903813eJake Slack        Constraint constraint = mapping.getConstraint();
57803928aee4356845252ac6b662d5c72c29903813eJake Slack        boolean forbidden = constraint.isForbidden();
57903928aee4356845252ac6b662d5c72c29903813eJake Slack        ri.setForbidden(forbidden);
58003928aee4356845252ac6b662d5c72c29903813eJake Slack
58103928aee4356845252ac6b662d5c72c29903813eJake Slack        //set up the data constraint (NOTE: must be done after setForbidden, as it nulls out the data constraint
58203928aee4356845252ac6b662d5c72c29903813eJake Slack        //which we need in order to do combining of omissions in prepareConstraintInfo
58303928aee4356845252ac6b662d5c72c29903813eJake Slack        UserDataConstraint userDataConstraint = UserDataConstraint.get(mapping.getConstraint().getDataConstraint());
58403928aee4356845252ac6b662d5c72c29903813eJake Slack        ri.setUserDataConstraint(userDataConstraint);
58503928aee4356845252ac6b662d5c72c29903813eJake Slack
58603928aee4356845252ac6b662d5c72c29903813eJake Slack
58703928aee4356845252ac6b662d5c72c29903813eJake Slack        //if forbidden, no point setting up roles
58803928aee4356845252ac6b662d5c72c29903813eJake Slack        if (!ri.isForbidden())
58903928aee4356845252ac6b662d5c72c29903813eJake Slack        {
59003928aee4356845252ac6b662d5c72c29903813eJake Slack            //add in the roles
59103928aee4356845252ac6b662d5c72c29903813eJake Slack            boolean checked = mapping.getConstraint().getAuthenticate();
59203928aee4356845252ac6b662d5c72c29903813eJake Slack            ri.setChecked(checked);
59303928aee4356845252ac6b662d5c72c29903813eJake Slack            if (ri.isChecked())
59403928aee4356845252ac6b662d5c72c29903813eJake Slack            {
59503928aee4356845252ac6b662d5c72c29903813eJake Slack                if (mapping.getConstraint().isAnyRole())
59603928aee4356845252ac6b662d5c72c29903813eJake Slack                {
59703928aee4356845252ac6b662d5c72c29903813eJake Slack                    if (_strict)
59803928aee4356845252ac6b662d5c72c29903813eJake Slack                    {
59903928aee4356845252ac6b662d5c72c29903813eJake Slack                        // * means "all defined roles"
60003928aee4356845252ac6b662d5c72c29903813eJake Slack                        for (String role : _roles)
60103928aee4356845252ac6b662d5c72c29903813eJake Slack                            ri.addRole(role);
60203928aee4356845252ac6b662d5c72c29903813eJake Slack                    }
60303928aee4356845252ac6b662d5c72c29903813eJake Slack                    else
60403928aee4356845252ac6b662d5c72c29903813eJake Slack                        // * means any role
60503928aee4356845252ac6b662d5c72c29903813eJake Slack                        ri.setAnyRole(true);
60603928aee4356845252ac6b662d5c72c29903813eJake Slack                }
60703928aee4356845252ac6b662d5c72c29903813eJake Slack                else
60803928aee4356845252ac6b662d5c72c29903813eJake Slack                {
60903928aee4356845252ac6b662d5c72c29903813eJake Slack                    String[] newRoles = mapping.getConstraint().getRoles();
61003928aee4356845252ac6b662d5c72c29903813eJake Slack                    for (String role : newRoles)
61103928aee4356845252ac6b662d5c72c29903813eJake Slack                    {
61203928aee4356845252ac6b662d5c72c29903813eJake Slack                        if (_strict &&!_roles.contains(role))
61303928aee4356845252ac6b662d5c72c29903813eJake Slack                            throw new IllegalArgumentException("Attempt to use undeclared role: " + role + ", known roles: " + _roles);
61403928aee4356845252ac6b662d5c72c29903813eJake Slack                        ri.addRole(role);
61503928aee4356845252ac6b662d5c72c29903813eJake Slack                    }
61603928aee4356845252ac6b662d5c72c29903813eJake Slack                }
61703928aee4356845252ac6b662d5c72c29903813eJake Slack            }
61803928aee4356845252ac6b662d5c72c29903813eJake Slack        }
61903928aee4356845252ac6b662d5c72c29903813eJake Slack    }
62003928aee4356845252ac6b662d5c72c29903813eJake Slack
62103928aee4356845252ac6b662d5c72c29903813eJake Slack
62203928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
62303928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
62403928aee4356845252ac6b662d5c72c29903813eJake Slack     * Find constraints that apply to the given path.
62503928aee4356845252ac6b662d5c72c29903813eJake Slack     * In order to do this, we consult 3 different types of information stored in the mappings for each path - each mapping
62603928aee4356845252ac6b662d5c72c29903813eJake Slack     * represents a merged set of user data constraints, roles etc -:
62703928aee4356845252ac6b662d5c72c29903813eJake Slack     * <ol>
62803928aee4356845252ac6b662d5c72c29903813eJake Slack     * <li>A mapping of an exact method name </li>
62903928aee4356845252ac6b662d5c72c29903813eJake Slack     * <li>A mapping will null key that matches every method name</li>
63003928aee4356845252ac6b662d5c72c29903813eJake Slack     * <li>Mappings with keys of the form "method.omission" that indicates it will match every method name EXCEPT that given</li>
63103928aee4356845252ac6b662d5c72c29903813eJake Slack     * </ol>
63203928aee4356845252ac6b662d5c72c29903813eJake Slack     *
63303928aee4356845252ac6b662d5c72c29903813eJake Slack     * @see org.eclipse.jetty.security.SecurityHandler#prepareConstraintInfo(java.lang.String, org.eclipse.jetty.server.Request)
63403928aee4356845252ac6b662d5c72c29903813eJake Slack     */
63503928aee4356845252ac6b662d5c72c29903813eJake Slack    protected Object prepareConstraintInfo(String pathInContext, Request request)
63603928aee4356845252ac6b662d5c72c29903813eJake Slack    {
63703928aee4356845252ac6b662d5c72c29903813eJake Slack        Map<String, RoleInfo> mappings = (Map<String, RoleInfo>)_constraintMap.match(pathInContext);
63803928aee4356845252ac6b662d5c72c29903813eJake Slack
63903928aee4356845252ac6b662d5c72c29903813eJake Slack        if (mappings != null)
64003928aee4356845252ac6b662d5c72c29903813eJake Slack        {
64103928aee4356845252ac6b662d5c72c29903813eJake Slack            String httpMethod = request.getMethod();
64203928aee4356845252ac6b662d5c72c29903813eJake Slack            RoleInfo roleInfo = mappings.get(httpMethod);
64303928aee4356845252ac6b662d5c72c29903813eJake Slack            if (roleInfo == null)
64403928aee4356845252ac6b662d5c72c29903813eJake Slack            {
64503928aee4356845252ac6b662d5c72c29903813eJake Slack                //No specific http-method names matched
64603928aee4356845252ac6b662d5c72c29903813eJake Slack                List<RoleInfo> applicableConstraints = new ArrayList<RoleInfo>();
64703928aee4356845252ac6b662d5c72c29903813eJake Slack
64803928aee4356845252ac6b662d5c72c29903813eJake Slack                //Get info for constraint that matches all methods if it exists
64903928aee4356845252ac6b662d5c72c29903813eJake Slack                RoleInfo all = mappings.get(null);
65003928aee4356845252ac6b662d5c72c29903813eJake Slack                if (all != null)
65103928aee4356845252ac6b662d5c72c29903813eJake Slack                    applicableConstraints.add(all);
65203928aee4356845252ac6b662d5c72c29903813eJake Slack
65303928aee4356845252ac6b662d5c72c29903813eJake Slack
65403928aee4356845252ac6b662d5c72c29903813eJake Slack                //Get info for constraints that name method omissions where target method name is not omitted
65503928aee4356845252ac6b662d5c72c29903813eJake Slack                //(ie matches because target method is not omitted, hence considered covered by the constraint)
65603928aee4356845252ac6b662d5c72c29903813eJake Slack                for (Entry<String, RoleInfo> entry: mappings.entrySet())
65703928aee4356845252ac6b662d5c72c29903813eJake Slack                {
65803928aee4356845252ac6b662d5c72c29903813eJake Slack                    if (entry.getKey() != null && entry.getKey().contains(OMISSION_SUFFIX) && !(httpMethod+OMISSION_SUFFIX).equals(entry.getKey()))
65903928aee4356845252ac6b662d5c72c29903813eJake Slack                        applicableConstraints.add(entry.getValue());
66003928aee4356845252ac6b662d5c72c29903813eJake Slack                }
66103928aee4356845252ac6b662d5c72c29903813eJake Slack
66203928aee4356845252ac6b662d5c72c29903813eJake Slack                if (applicableConstraints.size() == 1)
66303928aee4356845252ac6b662d5c72c29903813eJake Slack                    roleInfo = applicableConstraints.get(0);
66403928aee4356845252ac6b662d5c72c29903813eJake Slack                else
66503928aee4356845252ac6b662d5c72c29903813eJake Slack                {
66603928aee4356845252ac6b662d5c72c29903813eJake Slack                    roleInfo = new RoleInfo();
66703928aee4356845252ac6b662d5c72c29903813eJake Slack                    roleInfo.setUserDataConstraint(UserDataConstraint.None);
66803928aee4356845252ac6b662d5c72c29903813eJake Slack
66903928aee4356845252ac6b662d5c72c29903813eJake Slack                    for (RoleInfo r:applicableConstraints)
67003928aee4356845252ac6b662d5c72c29903813eJake Slack                        roleInfo.combine(r);
67103928aee4356845252ac6b662d5c72c29903813eJake Slack                }
67203928aee4356845252ac6b662d5c72c29903813eJake Slack
67303928aee4356845252ac6b662d5c72c29903813eJake Slack            }
67403928aee4356845252ac6b662d5c72c29903813eJake Slack            return roleInfo;
67503928aee4356845252ac6b662d5c72c29903813eJake Slack        }
67603928aee4356845252ac6b662d5c72c29903813eJake Slack        return null;
67703928aee4356845252ac6b662d5c72c29903813eJake Slack    }
67803928aee4356845252ac6b662d5c72c29903813eJake Slack
67903928aee4356845252ac6b662d5c72c29903813eJake Slack
68003928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
68103928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
68203928aee4356845252ac6b662d5c72c29903813eJake Slack     * @see org.eclipse.jetty.security.SecurityHandler#checkUserDataPermissions(java.lang.String, org.eclipse.jetty.server.Request, org.eclipse.jetty.server.Response, java.lang.Object)
68303928aee4356845252ac6b662d5c72c29903813eJake Slack     */
68403928aee4356845252ac6b662d5c72c29903813eJake Slack    protected boolean checkUserDataPermissions(String pathInContext, Request request, Response response, Object constraintInfo) throws IOException
68503928aee4356845252ac6b662d5c72c29903813eJake Slack    {
68603928aee4356845252ac6b662d5c72c29903813eJake Slack        if (constraintInfo == null)
68703928aee4356845252ac6b662d5c72c29903813eJake Slack            return true;
68803928aee4356845252ac6b662d5c72c29903813eJake Slack
68903928aee4356845252ac6b662d5c72c29903813eJake Slack        RoleInfo roleInfo = (RoleInfo)constraintInfo;
69003928aee4356845252ac6b662d5c72c29903813eJake Slack        if (roleInfo.isForbidden())
69103928aee4356845252ac6b662d5c72c29903813eJake Slack            return false;
69203928aee4356845252ac6b662d5c72c29903813eJake Slack
69303928aee4356845252ac6b662d5c72c29903813eJake Slack
69403928aee4356845252ac6b662d5c72c29903813eJake Slack        UserDataConstraint dataConstraint = roleInfo.getUserDataConstraint();
69503928aee4356845252ac6b662d5c72c29903813eJake Slack        if (dataConstraint == null || dataConstraint == UserDataConstraint.None)
69603928aee4356845252ac6b662d5c72c29903813eJake Slack        {
69703928aee4356845252ac6b662d5c72c29903813eJake Slack            return true;
69803928aee4356845252ac6b662d5c72c29903813eJake Slack        }
69903928aee4356845252ac6b662d5c72c29903813eJake Slack        AbstractHttpConnection connection = AbstractHttpConnection.getCurrentConnection();
70003928aee4356845252ac6b662d5c72c29903813eJake Slack        Connector connector = connection.getConnector();
70103928aee4356845252ac6b662d5c72c29903813eJake Slack
70203928aee4356845252ac6b662d5c72c29903813eJake Slack        if (dataConstraint == UserDataConstraint.Integral)
70303928aee4356845252ac6b662d5c72c29903813eJake Slack        {
70403928aee4356845252ac6b662d5c72c29903813eJake Slack            if (connector.isIntegral(request))
70503928aee4356845252ac6b662d5c72c29903813eJake Slack                return true;
70603928aee4356845252ac6b662d5c72c29903813eJake Slack            if (connector.getIntegralPort() > 0)
70703928aee4356845252ac6b662d5c72c29903813eJake Slack            {
70803928aee4356845252ac6b662d5c72c29903813eJake Slack                String scheme=connector.getIntegralScheme();
70903928aee4356845252ac6b662d5c72c29903813eJake Slack                int port=connector.getIntegralPort();
71003928aee4356845252ac6b662d5c72c29903813eJake Slack                String url = (HttpSchemes.HTTPS.equalsIgnoreCase(scheme) && port==443)
71103928aee4356845252ac6b662d5c72c29903813eJake Slack                    ? "https://"+request.getServerName()+request.getRequestURI()
71203928aee4356845252ac6b662d5c72c29903813eJake Slack                    : scheme + "://" + request.getServerName() + ":" + port + request.getRequestURI();
71303928aee4356845252ac6b662d5c72c29903813eJake Slack                if (request.getQueryString() != null)
71403928aee4356845252ac6b662d5c72c29903813eJake Slack                    url += "?" + request.getQueryString();
71503928aee4356845252ac6b662d5c72c29903813eJake Slack                response.setContentLength(0);
71603928aee4356845252ac6b662d5c72c29903813eJake Slack                response.sendRedirect(url);
71703928aee4356845252ac6b662d5c72c29903813eJake Slack            }
71803928aee4356845252ac6b662d5c72c29903813eJake Slack            else
71903928aee4356845252ac6b662d5c72c29903813eJake Slack                response.sendError(Response.SC_FORBIDDEN,"!Integral");
72003928aee4356845252ac6b662d5c72c29903813eJake Slack
72103928aee4356845252ac6b662d5c72c29903813eJake Slack            request.setHandled(true);
72203928aee4356845252ac6b662d5c72c29903813eJake Slack            return false;
72303928aee4356845252ac6b662d5c72c29903813eJake Slack        }
72403928aee4356845252ac6b662d5c72c29903813eJake Slack        else if (dataConstraint == UserDataConstraint.Confidential)
72503928aee4356845252ac6b662d5c72c29903813eJake Slack        {
72603928aee4356845252ac6b662d5c72c29903813eJake Slack            if (connector.isConfidential(request))
72703928aee4356845252ac6b662d5c72c29903813eJake Slack                return true;
72803928aee4356845252ac6b662d5c72c29903813eJake Slack
72903928aee4356845252ac6b662d5c72c29903813eJake Slack            if (connector.getConfidentialPort() > 0)
73003928aee4356845252ac6b662d5c72c29903813eJake Slack            {
73103928aee4356845252ac6b662d5c72c29903813eJake Slack                String scheme=connector.getConfidentialScheme();
73203928aee4356845252ac6b662d5c72c29903813eJake Slack                int port=connector.getConfidentialPort();
73303928aee4356845252ac6b662d5c72c29903813eJake Slack                String url = (HttpSchemes.HTTPS.equalsIgnoreCase(scheme) && port==443)
73403928aee4356845252ac6b662d5c72c29903813eJake Slack                    ? "https://"+request.getServerName()+request.getRequestURI()
73503928aee4356845252ac6b662d5c72c29903813eJake Slack                    : scheme + "://" + request.getServerName() + ":" + port + request.getRequestURI();
73603928aee4356845252ac6b662d5c72c29903813eJake Slack                if (request.getQueryString() != null)
73703928aee4356845252ac6b662d5c72c29903813eJake Slack                    url += "?" + request.getQueryString();
73803928aee4356845252ac6b662d5c72c29903813eJake Slack                response.setContentLength(0);
73903928aee4356845252ac6b662d5c72c29903813eJake Slack                response.sendRedirect(url);
74003928aee4356845252ac6b662d5c72c29903813eJake Slack            }
74103928aee4356845252ac6b662d5c72c29903813eJake Slack            else
74203928aee4356845252ac6b662d5c72c29903813eJake Slack                response.sendError(Response.SC_FORBIDDEN,"!Confidential");
74303928aee4356845252ac6b662d5c72c29903813eJake Slack
74403928aee4356845252ac6b662d5c72c29903813eJake Slack            request.setHandled(true);
74503928aee4356845252ac6b662d5c72c29903813eJake Slack            return false;
74603928aee4356845252ac6b662d5c72c29903813eJake Slack        }
74703928aee4356845252ac6b662d5c72c29903813eJake Slack        else
74803928aee4356845252ac6b662d5c72c29903813eJake Slack        {
74903928aee4356845252ac6b662d5c72c29903813eJake Slack            throw new IllegalArgumentException("Invalid dataConstraint value: " + dataConstraint);
75003928aee4356845252ac6b662d5c72c29903813eJake Slack        }
75103928aee4356845252ac6b662d5c72c29903813eJake Slack
75203928aee4356845252ac6b662d5c72c29903813eJake Slack    }
75303928aee4356845252ac6b662d5c72c29903813eJake Slack
75403928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
75503928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
75603928aee4356845252ac6b662d5c72c29903813eJake Slack     * @see org.eclipse.jetty.security.SecurityHandler#isAuthMandatory(org.eclipse.jetty.server.Request, org.eclipse.jetty.server.Response, java.lang.Object)
75703928aee4356845252ac6b662d5c72c29903813eJake Slack     */
75803928aee4356845252ac6b662d5c72c29903813eJake Slack    protected boolean isAuthMandatory(Request baseRequest, Response base_response, Object constraintInfo)
75903928aee4356845252ac6b662d5c72c29903813eJake Slack    {
76003928aee4356845252ac6b662d5c72c29903813eJake Slack        if (constraintInfo == null)
76103928aee4356845252ac6b662d5c72c29903813eJake Slack        {
76203928aee4356845252ac6b662d5c72c29903813eJake Slack            return false;
76303928aee4356845252ac6b662d5c72c29903813eJake Slack        }
76403928aee4356845252ac6b662d5c72c29903813eJake Slack        return ((RoleInfo)constraintInfo).isChecked();
76503928aee4356845252ac6b662d5c72c29903813eJake Slack    }
76603928aee4356845252ac6b662d5c72c29903813eJake Slack
76703928aee4356845252ac6b662d5c72c29903813eJake Slack
76803928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
76903928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
77003928aee4356845252ac6b662d5c72c29903813eJake Slack     * @see org.eclipse.jetty.security.SecurityHandler#checkWebResourcePermissions(java.lang.String, org.eclipse.jetty.server.Request, org.eclipse.jetty.server.Response, java.lang.Object, org.eclipse.jetty.server.UserIdentity)
77103928aee4356845252ac6b662d5c72c29903813eJake Slack     */
77203928aee4356845252ac6b662d5c72c29903813eJake Slack    @Override
77303928aee4356845252ac6b662d5c72c29903813eJake Slack    protected boolean checkWebResourcePermissions(String pathInContext, Request request, Response response, Object constraintInfo, UserIdentity userIdentity)
77403928aee4356845252ac6b662d5c72c29903813eJake Slack            throws IOException
77503928aee4356845252ac6b662d5c72c29903813eJake Slack    {
77603928aee4356845252ac6b662d5c72c29903813eJake Slack        if (constraintInfo == null)
77703928aee4356845252ac6b662d5c72c29903813eJake Slack        {
77803928aee4356845252ac6b662d5c72c29903813eJake Slack            return true;
77903928aee4356845252ac6b662d5c72c29903813eJake Slack        }
78003928aee4356845252ac6b662d5c72c29903813eJake Slack        RoleInfo roleInfo = (RoleInfo)constraintInfo;
78103928aee4356845252ac6b662d5c72c29903813eJake Slack
78203928aee4356845252ac6b662d5c72c29903813eJake Slack        if (!roleInfo.isChecked())
78303928aee4356845252ac6b662d5c72c29903813eJake Slack        {
78403928aee4356845252ac6b662d5c72c29903813eJake Slack            return true;
78503928aee4356845252ac6b662d5c72c29903813eJake Slack        }
78603928aee4356845252ac6b662d5c72c29903813eJake Slack
78703928aee4356845252ac6b662d5c72c29903813eJake Slack        if (roleInfo.isAnyRole() && request.getAuthType()!=null)
78803928aee4356845252ac6b662d5c72c29903813eJake Slack            return true;
78903928aee4356845252ac6b662d5c72c29903813eJake Slack
79003928aee4356845252ac6b662d5c72c29903813eJake Slack        for (String role : roleInfo.getRoles())
79103928aee4356845252ac6b662d5c72c29903813eJake Slack        {
79203928aee4356845252ac6b662d5c72c29903813eJake Slack            if (userIdentity.isUserInRole(role, null))
79303928aee4356845252ac6b662d5c72c29903813eJake Slack                return true;
79403928aee4356845252ac6b662d5c72c29903813eJake Slack        }
79503928aee4356845252ac6b662d5c72c29903813eJake Slack        return false;
79603928aee4356845252ac6b662d5c72c29903813eJake Slack    }
79703928aee4356845252ac6b662d5c72c29903813eJake Slack
79803928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
79903928aee4356845252ac6b662d5c72c29903813eJake Slack    @Override
80003928aee4356845252ac6b662d5c72c29903813eJake Slack    public void dump(Appendable out,String indent) throws IOException
80103928aee4356845252ac6b662d5c72c29903813eJake Slack    {
80203928aee4356845252ac6b662d5c72c29903813eJake Slack        dumpThis(out);
80303928aee4356845252ac6b662d5c72c29903813eJake Slack        dump(out,indent,
80403928aee4356845252ac6b662d5c72c29903813eJake Slack                Collections.singleton(getLoginService()),
80503928aee4356845252ac6b662d5c72c29903813eJake Slack                Collections.singleton(getIdentityService()),
80603928aee4356845252ac6b662d5c72c29903813eJake Slack                Collections.singleton(getAuthenticator()),
80703928aee4356845252ac6b662d5c72c29903813eJake Slack                Collections.singleton(_roles),
80803928aee4356845252ac6b662d5c72c29903813eJake Slack                _constraintMap.entrySet(),
80903928aee4356845252ac6b662d5c72c29903813eJake Slack                getBeans(),
81003928aee4356845252ac6b662d5c72c29903813eJake Slack                TypeUtil.asList(getHandlers()));
81103928aee4356845252ac6b662d5c72c29903813eJake Slack    }
81203928aee4356845252ac6b662d5c72c29903813eJake Slack
81303928aee4356845252ac6b662d5c72c29903813eJake Slack}
814