001    /**
002     * Copyright (c) 2000-2013 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                    boolean skipLiferayCheck = false;
214    
215                    Authenticator[] authenticators = _authenticators.get(key);
216    
217                    if ((authenticators == null) || (authenticators.length == 0)) {
218                            return Authenticator.SUCCESS;
219                    }
220    
221                    for (Authenticator authenticator : authenticators) {
222                            try {
223                                    int authResult = Authenticator.FAILURE;
224    
225                                    if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
226                                            authResult = authenticator.authenticateByEmailAddress(
227                                                    companyId, login, password, headerMap, parameterMap);
228                                    }
229                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
230                                            authResult = authenticator.authenticateByScreenName(
231                                                    companyId, login, password, headerMap, parameterMap);
232                                    }
233                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
234                                            long userId = GetterUtil.getLong(login);
235    
236                                            authResult = authenticator.authenticateByUserId(
237                                                    companyId, userId, password, headerMap, parameterMap);
238                                    }
239    
240                                    if (authResult == Authenticator.SKIP_LIFERAY_CHECK) {
241                                            skipLiferayCheck = true;
242                                    }
243                                    else if (authResult != Authenticator.SUCCESS) {
244                                            return authResult;
245                                    }
246                            }
247                            catch (AuthException ae) {
248                                    throw ae;
249                            }
250                            catch (Exception e) {
251                                    throw new AuthException(e);
252                            }
253                    }
254    
255                    if (skipLiferayCheck) {
256                            return Authenticator.SKIP_LIFERAY_CHECK;
257                    }
258    
259                    return Authenticator.SUCCESS;
260            }
261    
262            private void _onFailure(
263                            String key, long companyId, String login, String authType,
264                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
265                    throws AuthException {
266    
267                    AuthFailure[] authFailures = _authFailures.get(key);
268    
269                    if ((authFailures == null) || (authFailures.length == 0)) {
270                            return;
271                    }
272    
273                    for (AuthFailure authFailure : authFailures) {
274                            try {
275                                    if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
276                                            authFailure.onFailureByEmailAddress(
277                                                    companyId, login, headerMap, parameterMap);
278                                    }
279                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
280                                            authFailure.onFailureByScreenName(
281                                                    companyId, login, headerMap, parameterMap);
282                                    }
283                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
284                                            long userId = GetterUtil.getLong(login);
285    
286                                            authFailure.onFailureByUserId(
287                                                    companyId, userId, headerMap, parameterMap);
288                                    }
289                            }
290                            catch (AuthException ae) {
291                                    throw ae;
292                            }
293                            catch (Exception e) {
294                                    throw new AuthException(e);
295                            }
296                    }
297            }
298    
299            private void _registerAuthenticator(
300                    String key, Authenticator authenticator) {
301    
302                    List<Authenticator> authenticators = ListUtil.fromArray(
303                            _authenticators.get(key));
304    
305                    authenticators.add(authenticator);
306    
307                    _authenticators.put(
308                            key,
309                            authenticators.toArray(new Authenticator[authenticators.size()]));
310            }
311    
312            private void _registerAuthFailure(String key, AuthFailure authFailure) {
313                    List<AuthFailure> authFailures = ListUtil.fromArray(
314                            _authFailures.get(key));
315    
316                    authFailures.add(authFailure);
317    
318                    _authFailures.put(
319                            key, authFailures.toArray(new AuthFailure[authFailures.size()]));
320            }
321    
322            private void _unregisterAuthenticator(
323                    String key, Authenticator authenticator) {
324    
325                    List<Authenticator> authenticators = ListUtil.fromArray(
326                            _authenticators.get(key));
327    
328                    if (authenticators.remove(authenticator)) {
329                            _authenticators.put(
330                                    key,
331                                    authenticators.toArray(
332                                            new Authenticator[authenticators.size()]));
333                    }
334            }
335    
336            private void _unregisterAuthFailure(String key, AuthFailure authFailure) {
337                    List<AuthFailure> authFailures = ListUtil.fromArray(
338                            _authFailures.get(key));
339    
340                    if (authFailures.remove(authFailure)) {
341                            _authFailures.put(
342                                    key,
343                                    authFailures.toArray(new AuthFailure[authFailures.size()]));
344                    }
345            }
346    
347            private static AuthPipeline _instance = new AuthPipeline();
348    
349            private Map<String, Authenticator[]> _authenticators =
350                    new HashMap<String, Authenticator[]>();
351            private Map<String, AuthFailure[]> _authFailures =
352                    new HashMap<String, AuthFailure[]>();
353    
354    }