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