Changed arp repository factory so that classes can be plugged in from runtime config.
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / aa / AAServlet.java
1 /* 
2  * The Shibboleth License, Version 1. 
3  * Copyright (c) 2002 
4  * University Corporation for Advanced Internet Development, Inc. 
5  * All rights reserved
6  * 
7  * 
8  * Redistribution and use in source and binary forms, with or without 
9  * modification, are permitted provided that the following conditions are met:
10  * 
11  * Redistributions of source code must retain the above copyright notice, this 
12  * list of conditions and the following disclaimer.
13  * 
14  * Redistributions in binary form must reproduce the above copyright notice, 
15  * this list of conditions and the following disclaimer in the documentation 
16  * and/or other materials provided with the distribution, if any, must include 
17  * the following acknowledgment: "This product includes software developed by 
18  * the University Corporation for Advanced Internet Development 
19  * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement 
20  * may appear in the software itself, if and wherever such third-party 
21  * acknowledgments normally appear.
22  * 
23  * Neither the name of Shibboleth nor the names of its contributors, nor 
24  * Internet2, nor the University Corporation for Advanced Internet Development, 
25  * Inc., nor UCAID may be used to endorse or promote products derived from this 
26  * software without specific prior written permission. For written permission, 
27  * please contact shibboleth@shibboleth.org
28  * 
29  * Products derived from this software may not be called Shibboleth, Internet2, 
30  * UCAID, or the University Corporation for Advanced Internet Development, nor 
31  * may Shibboleth appear in their name, without prior written permission of the 
32  * University Corporation for Advanced Internet Development.
33  * 
34  * 
35  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
36  * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
37  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
38  * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK 
39  * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE. 
40  * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY 
41  * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT, 
42  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
43  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
44  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
46  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
47  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48  */
49
50 package edu.internet2.middleware.shibboleth.aa;
51
52 import java.io.*;
53 import java.util.*;
54 import javax.servlet.*;
55 import javax.servlet.http.*;
56 import javax.naming.*;
57 import javax.naming.directory.*;
58 import org.opensaml.*;
59 import org.w3c.dom.*;
60 import edu.internet2.middleware.shibboleth.*;
61 import edu.internet2.middleware.shibboleth.common.*;
62 import edu.internet2.middleware.shibboleth.hs.*;
63 import edu.internet2.middleware.eduPerson.*;
64 import org.apache.log4j.Logger;
65 import org.apache.log4j.MDC;
66 import org.doomdark.uuid.UUIDGenerator;
67
68 /**
69  *  Attribute Authority & Release Policy
70  *  Handles Initialization and incoming requests to AA
71  *
72  * @author     Parviz Dousti (dousti@cmu.edu)
73  * @created    June, 2002
74  */
75
76 public class AAServlet extends HttpServlet {
77
78     String myName;
79     String dirUrl;
80     String uidSyntax;
81     String arpFactoryMethod;
82     String ctxFactory;
83     AAResponder responder;
84     HandleRepositoryFactory hrf;
85     ArpFactory arpFactory;
86     private static Logger log = Logger.getLogger(AAServlet.class.getName());    
87     
88     public void init()
89         throws ServletException{
90                 
91         MDC.put("serviceId", "[AA Core]");
92         
93         try{
94
95             edu.internet2.middleware.eduPerson.Init.init();
96             myName = getInitParameter("domain");
97             dirUrl = getInitParameter("dirUrl");
98             uidSyntax = getInitParameter("ldapUserDnPhrase");
99             ctxFactory = getInitParameter("ctxFactoryClass");
100             if(ctxFactory == null)
101                 ctxFactory = "com.sun.jndi.ldap.LdapCtxFactory";
102             // build a properties object to be handed to ArpFactories
103             // include all parameters :-(
104             Enumeration en = getInitParameterNames();
105             Properties props = new Properties();
106             while(en.hasMoreElements()){
107                 String key = (String)en.nextElement();
108                 String val = getInitParameter(key);
109                 props.setProperty(key, val);
110             }
111             props.setProperty("arpFactoryRealPath",
112                               getServletContext().getRealPath("/"));
113
114             arpFactoryMethod = getInitParameter("arpFactoryMethod");
115
116    
117             arpFactory = ArpRepository.getInstance(arpFactoryMethod, props);
118
119             log.info("Using "+ctxFactory+" as directory for attributes.");
120
121             Hashtable env = new Hashtable(11);
122             env.put(Context.INITIAL_CONTEXT_FACTORY, ctxFactory);
123
124             env.put(Context.PROVIDER_URL, dirUrl);
125             DirContext ctx = new InitialDirContext(env);
126             
127             responder = new AAResponder(arpFactory, ctx, myName);
128
129             hrf = getHandleRepository();
130
131             log.info("AA all initialized at "+new Date());
132
133         }catch(NamingException ne){
134             log.fatal("AA init failed: "+ne);
135             throw new ServletException("Init failed: "+ne);
136         }catch(AAException ae){
137             log.fatal("AA init failed: "+ae);
138             throw new ServletException("Init failed: "+ae);
139         }catch(HandleException he){
140             log.fatal("AA init failed: "+he);
141             throw new ServletException("Init failed: "+he);
142         }
143     }
144
145     public void doPost(HttpServletRequest req, HttpServletResponse resp)
146         throws ServletException, IOException {
147                 
148         log.info("Recieved a request.");
149         MDC.put("serviceId", UUIDGenerator.getInstance().generateRandomBasedUUID());
150         MDC.put("remoteAddr", req.getRemoteAddr());
151         log.info("Handling request.");
152
153         SAMLAttribute[] attrs = null;
154         SAMLException ourSE = null;
155         AASaml saml = null;
156         String userName = null;
157             
158         try{
159             saml = new AASaml(myName);
160             saml.receive(req);
161             String resource = saml.getResource();
162             String handle = saml.getHandle();
163             String shar = saml.getShar();
164             String issuedBy = saml.getIssuer();
165             log.info("AA: handle:"+handle);
166             log.info("AA: issuer:"+issuedBy);
167             log.info("AA: shar:"+shar);
168
169
170             if(handle.equalsIgnoreCase("foo")){
171                 // for testing only
172                 userName = "dummy"; 
173             }else{
174                 if(hrf == null){
175                     throw new HandleException("No HandleRepository found! Has HS initialized?");
176                 }else{
177                     HandleEntry he = hrf.getHandleEntry(handle);
178                     userName = he.getUsername();
179                     if(userName == null)
180                         throw new HandleException("HandleServer returns null for user name!");
181                 }
182             }
183
184             attrs = responder.getReleaseAttributes(userName, uidSyntax, handle, shar, resource);
185             log.info("Got "+attrs.length+" attributes for "+userName);
186             saml.respond(resp, attrs, null);
187             log.info("Successfully responded about "+userName);
188
189         }catch (org.opensaml.SAMLException se) {
190             log.error("AA failed for "+userName+" because of: "+se);
191             try{
192                 saml.fail(resp, new SAMLException(SAMLException.RESPONDER, "AA got a SAML Exception: "+se));
193             }catch(Exception ee){
194                 throw new ServletException("AA failed to even make a SAML Failure message because "+ee+"  Origianl problem: "+se);
195             }
196         }catch (HandleException he) {
197             log.error("AA failed for "+userName+" because of: "+he);
198             try{
199                 QName[] codes=new QName[2];
200                 codes[0]=SAMLException.REQUESTER[0];
201                 codes[1]=new QName(
202                                    edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,
203                                    "InvalidHandle");
204                 saml.fail(resp, new SAMLException(codes, "AA got a HandleException: "+he));
205             }catch(Exception ee){
206                 throw new ServletException("AA failed to even make a SAML Failure message because "+ee+"  Origianl problem: "+he);
207             }
208         }catch (Exception e) {
209             log.error("AA failed for "+userName+" because of: "+e);
210             try{
211                 saml.fail(resp, new SAMLException(SAMLException.RESPONDER, "AA got an Exception: "+e));
212             }catch(Exception ee){
213                 throw new ServletException("AA failed to even make a SAML Failure message because "+ee+"  Origianl problem: "+e);
214             }
215
216         }
217     }
218
219
220     private synchronized HandleRepositoryFactory getHandleRepository()
221         throws HandleException, AAException{
222
223         ServletConfig sc = getServletConfig();
224         ServletContext sctx = sc.getServletContext(); 
225         HandleRepositoryFactory hrf = (HandleRepositoryFactory)sctx.getAttribute("HandleRepository");
226
227         log.debug("Context attribute for HandleRepository: "+hrf);
228             
229             
230         if(hrf == null){
231             // make one
232             String repositoryType = this.getServletContext().getInitParameter("repository");
233             if(repositoryType == null)
234                 throw new AAException("repository parameter not set. Unknown Handle repository type");
235             hrf = HandleRepositoryFactory.getInstance(                                                Constants.POLICY_CLUBSHIB, 
236                                                                                                       repositoryType,
237                                                                                                       this );
238             sctx.setAttribute("HandleRepository", hrf);
239             log.info("A new HandleRepository created by AA: "+hrf);
240             
241         }
242         return hrf;
243     }
244
245
246 }