001/*
002 * Copyright (c) 2003-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: barseghian $'
006 * '$Date: 2013-01-25 00:59:27 +0000 (Fri, 25 Jan 2013) $' 
007 * '$Revision: 31370 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.kepler.authentication;
031
032import java.io.IOException;
033
034import org.apache.commons.logging.Log;
035import org.apache.commons.logging.LogFactory;
036
037import ptolemy.actor.gui.Configuration;
038import ptolemy.kernel.util.StringAttribute;
039
040/**
041 * AuthenticationManager manages all the authentication issue for the user. It
042 * helps the user to get the proxy from the GAMA server. For details:
043 * http://kepler-project.org/Wiki.jsp?page=KeplerAuthenticationFramework Note:
044 * all of the get Proxy methods are synchronized to avoid multiple entries
045 * (which may cause multiple user login dialogs appear) from the actors.
046 * 
047 * @author Zhijie Guan guan@sdsc.edu
048 * 
049 */
050
051public class AuthenticationManager {
052  private static final Log log = LogFactory.getLog(AuthenticationManager.class
053      .getName());
054        // ProxyRepository is used to store all of the proxies
055        private ProxyRepository proxyRepository = new ProxyRepository();
056
057        // Singleton template is used here to make sure there is only one
058        // AuthenticationManager in the system
059        private static AuthenticationManager authenticationManager = null;
060        private static AuthenticationListener authListener = null;
061
062        /**
063         * singleton constructor
064         */
065        private AuthenticationManager() {
066                try {
067                        preAuthenticate();
068                }
069                catch (Exception e) {
070                        e.printStackTrace();
071                }
072        }
073
074        private void preAuthenticate() throws Exception {
075                
076                // authenticate using configured values
077                String userName = null;
078                String password = null;
079                String[] domainNames = null;
080                
081                // look up the configured values
082                Configuration _configuration = (Configuration) Configuration.configurations().iterator().next();
083                StringAttribute domainAttr = (StringAttribute)_configuration.getAttribute("_domain");
084                if (domainAttr != null) {
085                        String domainName = domainAttr.getExpression();
086                        domainNames = domainName.split(",");
087                }
088                StringAttribute userAttr = (StringAttribute)_configuration.getAttribute("_username");
089                if (userAttr != null) {
090                        userName = userAttr.getExpression();
091                }
092                StringAttribute passwordAttr = (StringAttribute)_configuration.getAttribute("_password");
093                if (passwordAttr != null) {
094                        password = passwordAttr.getExpression();
095                }
096                
097                if (domainNames != null && userName != null && password != null) {
098                        for (String domainName: domainNames) {
099                                // find the domain
100                                Domain domain = AuthenticationManager.getDomain(domainName);
101                                
102                                // do the authentication
103                                AuthenticationService authService = AuthenticationManager.getAuthenticationService(domain);
104                                authService.setUserName(userName);
105                                authService.setPassword(password);
106                                ProxyEntity proxy = authService.authenticate(domain);
107                                String sessionId = proxy.getCredential();
108                                addProxyEntity(proxy);
109                        }
110                }
111        }
112
113        /**
114         * Part of singleton template, the only way to get an instance of
115         * AuthenticationManager
116         * 
117         * @return The unique AuthenticationManager instance
118         */
119        public static AuthenticationManager getManager() {
120                if (authenticationManager == null) {
121                        authenticationManager = new AuthenticationManager();
122                }
123                return authenticationManager;
124        }
125
126        /**
127         * This function retrieves back the default proxy for the user
128         * 
129         * @return The default proxy
130         */
131        /*
132         * public synchronized ProxyEntity getProxy() { while
133         * (proxyRepository.getDefaultProxy() == null) { // No proxy exists
134         * LoginGUI.fire(proxyRepository); // Launch the login dialog
135         * proxyRepository.waitForUserLogin(); // Wait in ProxyRepository for user
136         * login } return proxyRepository.getDefaultProxy(); }
137         */
138
139        /**
140         * This function retrieves back the user proxy within specified domain,
141         * adding ProxyEntity to AuthenticationManager's proxyRepository in the 
142         * process.
143         * 
144         * @param domain
145         *            Specified domain
146         * @return The requested proxy
147         */
148        public synchronized ProxyEntity getProxy(String domainName)
149                        throws AuthenticationException {
150                try {
151                        Domain d = getDomain(domainName);
152                        ProxyEntity entity = proxyRepository.searchProxyInRepository(d);
153                        // check to see if we're already authenticated against this service
154                        if (entity != null) {
155                                return entity;
156                        }
157                        // get the service
158                        AuthenticationService service = getAuthenticationService(d);
159                        // auth against the service
160                        entity = service.authenticate(d);
161                        addProxyEntity(entity);
162                        return entity;
163                } catch (Exception e) {
164                        if (e instanceof AuthenticationException){
165                                throw (AuthenticationException)e;
166                        }
167                        throw new AuthenticationException(e.getMessage());
168                }
169        }
170
171        public synchronized void revokeProxy(ProxyEntity entity)
172                        throws AuthenticationException {
173                try {
174                        // Domain d = getDomain(domainName);
175                        // ProxyEntity entity = proxyRepository.searchProxyInRepository(d);
176
177                        if (entity != null) { // check to see if we're already authenticated
178                                                                        // against this service.
179                                AuthenticationService service = getAuthenticationService(entity
180                                                .getDomain()); // get the service
181                                service.unauthenticate(entity); // unauth against the service
182                                proxyRepository.removeProxy(entity);
183                        }
184                        return;
185                } catch (AuthenticationException ae) {
186                        throw ae;
187                } catch (Exception e) {
188                        throw new AuthenticationException(e.getMessage());
189                }
190        }
191
192        public synchronized ProxyEntity peekProxy(String domainName)
193                        throws AuthenticationException {
194                try {
195                        Domain d = getDomain(domainName);
196                        ProxyEntity entity = proxyRepository.searchProxyInRepository(d);
197
198                        if (entity != null) { // do we have some sort of proxy?
199                                return entity;
200                        }
201                        return null;
202                } catch (AuthenticationException ae) {
203                        throw ae;
204                } catch (Exception e) {
205                        throw new AuthenticationException(e.getMessage());
206                }
207        }
208
209        /**
210         * adds a proxyEntity to the entity repository if it was authenticated
211         * outside of the AuthManager.
212         */
213        public synchronized void addProxyEntity(ProxyEntity pentity)
214                        throws AuthenticationException {
215                if (pentity != null) {
216                        // save the entity for the next time
217                        proxyRepository.insertProxy(pentity);
218                } else {
219                        AuthenticationException ex = new AuthenticationException(
220                                "Error authenticating.  The "
221                                + "authentication service returned null.");
222                        ex.setType(AuthenticationException.USER_CANCEL);
223                        throw ex;
224                }
225        }
226
227        /**
228         * return an AuthenticationService for the given domain name
229         */
230        public synchronized AuthenticationService getAuthenticationService(
231                        String domainName) throws AuthenticationException {
232                try {
233                        DomainList dlist = DomainList.getInstance();
234                        Domain d = dlist.searchDomainList(domainName);
235                        return getAuthenticationService(d);
236                } catch (Exception e) {
237                        throw new AuthenticationException(
238                                        "Error getting authentication service: " + e.getMessage());
239                }
240        }
241
242        /**
243         * returns a Domain for a given domainName
244         */
245        public static Domain getDomain(String domainName)
246                        throws AuthenticationException {
247                try {
248                        DomainList dlist = DomainList.getInstance();
249                        Domain d = dlist.searchDomainList(domainName);
250                        return d;
251                } catch (Exception e) {
252                        throw new AuthenticationException("Error getting domain: "
253                                        + e.getMessage());
254                }
255        }
256
257        /**
258         * returns an instantiation of the correct AuthenticationService based on
259         * the serviceClass listed for the domain. This is set in the
260         * authServicesBundle.properties file
261         */
262        public static synchronized AuthenticationService getAuthenticationService(
263                        Domain domain) throws ClassNotFoundException,
264                        InstantiationException, IllegalAccessException {
265                String className = domain.getServiceClass();
266                Class authClass = Class.forName(className);
267                AuthenticationService service = (AuthenticationService) authClass
268                                .newInstance();
269                service.setAuthenticationListener(authListener);
270                service.setOperationName(domain.getDomain());
271                service.setServiceURL(domain.getServiceURL());
272                service.setOperationName(domain.getServiceOperation());
273                return service;
274        }
275        
276  /**
277   * Check if a credential with the given domain exists in this manager 
278   * @param proxyCredential the string of the credential
279   * @param domaim the given domain
280   * @return true if the credential with the given domain exists
281   */
282        public synchronized boolean proxyExists(String proxyCredential,
283                        String domainName) {
284                Domain domain = null;
285                try {
286                        domain = DomainList.getInstance().searchDomainList(domainName);
287                } catch (IOException e) {
288                        log.warn("Couldn't get the autherntication doman named "
289                                        + domainName + " - " + e.getMessage());
290                        return false;
291                }
292
293                return proxyRepository.proxyExists(proxyCredential, domain);
294        }
295
296        
297        /**
298         * Set the authentication listener
299         * @param listener
300         */
301        public void setAuthenticationListener(AuthenticationListener listener) {
302                authListener = listener;
303        }
304}