View Javadoc
1   /*
2    * Copyright 2001-2008 The Apache Software Foundation.
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 org.apache.juddi.v3.auth;
18  
19  import java.io.File;
20  import java.io.FileInputStream;
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.net.URL;
24  import java.util.HashMap;
25  import java.util.Map;
26  
27  import javax.persistence.EntityManager;
28  import javax.persistence.EntityTransaction;
29  import javax.xml.bind.JAXBContext;
30  import javax.xml.bind.JAXBElement;
31  import javax.xml.bind.JAXBException;
32  import javax.xml.bind.Unmarshaller;
33  import javax.xml.transform.stream.StreamSource;
34  import javax.xml.ws.WebServiceContext;
35  
36  import org.apache.commons.configuration.ConfigurationException;
37  import org.apache.commons.logging.Log;
38  import org.apache.commons.logging.LogFactory;
39  import org.apache.juddi.ClassUtil;
40  import org.apache.juddi.config.AppConfig;
41  import org.apache.juddi.config.PersistenceManager;
42  import org.apache.juddi.config.Property;
43  import org.apache.juddi.model.Publisher;
44  import org.apache.juddi.model.UddiEntityPublisher;
45  import org.apache.juddi.v3.error.AuthenticationException;
46  import org.apache.juddi.v3.error.ErrorMessage;
47  import org.apache.juddi.v3.error.FatalErrorException;
48  import org.apache.juddi.v3.error.UnknownUserException;
49  
50  /**
51   * This is a simple implementation of jUDDI's Authenticator interface. The
52   * credential store is simply an unencrypted xml document called 'juddi.users'
53   * that can be found in jUDDI's config directory. Below is an example of what
54   * you might find in this document.
55   *
56   * Example juddi.users document: =============================
57   * <?xml version="1.0" encoding="UTF-8"?>
58   * <juddi-users>
59   * <user userid="sviens" password="password" />
60   * <user userid="griddell" password="password" />
61   * <user userid="bhablutzel" password="password" />
62   * </juddi-users>
63   *
64   * @author Steve Viens (sviens@apache.org)
65   * @author <a href="mailto:kstam@apache.org">Kurt T Stam</a>
66   * @author <a href="mailto:jfaath@apache.org">Jeff Faath</a>
67   */
68  public class XMLDocAuthenticator implements Authenticator {
69  
70          protected final static Log log = LogFactory.getLog(AuthenticatorFactory.class);
71          /**
72           * Container for the user credentials
73           */
74          Map<String, User> userTable;
75  
76          /**
77           *
78           */
79          public XMLDocAuthenticator() throws JAXBException, IOException, ConfigurationException {
80                  readUserFile();
81          }
82  
83          /**
84           * an empty constructor
85           */
86          public XMLDocAuthenticator(boolean b) {
87  
88          }
89  
90          protected String getFilename() throws ConfigurationException {
91                  return AppConfig.getConfiguration().getString(Property.JUDDI_USERSFILE, Property.DEFAULT_XML_USERSFILE);
92          }
93  
94          /**
95           * Read user data from the juddi-users file.
96           *
97           * @throws IOException when the file cannot be opened JAXBException when
98           * the content is malformed.
99           * @throws ConfigurationException
100          */
101         public synchronized void readUserFile() throws JAXBException, IOException, ConfigurationException {
102 
103                 userTable = new HashMap<String, User>();
104                 String usersFileName = getFilename();
105                 if (usersFileName == null || usersFileName.length() == 0) {
106                         throw new ConfigurationException("usersFileName value is null!");
107                 }
108                 File file = new File(usersFileName);
109                 InputStream stream = null;
110                 try {
111                         if (file.exists()) {
112                                 log.info("Reading jUDDI Users File: " + usersFileName + "...");
113                                 stream = new FileInputStream(file);
114                         } else {
115                                 URL resource = ClassUtil.getResource(usersFileName, this.getClass());
116                                 if (resource != null) {
117                                         log.info("Reading jUDDI Users File: " + usersFileName + "...from " + resource.toExternalForm());
118                                 } else {
119                                         log.info("Reading jUDDI Users File: " + usersFileName + "...");
120                                 }
121                                 stream = ClassUtil.getResource(usersFileName, this.getClass()).openStream();
122                         }
123                         JAXBContext jaxbContext = JAXBContext.newInstance(JuddiUsers.class);
124                         Unmarshaller unMarshaller = jaxbContext.createUnmarshaller();
125                         JAXBElement<JuddiUsers> element = unMarshaller.unmarshal(new StreamSource(stream), JuddiUsers.class);
126                         JuddiUsers users = element.getValue();
127                         for (User user : users.getUser()) {
128                                 userTable.put(user.getUserid(), user);
129                                 log.debug("Loading user credentials for user: " + user.getUserid());
130                         }
131                 } catch (IOException ex) {
132                         log.warn("io exception", ex);
133                 } finally {
134                         if (stream != null) {
135                                 stream.close();
136                         }
137                 }
138         }
139 
140         /**
141          *
142          * @param userID
143          * @param credential
144          */
145         public String authenticate(String userID, String credential)
146                 throws AuthenticationException, FatalErrorException {
147                 // a userID must be specified.
148                 if (userID == null) {
149                         throw new UnknownUserException(new ErrorMessage("errors.auth.InvalidUserId"));
150                 }
151 
152                 // credential (password) must be specified.
153                 if (credential == null) {
154                         throw new UnknownUserException(new ErrorMessage("errors.auth.InvalidCredentials"));
155                 }
156 
157                 if (userTable.containsKey(userID)) {
158                         User user = (User) userTable.get(userID);
159                         if ((user.getPassword() == null) || (!credential.equals(user.getPassword()))) {
160                                 throw new UnknownUserException(new ErrorMessage("errors.auth.InvalidCredentials"));
161                         }
162                 } else {
163                         throw new UnknownUserException(new ErrorMessage("errors.auth.InvalidUserId", userID));
164                 }
165 
166                 int MaxBindingsPerService = -1;
167                 int MaxServicesPerBusiness = -1;
168                 int MaxTmodels = -1;
169                 int MaxBusinesses = -1;
170                 try {
171                         MaxBindingsPerService = AppConfig.getConfiguration().getInt(Property.JUDDI_MAX_BINDINGS_PER_SERVICE, -1);
172                         MaxServicesPerBusiness = AppConfig.getConfiguration().getInt(Property.JUDDI_MAX_SERVICES_PER_BUSINESS, -1);
173                         MaxTmodels = AppConfig.getConfiguration().getInt(Property.JUDDI_MAX_TMODELS_PER_PUBLISHER, -1);
174                         MaxBusinesses = AppConfig.getConfiguration().getInt(Property.JUDDI_MAX_BUSINESSES_PER_PUBLISHER, -1);
175                 } catch (Exception ex) {
176                         MaxBindingsPerService = -1;
177                         MaxServicesPerBusiness = -1;
178                         MaxTmodels = -1;
179                         MaxBusinesses = -1;
180                         log.error("config exception! " + userID, ex);
181                 }
182                 EntityManager em = PersistenceManager.getEntityManager();
183                 EntityTransaction tx = em.getTransaction();
184                 try {
185                         tx.begin();
186                         Publisher publisher = em.find(Publisher.class, userID);
187                         if (publisher == null) {
188                                 log.warn("Publisher \"" + userID + "\" was not found in the database, adding the publisher in on the fly.");
189                                 publisher = new Publisher();
190                                 publisher.setAuthorizedName(userID);
191                                 publisher.setIsAdmin("false");
192                                 publisher.setIsEnabled("true");
193                                 publisher.setMaxBindingsPerService(MaxBindingsPerService);
194                                 publisher.setMaxBusinesses(MaxBusinesses);
195                                 publisher.setMaxServicesPerBusiness(MaxServicesPerBusiness);
196                                 publisher.setMaxTmodels(MaxTmodels);
197                                 publisher.setPublisherName("Unknown");
198                                 em.persist(publisher);
199                                 tx.commit();
200                         }
201                 } finally {
202                         if (tx.isActive()) {
203                                 tx.rollback();
204                         }
205                         em.close();
206                 }
207                 return userID;
208         }
209 
210         @Override
211         public UddiEntityPublisher identify(String authInfo, String authorizedName, WebServiceContext ctx) throws AuthenticationException {
212 
213                 EntityManager em = PersistenceManager.getEntityManager();
214                 EntityTransaction tx = em.getTransaction();
215                 try {
216                         tx.begin();
217                         Publisher publisher = em.find(Publisher.class, authorizedName);
218                         if (publisher == null) {
219                                 throw new UnknownUserException(new ErrorMessage("errors.auth.NoPublisher", authorizedName));
220                         }
221 
222                         return publisher;
223                 } finally {
224                         if (tx.isActive()) {
225                                 tx.rollback();
226                         }
227                         em.close();
228                 }
229 
230         }
231 
232 }