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                    _authFailures = ServiceTrackerCollections.multiValueMap(
119                            AuthFailure.class, "key");
120    
121                    _authFailures.open();
122    
123                    _authenticators = ServiceTrackerCollections.multiValueMap(
124                            Authenticator.class, "key");
125    
126                    _authenticators.open();
127            }
128    
129            private int _authenticate(
130                            String key, long companyId, String login, String password,
131                            String authType, Map<String, String[]> headerMap,
132                            Map<String, String[]> parameterMap)
133                    throws AuthException {
134    
135                    boolean skipLiferayCheck = false;
136    
137                    List<Authenticator> authenticators = _authenticators.getService(key);
138    
139                    if (ListUtil.isEmpty(authenticators)) {
140                            return Authenticator.SUCCESS;
141                    }
142    
143                    for (Authenticator authenticator : authenticators) {
144                            try {
145                                    int authResult = Authenticator.FAILURE;
146    
147                                    if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
148                                            authResult = authenticator.authenticateByEmailAddress(
149                                                    companyId, login, password, headerMap, parameterMap);
150                                    }
151                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
152                                            authResult = authenticator.authenticateByScreenName(
153                                                    companyId, login, password, headerMap, parameterMap);
154                                    }
155                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
156                                            long userId = GetterUtil.getLong(login);
157    
158                                            authResult = authenticator.authenticateByUserId(
159                                                    companyId, userId, password, headerMap, parameterMap);
160                                    }
161    
162                                    if (authResult == Authenticator.SKIP_LIFERAY_CHECK) {
163                                            skipLiferayCheck = true;
164                                    }
165                                    else if (authResult != Authenticator.SUCCESS) {
166                                            return authResult;
167                                    }
168                            }
169                            catch (AuthException ae) {
170                                    throw ae;
171                            }
172                            catch (Exception e) {
173                                    throw new AuthException(e);
174                            }
175                    }
176    
177                    if (skipLiferayCheck) {
178                            return Authenticator.SKIP_LIFERAY_CHECK;
179                    }
180    
181                    return Authenticator.SUCCESS;
182            }
183    
184            private void _onFailure(
185                            String key, long companyId, String login, String authType,
186                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
187                    throws AuthException {
188    
189                    List<AuthFailure> authFailures = _authFailures.getService(key);
190    
191                    if (authFailures.isEmpty()) {
192                            return;
193                    }
194    
195                    for (AuthFailure authFailure : authFailures) {
196                            try {
197                                    if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
198                                            authFailure.onFailureByEmailAddress(
199                                                    companyId, login, headerMap, parameterMap);
200                                    }
201                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
202                                            authFailure.onFailureByScreenName(
203                                                    companyId, login, headerMap, parameterMap);
204                                    }
205                                    else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
206                                            long userId = GetterUtil.getLong(login);
207    
208                                            authFailure.onFailureByUserId(
209                                                    companyId, userId, headerMap, parameterMap);
210                                    }
211                            }
212                            catch (AuthException ae) {
213                                    throw ae;
214                            }
215                            catch (Exception e) {
216                                    throw new AuthException(e);
217                            }
218                    }
219            }
220    
221            private static final AuthPipeline _instance = new AuthPipeline();
222    
223            private final ServiceTrackerMap<String, List<Authenticator>>
224                    _authenticators;
225            private final ServiceTrackerMap<String, List<AuthFailure>> _authFailures;
226    
227    }