001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.security.auth;
016    
017    import com.liferay.portal.kernel.util.GetterUtil;
018    import com.liferay.portal.kernel.util.InstancePool;
019    import com.liferay.portal.kernel.util.ListUtil;
020    import com.liferay.portal.kernel.util.PropsKeys;
021    import com.liferay.portal.model.CompanyConstants;
022    import com.liferay.portal.util.PropsValues;
023    
024    import java.util.ArrayList;
025    import java.util.HashMap;
026    import java.util.List;
027    import java.util.Map;
028    
029    /**
030     * @author Brian Wing Shun Chan
031     */
032    public class AuthPipeline {
033    
034            public static int authenticateByEmailAddress(
035                            String key, long companyId, String emailAddress, String password,
036                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
037                    throws AuthException {
038    
039                    return _instance._authenticate(
040                            key, companyId, emailAddress, password,
041                            CompanyConstants.AUTH_TYPE_EA, headerMap, parameterMap);
042            }
043    
044            public static int authenticateByScreenName(
045                            String key, long companyId, String screenName, String password,
046                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
047                    throws AuthException {
048    
049                    return _instance._authenticate(
050                            key, companyId, screenName, password, CompanyConstants.AUTH_TYPE_SN,
051                            headerMap, parameterMap);
052            }
053    
054            public static int authenticateByUserId(
055                            String key, long companyId, long userId, String password,
056                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
057                    throws AuthException {
058    
059                    return _instance._authenticate(
060                            key, companyId, String.valueOf(userId), password,
061                            CompanyConstants.AUTH_TYPE_ID, headerMap, parameterMap);
062            }
063    
064            public static void onFailureByEmailAddress(
065                            String key, long companyId, String emailAddress,
066                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
067                    throws AuthException {
068    
069                    _instance._onFailure(
070                            key, companyId, emailAddress, CompanyConstants.AUTH_TYPE_EA,
071                            headerMap, parameterMap);
072            }
073    
074            public static void onFailureByScreenName(
075                            String key, long companyId, String screenName,
076                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
077                    throws AuthException {
078    
079                    _instance._onFailure(
080                            key, companyId, screenName, CompanyConstants.AUTH_TYPE_SN,
081                            headerMap, parameterMap);
082            }
083    
084            public static void onFailureByUserId(
085                            String key, long companyId, long userId,
086                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
087                    throws AuthException {
088    
089                    _instance._onFailure(
090                            key, companyId, String.valueOf(userId),
091                            CompanyConstants.AUTH_TYPE_ID, headerMap, parameterMap);
092            }
093    
094            public static void onMaxFailuresByEmailAddress(
095                            String key, long companyId, String emailAddress,
096                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
097                    throws AuthException {
098    
099                    onFailureByEmailAddress(
100                            key, companyId, emailAddress, headerMap, parameterMap);
101            }
102    
103            public static void onMaxFailuresByScreenName(
104                            String key, long companyId, String screenName,
105                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
106                    throws AuthException {
107    
108                    onFailureByScreenName(
109                            key, companyId, screenName, headerMap, parameterMap);
110            }
111    
112            public static void onMaxFailuresByUserId(
113                            String key, long companyId, long userId,
114                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
115                    throws AuthException {
116    
117                    onFailureByUserId(key, companyId, userId, headerMap, parameterMap);
118            }
119    
120            public static void registerAuthenticator(
121                    String key, Authenticator authenticator) {
122    
123                    _instance._registerAuthenticator(key, authenticator);
124            }
125    
126            public static void registerAuthFailure(
127                    String key, AuthFailure authFailure) {
128    
129                    _instance._registerAuthFailure(key, authFailure);
130            }
131    
132            public static void unregisterAuthenticator(
133                    String key, Authenticator authenticator) {
134    
135                    _instance._unregisterAuthenticator(key, authenticator);
136            }
137    
138            public static void unregisterAuthFailure(
139                    String key, AuthFailure authFailure) {
140    
141                    _instance._unregisterAuthFailure(key, authFailure);
142            }
143    
144            private AuthPipeline() {
145    
146                    // auth.pipeline.pre
147    
148                    List<Authenticator> authenticators = new ArrayList<Authenticator>();
149    
150                    for (String authenticatorClassName : PropsValues.AUTH_PIPELINE_PRE) {
151                            Authenticator authenticator = (Authenticator)InstancePool.get(
152                                    authenticatorClassName);
153    
154                            authenticators.add(authenticator);
155                    }
156    
157                    _authenticators.put(
158                            PropsKeys.AUTH_PIPELINE_PRE,
159                            authenticators.toArray(new Authenticator[authenticators.size()]));
160    
161                    // auth.pipeline.post
162    
163                    authenticators.clear();
164    
165                    for (String authenticatorClassName : PropsValues.AUTH_PIPELINE_POST) {
166                            Authenticator authenticator = (Authenticator)InstancePool.get(
167                                    authenticatorClassName);
168    
169                            authenticators.add(authenticator);
170                    }
171    
172                    _authenticators.put(
173                            PropsKeys.AUTH_PIPELINE_POST,
174                            authenticators.toArray(new Authenticator[authenticators.size()]));
175    
176                    // auth.failure
177    
178                    List<AuthFailure> authFailures = new ArrayList<AuthFailure>();
179    
180                    for (String authFailureClassName : PropsValues.AUTH_FAILURE) {
181                            AuthFailure authFailure = (AuthFailure)InstancePool.get(
182                                    authFailureClassName);
183    
184                            authFailures.add(authFailure);
185                    }
186    
187                    _authFailures.put(
188                            PropsKeys.AUTH_FAILURE,
189                            authFailures.toArray(new AuthFailure[authFailures.size()]));
190    
191                    // auth.max.failures
192    
193                    authFailures.clear();
194    
195                    for (String authFailureClassName : PropsValues.AUTH_MAX_FAILURES) {
196                            AuthFailure authFailure = (AuthFailure)InstancePool.get(
197                                    authFailureClassName);
198    
199                            authFailures.add(authFailure);
200                    }
201    
202                    _authFailures.put(
203                            PropsKeys.AUTH_MAX_FAILURES,
204                            authFailures.toArray(new AuthFailure[authFailures.size()]));
205            }
206    
207            private int _authenticate(
208                            String key, long companyId, String login, String password,
209                            String authType, Map<String, String[]> headerMap,
210                            Map<String, String[]> parameterMap)
211                    throws AuthException {
212    
213                    Authenticator[] authenticators = _authenticators.get(key);
214    
215                    if ((authenticators == null) || (authenticators.length == 0)) {
216                            return 1;
217                    }
218    
219                    for (Authenticator authenticator : authenticators) {
220                            try {
221                                    int authResult = Authenticator.FAILURE;
222    
223                                    if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
224                                            authResult = authenticator.authenticateByEmailAddress(
225                                                    companyId, login, password, headerMap, parameterMap);
226                                    }
227                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
228                                            authResult = authenticator.authenticateByScreenName(
229                                                    companyId, login, password, headerMap, parameterMap);
230                                    }
231                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
232                                            long userId = GetterUtil.getLong(login);
233    
234                                            authResult = authenticator.authenticateByUserId(
235                                                    companyId, userId, password, headerMap, parameterMap);
236                                    }
237    
238                                    if (authResult != Authenticator.SUCCESS) {
239                                            return authResult;
240                                    }
241                            }
242                            catch (AuthException ae) {
243                                    throw ae;
244                            }
245                            catch (Exception e) {
246                                    throw new AuthException(e);
247                            }
248                    }
249    
250                    return Authenticator.SUCCESS;
251            }
252    
253            private void _onFailure(
254                            String key, long companyId, String login, String authType,
255                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
256                    throws AuthException {
257    
258                    AuthFailure[] authFailures = _authFailures.get(key);
259    
260                    if ((authFailures == null) || (authFailures.length == 0)) {
261                            return;
262                    }
263    
264                    for (AuthFailure authFailure : authFailures) {
265                            try {
266                                    if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
267                                            authFailure.onFailureByEmailAddress(
268                                                    companyId, login, headerMap, parameterMap);
269                                    }
270                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
271                                            authFailure.onFailureByScreenName(
272                                                    companyId, login, headerMap, parameterMap);
273                                    }
274                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
275                                            long userId = GetterUtil.getLong(login);
276    
277                                            authFailure.onFailureByUserId(
278                                                    companyId, userId, headerMap, parameterMap);
279                                    }
280                            }
281                            catch (AuthException ae) {
282                                    throw ae;
283                            }
284                            catch (Exception e) {
285                                    throw new AuthException(e);
286                            }
287                    }
288            }
289    
290            private void _registerAuthenticator(
291                    String key, Authenticator authenticator) {
292    
293                    List<Authenticator> authenticators = ListUtil.fromArray(
294                            _authenticators.get(key));
295    
296                    authenticators.add(authenticator);
297    
298                    _authenticators.put(
299                            key,
300                            authenticators.toArray(new Authenticator[authenticators.size()]));
301            }
302    
303            private void _registerAuthFailure(String key, AuthFailure authFailure) {
304                    List<AuthFailure> authFailures = ListUtil.fromArray(
305                            _authFailures.get(key));
306    
307                    authFailures.add(authFailure);
308    
309                    _authFailures.put(
310                            key, authFailures.toArray(new AuthFailure[authFailures.size()]));
311            }
312    
313            private void _unregisterAuthenticator(
314                    String key, Authenticator authenticator) {
315    
316                    List<Authenticator> authenticators = ListUtil.fromArray(
317                            _authenticators.get(key));
318    
319                    if (authenticators.remove(authenticator)) {
320                            _authenticators.put(
321                                    key,
322                                    authenticators.toArray(
323                                            new Authenticator[authenticators.size()]));
324                    }
325            }
326    
327            private void _unregisterAuthFailure(String key, AuthFailure authFailure) {
328                    List<AuthFailure> authFailures = ListUtil.fromArray(
329                            _authFailures.get(key));
330    
331                    if (authFailures.remove(authFailure)) {
332                            _authFailures.put(
333                                    key,
334                                    authFailures.toArray(new AuthFailure[authFailures.size()]));
335                    }
336            }
337    
338            private static AuthPipeline _instance = new AuthPipeline();
339    
340            private Map<String, Authenticator[]> _authenticators =
341                    new HashMap<String, Authenticator[]>();
342            private Map<String, AuthFailure[]> _authFailures =
343                    new HashMap<String, AuthFailure[]>();
344    
345    }