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