1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.portal.security.auth;
21  
22  import com.liferay.portal.NoSuchUserException;
23  import com.liferay.portal.SystemException;
24  import com.liferay.portal.kernel.log.Log;
25  import com.liferay.portal.kernel.log.LogFactoryUtil;
26  import com.liferay.portal.kernel.util.StringPool;
27  import com.liferay.portal.kernel.util.StringUtil;
28  import com.liferay.portal.kernel.util.Validator;
29  import com.liferay.portal.model.User;
30  import com.liferay.portal.security.ldap.PortalLDAPUtil;
31  import com.liferay.portal.service.UserLocalServiceUtil;
32  import com.liferay.portal.util.PortalUtil;
33  import com.liferay.portal.util.PrefsPropsUtil;
34  import com.liferay.portal.util.PropsKeys;
35  import com.liferay.portal.util.PropsValues;
36  
37  import edu.yale.its.tp.cas.client.filter.CASFilter;
38  
39  import javax.naming.Binding;
40  import javax.naming.NamingEnumeration;
41  import javax.naming.directory.Attributes;
42  import javax.naming.directory.SearchControls;
43  import javax.naming.directory.SearchResult;
44  import javax.naming.ldap.LdapContext;
45  
46  import javax.servlet.http.HttpServletRequest;
47  import javax.servlet.http.HttpServletResponse;
48  import javax.servlet.http.HttpSession;
49  
50  /**
51   * <a href="CASAutoLogin.java.html"><b><i>View Source</i></b></a>
52   *
53   * @author Brian Wing Shun Chan
54   * @author Jorge Ferrer
55   *
56   */
57  public class CASAutoLogin implements AutoLogin {
58  
59      public String[] login(
60              HttpServletRequest request, HttpServletResponse response)
61          throws AutoLoginException {
62  
63          String[] credentials = null;
64  
65          try {
66              long companyId = PortalUtil.getCompanyId(request);
67  
68              if (!PrefsPropsUtil.getBoolean(
69                      companyId, PropsKeys.CAS_AUTH_ENABLED,
70                      PropsValues.CAS_AUTH_ENABLED)) {
71  
72                  return credentials;
73              }
74  
75              HttpSession session = request.getSession();
76  
77              String screenName = (String)session.getAttribute(
78                  CASFilter.CAS_FILTER_USER);
79  
80              if (Validator.isNull(screenName)) {
81                  return credentials;
82              }
83  
84              User user = null;
85  
86              try {
87                  user = UserLocalServiceUtil.getUserByScreenName(
88                      companyId, screenName);
89              }
90              catch (NoSuchUserException nsue) {
91                  if (PrefsPropsUtil.getBoolean(
92                          companyId, PropsKeys.CAS_IMPORT_FROM_LDAP,
93                          PropsValues.CAS_IMPORT_FROM_LDAP)) {
94  
95                      user = addUser(companyId, screenName);
96                  }
97                  else {
98                      throw nsue;
99                  }
100             }
101 
102             credentials = new String[3];
103 
104             credentials[0] = String.valueOf(user.getUserId());
105             credentials[1] = user.getPassword();
106             credentials[2] = Boolean.TRUE.toString();
107 
108             return credentials;
109         }
110         catch (Exception e) {
111             _log.error(e, e);
112         }
113 
114         return credentials;
115     }
116 
117     protected User addUser(long companyId, String screenName)
118         throws SystemException {
119 
120         try {
121             String baseDN = PrefsPropsUtil.getString(
122                 companyId, PropsKeys.LDAP_BASE_DN);
123 
124             LdapContext ctx = PortalLDAPUtil.getContext(companyId);
125 
126             if (ctx == null) {
127                 throw new SystemException("Failed to bind to the LDAP server");
128             }
129 
130             String filter = PrefsPropsUtil.getString(
131                 companyId, PropsKeys.LDAP_AUTH_SEARCH_FILTER);
132 
133             if (_log.isDebugEnabled()) {
134                 _log.debug("Search filter before transformation " + filter);
135             }
136 
137             filter = StringUtil.replace(
138                 filter,
139                 new String[] {
140                     "@company_id@", "@email_address@", "@screen_name@"
141                 },
142                 new String[] {
143                     String.valueOf(companyId), StringPool.BLANK, screenName
144                 });
145 
146             if (_log.isDebugEnabled()) {
147                 _log.debug("Search filter after transformation " + filter);
148             }
149 
150             SearchControls cons = new SearchControls(
151                 SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false);
152 
153             NamingEnumeration<SearchResult> enu = ctx.search(
154                 baseDN, filter, cons);
155 
156             if (enu.hasMoreElements()) {
157                 if (_log.isDebugEnabled()) {
158                     _log.debug("Search filter returned at least one result");
159                 }
160 
161                 Binding binding = enu.nextElement();
162 
163                 Attributes attrs = PortalLDAPUtil.getUserAttributes(
164                     companyId, ctx,
165                     PortalLDAPUtil.getNameInNamespace(companyId, binding));
166 
167                 return PortalLDAPUtil.importLDAPUser(
168                     companyId, ctx, attrs, StringPool.BLANK, true);
169             }
170             else {
171                 throw new NoSuchUserException(
172                     "User " + screenName + " was not found in the LDAP server");
173             }
174         }
175         catch (Exception e) {
176             _log.error("Problem accessing LDAP server ", e);
177 
178             throw new SystemException(
179                 "Problem accessign LDAP server " + e.getMessage());
180         }
181     }
182 
183     private static Log _log = LogFactoryUtil.getLog(CASAutoLogin.class);
184 
185 }