Fix NPE when there is no relying party metadata
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / idp / profile / saml1 / ShibbolethSSOEndpointSelector.java
1 /*
2  * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package edu.internet2.middleware.shibboleth.idp.profile.saml1;
18
19 import java.util.List;
20
21 import org.opensaml.common.binding.BasicEndpointSelector;
22 import org.opensaml.saml2.metadata.Endpoint;
23 import org.opensaml.xml.util.DatatypeHelper;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * An endpoint selector that may optionally take a SP-provided assertion consumer service URL, validate it against
29  * metadata, and return an endpoint based on it. If no URL is provided the {@link BasicEndpointSelector} selection is
30  * used.
31  */
32 public class ShibbolethSSOEndpointSelector extends BasicEndpointSelector {
33
34     /** Class logger. */
35     private final Logger log = LoggerFactory.getLogger(ShibbolethSSOEndpointSelector.class);
36
37     /** Assertion consumer service URL provided by SP. */
38     private String spAssertionConsumerService;
39
40     /**
41      * Gets the assertion consumer service URL provided by SP.
42      * 
43      * @return assertion consumer service URL provided by SP
44      */
45     public String getSpAssertionConsumerService() {
46         return spAssertionConsumerService;
47     }
48
49     /**
50      * Sets the assertion consumer service URL provided by SP.
51      * 
52      * @param acs assertion consumer service URL provided by SP
53      */
54     public void setSpAssertionConsumerService(String acs) {
55         spAssertionConsumerService = DatatypeHelper.safeTrimOrNullString(acs);
56     }
57
58     /** {@inheritDoc} */
59     public Endpoint selectEndpoint() {
60         if (getEntityRoleMetadata() == null) {
61             log.debug("Unable to select endpoint, no entity role metadata available.");
62             return null;
63         }
64
65         if (spAssertionConsumerService != null) {
66             return selectEndpointByACS();
67         } else {
68             return super.selectEndpoint();
69         }
70     }
71
72     /**
73      * Selects the endpoint, from metadata, corresponding to the SP-provdided ACS URL.
74      * 
75      * @return endpoint corresponding to the SP-provdided ACS URL
76      */
77     protected Endpoint selectEndpointByACS() {
78         log.debug("Selecting endpoint from metadata corresponding to provided ACS URL: {}",
79                 getSpAssertionConsumerService());
80
81         List<Endpoint> endpoints = getEntityRoleMetadata().getEndpoints();
82         log.debug("Relying party role contains {} endpoints", endpoints.size());
83
84         if (endpoints != null && endpoints.size() > 0) {
85             for (Endpoint endpoint : endpoints) {
86                 if (endpoint == null || !getSupportedIssuerBindings().contains(endpoint.getBinding())) {
87                     continue;
88                 }
89
90                 if (endpoint.getLocation().equalsIgnoreCase(spAssertionConsumerService)) {
91                     return endpoint;
92                 }
93
94                 if (!DatatypeHelper.isEmpty(endpoint.getResponseLocation())
95                         && endpoint.getResponseLocation().equalsIgnoreCase(spAssertionConsumerService)) {
96                     return endpoint;
97                 }
98             }
99         }
100
101         log.debug("No endpoint meets selection criteria for SAML entity {}", getEntityMetadata().getEntityID());
102         return null;
103     }
104 }