001    /**
002     * Copyright (c) 2000-present 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.ListUtil;
019    import com.liferay.portal.model.CompanyConstants;
020    import com.liferay.registry.collections.ServiceTrackerCollections;
021    import com.liferay.registry.collections.ServiceTrackerMap;
022    
023    import java.util.List;
024    import java.util.Map;
025    
026    /**
027     * @author Brian Wing Shun Chan
028     */
029    public class AuthPipeline {
030    
031            public static int authenticateByEmailAddress(
032                            String key, long companyId, String emailAddress, String password,
033                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
034                    throws AuthException {
035    
036                    return _instance._authenticate(
037                            key, companyId, emailAddress, password,
038                            CompanyConstants.AUTH_TYPE_EA, headerMap, parameterMap);
039            }
040    
041            public static int authenticateByScreenName(
042                            String key, long companyId, String screenName, String password,
043                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
044                    throws AuthException {
045    
046                    return _instance._authenticate(
047                            key, companyId, screenName, password, CompanyConstants.AUTH_TYPE_SN,
048                            headerMap, parameterMap);
049            }
050    
051            public static int authenticateByUserId(
052                            String key, long companyId, long userId, String password,
053                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
054                    throws AuthException {
055    
056                    return _instance._authenticate(
057                            key, companyId, String.valueOf(userId), password,
058                            CompanyConstants.AUTH_TYPE_ID, headerMap, parameterMap);
059            }
060    
061            public static void onFailureByEmailAddress(
062                            String key, long companyId, String emailAddress,
063                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
064                    throws AuthException {
065    
066                    _instance._onFailure(
067                            key, companyId, emailAddress, CompanyConstants.AUTH_TYPE_EA,
068                            headerMap, parameterMap);
069            }
070    
071            public static void onFailureByScreenName(
072                            String key, long companyId, String screenName,
073                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
074                    throws AuthException {
075    
076                    _instance._onFailure(
077                            key, companyId, screenName, CompanyConstants.AUTH_TYPE_SN,
078                            headerMap, parameterMap);
079            }
080    
081            public static void onFailureByUserId(
082                            String key, long companyId, long userId,
083                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
084                    throws AuthException {
085    
086                    _instance._onFailure(
087                            key, companyId, String.valueOf(userId),
088                            CompanyConstants.AUTH_TYPE_ID, headerMap, parameterMap);
089            }
090    
091            public static void onMaxFailuresByEmailAddress(
092                            String key, long companyId, String emailAddress,
093                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
094                    throws AuthException {
095    
096                    onFailureByEmailAddress(
097                            key, companyId, emailAddress, headerMap, parameterMap);
098            }
099    
100            public static void onMaxFailuresByScreenName(
101                            String key, long companyId, String screenName,
102                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
103                    throws AuthException {
104    
105                    onFailureByScreenName(
106                            key, companyId, screenName, headerMap, parameterMap);
107            }
108    
109            public static void onMaxFailuresByUserId(
110                            String key, long companyId, long userId,
111                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
112                    throws AuthException {
113    
114                    onFailureByUserId(key, companyId, userId, headerMap, parameterMap);
115            }
116    
117            private AuthPipeline() {
118                    _authenticators = ServiceTrackerCollections.openMultiValueMap(
119                            Authenticator.class, "key");
120                    _authFailures = ServiceTrackerCollections.openMultiValueMap(
121                            AuthFailure.class, "key");
122            }
123    
124            private int _authenticate(
125                            String key, long companyId, String login, String password,
126                            String authType, Map<String, String[]> headerMap,
127                            Map<String, String[]> parameterMap)
128                    throws AuthException {
129    
130                    boolean skipLiferayCheck = false;
131    
132                    List<Authenticator> authenticators = _authenticators.getService(key);
133    
134                    if (ListUtil.isEmpty(authenticators)) {
135                            return Authenticator.SUCCESS;
136                    }
137    
138                    for (Authenticator authenticator : authenticators) {
139                            try {
140                                    int authResult = Authenticator.FAILURE;
141    
142                                    if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
143                                            authResult = authenticator.authenticateByEmailAddress(
144                                                    companyId, login, password, headerMap, parameterMap);
145                                    }
146                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
147                                            authResult = authenticator.authenticateByScreenName(
148                                                    companyId, login, password, headerMap, parameterMap);
149                                    }
150                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
151                                            long userId = GetterUtil.getLong(login);
152    
153                                            authResult = authenticator.authenticateByUserId(
154                                                    companyId, userId, password, headerMap, parameterMap);
155                                    }
156    
157                                    if (authResult == Authenticator.SKIP_LIFERAY_CHECK) {
158                                            skipLiferayCheck = true;
159                                    }
160                                    else if (authResult != Authenticator.SUCCESS) {
161                                            return authResult;
162                                    }
163                            }
164                            catch (AuthException ae) {
165                                    throw ae;
166                            }
167                            catch (Exception e) {
168                                    throw new AuthException(e);
169                            }
170                    }
171    
172                    if (skipLiferayCheck) {
173                            return Authenticator.SKIP_LIFERAY_CHECK;
174                    }
175    
176                    return Authenticator.SUCCESS;
177            }
178    
179            private void _onFailure(
180                            String key, long companyId, String login, String authType,
181                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
182                    throws AuthException {
183    
184                    List<AuthFailure> authFailures = _authFailures.getService(key);
185    
186                    if (authFailures.isEmpty()) {
187                            return;
188                    }
189    
190                    for (AuthFailure authFailure : authFailures) {
191                            try {
192                                    if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
193                                            authFailure.onFailureByEmailAddress(
194                                                    companyId, login, headerMap, parameterMap);
195                                    }
196                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
197                                            authFailure.onFailureByScreenName(
198                                                    companyId, login, headerMap, parameterMap);
199                                    }
200                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
201                                            long userId = GetterUtil.getLong(login);
202    
203                                            authFailure.onFailureByUserId(
204                                                    companyId, userId, headerMap, parameterMap);
205                                    }
206                            }
207                            catch (AuthException ae) {
208                                    throw ae;
209                            }
210                            catch (Exception e) {
211                                    throw new AuthException(e);
212                            }
213                    }
214            }
215    
216            private static final AuthPipeline _instance = new AuthPipeline();
217    
218            private final ServiceTrackerMap<String, List<Authenticator>>
219                    _authenticators;
220            private final ServiceTrackerMap<String, List<AuthFailure>> _authFailures;
221    
222    }