View Javadoc

1   /*
2    * Copyright [2005] [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.wayf;
18  
19  import java.util.Comparator;
20  import java.util.List;
21  import java.util.Locale;
22  
23  import javax.servlet.http.HttpServletRequest;
24  
25  import org.opensaml.saml2.common.Extensions;
26  import org.opensaml.saml2.metadata.EntityDescriptor;
27  import org.opensaml.saml2.metadata.IDPSSODescriptor;
28  import org.opensaml.saml2.metadata.Organization;
29  import org.opensaml.saml2.metadata.OrganizationDisplayName;
30  import org.opensaml.saml2.metadata.SingleSignOnService;
31  
32  /**
33   * A class which abstracts an IdP for the sake of the WAYF display.  Given an {@link EntityDescriptor} as
34   * input it provides bean style get functions for the name (EntityId), the display name 
35   * (a hybrid of Organization name or EntityId and the IdP's SSO connection point.
36   * 
37   */
38  public class IdPSite {
39  
40      /** The OpenSaml element that this stands for. */
41      private EntityDescriptor entity;
42      
43      /** The language we set up */
44      private String displayLanguage;
45      
46      /**
47       * Create a new element from the provided Entity.
48       * @param entityParam - What to create from
49       */
50      public IdPSite(EntityDescriptor entityParam) {
51          entity = entityParam;
52      }
53      
54      /**
55       * Get the name for the enclosed entity. 
56       * @return the name for the enclosed entity.
57       */
58      public String getName() {
59              return entity.getEntityID();
60      }
61      
62      /**
63       * Get the user friendly name for the entity, collecting the locale from the 
64       * browser if possible
65       * @param req the request
66       * @return a user friendly name.
67       */
68      public String getDisplayName(HttpServletRequest req) {
69          //
70          // Get the browser locale, failing that the server one
71          //
72          Locale locale = req.getLocale();
73          if (null == locale) {
74              Locale.getDefault();
75          }
76          String lang = locale.getLanguage();
77              
78          return getDisplayName(lang);
79      }
80      /**
81       * Get the user friendly name for the entity, using provided language
82       * @param lang the language.
83       * 
84       * @return a user friendly name.
85       */
86      private String getDisplayName(String lang) {
87          Organization org = entity.getOrganization();
88      
89          if (org == null) {
90              return entity.getEntityID();
91          } 
92          
93          List<OrganizationDisplayName> list = org.getDisplayNames();
94  
95          //
96          // Lookup first by locale
97          //
98          
99          for (OrganizationDisplayName name:list) {
100             if (null !=name && lang.equals(name.getName().getLanguage())) {
101                 return name.getName().getLocalString();
102             }
103         }
104         
105         //
106         // If that doesn't work then anything goes
107         //
108         
109         for (OrganizationDisplayName name:list) {
110             if (null !=name && null != name.getName().getLocalString()) {
111                 return name.getName().getLocalString();
112             }
113         }
114      
115         //
116         // If there is still nothing then use the entity Id
117         //
118         return entity.getEntityID();
119     }
120     /**
121      * Get the user friendly name for the entity, the language we previously set up.
122      * 
123      * @return a user friendly name.
124      */
125     public String getDisplayName() {
126         return getDisplayName(displayLanguage);
127     }
128     
129     /**
130      * Return all the extension elements.
131      * @return the extensions
132      */
133     public Extensions getExtensions() {
134         IDPSSODescriptor idpss = entity.getIDPSSODescriptor(XMLConstants.SHIB_NS);
135         if (null == idpss) {
136             //
137             // Get the SAML2 protocol
138             //
139             idpss = entity.getIDPSSODescriptor(XMLConstants.SALM2_PROTOCOL);
140         }
141         if (null == idpss) {
142             return null;
143         }
144         return idpss.getExtensions();
145     }
146     
147     /**
148      * Comparison so we can sort the output for jsp.
149      * @param What to compare against
150      * @return numeric encoding of comparison 
151      * @see java.lang.Comparator
152      */
153     protected int compareTo(Object o, HttpServletRequest req) {
154             
155 
156         String myDisplayName;
157         String otherDisplayName;
158         IdPSite other;
159 
160         if (equals(o)) {
161             return 0;
162         }
163 
164         myDisplayName = getDisplayName(req);
165         if (null == myDisplayName) {
166             myDisplayName = "";
167         } 
168         
169         other = (IdPSite) o;
170         otherDisplayName = other.getDisplayName(req);
171         if (null == otherDisplayName) {
172             otherDisplayName = "";
173         }
174 
175         int result = myDisplayName.toLowerCase().compareTo(otherDisplayName.toLowerCase());
176         if (result == 0) {
177                 result = myDisplayName.compareTo(otherDisplayName);
178         }
179         return result;
180     }
181 
182     /**
183      * When a user has selected an IdP, this provides the address to which we redirect.
184      * @return http address for the IdP this represents.  
185      */
186     public String getAddressForWAYF() {
187         List<SingleSignOnService> ssoList;
188         
189         ssoList = entity.getIDPSSODescriptor(XMLConstants.SHIB_NS).getSingleSignOnServices();
190         
191         for (SingleSignOnService signOnService: ssoList) {
192             if (XMLConstants.IDP_SSO_BINDING.equals(signOnService.getBinding())) {
193                 return signOnService.getLocation();
194             }
195         }
196         return null;
197     }
198 
199     /**
200      * Prior to display we set the display language from the
201      * browser. There is probably a proper way to do this using
202      * jsp, but I want to keep the API between JSP and java the same 1.3->2.0
203      * @param lang the language to set
204      */
205     public void setDisplayLanguage(String lang) {
206         this.displayLanguage = lang;
207     }
208     
209     public static class Compare implements Comparator<IdPSite> {
210 
211         /**
212          * This allows us to set up sorted lists of entities with respect to
213          * the browser request.
214          * 
215          * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
216          */
217         private HttpServletRequest req = null;
218         
219         private Compare() {
220             //
221             // No public method
222         }
223         
224         public Compare(HttpServletRequest req) {
225             this.req = req;
226         }
227         
228         public int compare(IdPSite o1, IdPSite o2) {
229             // TODO Auto-generated method stub
230             return o1.compareTo(o2, req);
231         }
232         
233     }
234 
235 }       
236