View Javadoc

1   /***
2    * <cvs:id>$Id: LoginAction.java,v 1.32 2005/01/31 19:39:00 jdt Exp $</cvs:id>
3    * <cvs:source>$Source: /devel/astrogrid/portal/login/src/java/org/astrogrid/portal/cocoon/common/LoginAction.java,v $</cvs:source>
4    * <cvs:author>$Author: jdt $</cvs:author>
5    * <cvs:date>$Date: 2005/01/31 19:39:00 $</cvs:date>
6    * <cvs:version>$Revision: 1.32 $</cvs:version>
7    */
8   package org.astrogrid.portal.cocoon.common;
9   import java.net.MalformedURLException;
10  import java.net.URL;
11  import java.util.HashMap;
12  import java.util.Map;
13  
14  import org.apache.avalon.framework.logger.ConsoleLogger;
15  import org.apache.avalon.framework.logger.Logger;
16  import org.apache.avalon.framework.parameters.Parameters;
17  import org.apache.cocoon.acting.AbstractAction;
18  import org.apache.cocoon.environment.ObjectModelHelper;
19  import org.apache.cocoon.environment.Redirector;
20  import org.apache.cocoon.environment.Request;
21  import org.apache.cocoon.environment.Session;
22  import org.apache.cocoon.environment.SourceResolver;
23  import org.astrogrid.community.common.config.CommunityConfig;
24  import org.astrogrid.community.common.exception.CommunityIdentifierException;
25  import org.astrogrid.community.common.exception.CommunityPolicyException;
26  import org.astrogrid.community.common.exception.CommunitySecurityException;
27  import org.astrogrid.community.common.exception.CommunityServiceException;
28  import org.astrogrid.community.common.ivorn.CommunityAccountIvornFactory;
29  import org.astrogrid.community.common.security.data.SecurityToken;
30  import org.astrogrid.community.common.security.service.SecurityServiceMock;
31  import org.astrogrid.community.resolver.CommunityAccountSpaceResolver;
32  import org.astrogrid.community.resolver.CommunityPasswordResolver;
33  import org.astrogrid.community.resolver.exception.CommunityResolverException;
34  import org.astrogrid.config.Config;
35  import org.astrogrid.config.SimpleConfig;
36  import org.astrogrid.portal.login.common.SessionKeys;
37  import org.astrogrid.registry.RegistryException;
38  import org.astrogrid.store.Ivorn;
39  /***
40   * Login Action.  Extracts login parameters from the 
41   * request action and checks them with the security 
42   * delegate.
43   * Note that using an incorrect community will cause this class' act() method
44   * to throw an exception, since an
45   * attempt is made to look up the community in the registry.  If you have not configured
46   * a registry then you can use the back door community "org.astrogrid.mock" to avoid this.  
47   * This is provided for testing purposes and is configured so that the password "secret"
48   * will allow access.
49   * 
50   * @TODO plumb in the policy delegate to check
51   * we have permission to view the site!
52   * @author dave/jdt
53   */
54  public final class LoginAction extends AbstractAction {
55  
56      /***
57       * Parameter names to look for in the request object. We could refer to
58       * these vars for better safety in the xsps, but it makes the code so ugly
59       * and difficult to read I've decided not to.
60       */
61      public static final String USER_PARAM = "user";
62      /***
63       * Parameter names to look for in the request object.
64       */
65      public static final String COMMUNITY_PARAM = "community";
66      /***
67       * Parameter names to look for in the request object.
68       */
69      public static final String PASS_PARAM = "pass";
70  
71      /***
72       * Logger
73       */
74      private Logger log;
75    
76    
77      /***
78       * Our action method. Expects the "user", "community" and "pass" to be in
79       * the request header.  Returns null if the user fails to
80       * login, or a hashmap (currently empty) on success.
81       * Disasters raise exceptions now.  
82       * 
83       * @param redirector see org.apache.cocoon.acting.Action#act
84       * @param resolver see org.apache.cocoon.acting.Action#act
85       * @param objectModel see org.apache.cocoon.acting.Action#act
86       * @param source see org.apache.cocoon.acting.Action#act
87       * @param params see org.apache.cocoon.acting.Action#act
88       * @return null on failure to login, an empty HashMap on success
89       * @throws LoginException if there's a problem with the 
90       * input parameters or we're unable to get a delegate
91       * @see org.apache.cocoon.acting.Action#act
92       *      (org.apache.cocoon.environment.Redirector,
93       *      org.apache.cocoon.environment.SourceResolver, java.util.Map,
94       *      java.lang.String,
95       *      org.apache.avalon.framework.parameters.Parameters)
96       */
97      public Map act(
98          final Redirector redirector,
99          final SourceResolver resolver,
100         final Map objectModel,
101         final String source,
102         final Parameters params)
103         throws LoginException {
104 
105         // Ensure logger is set correctly
106         checkLogger();
107 
108         //
109         // Get our current request and session.
110         final Request request = ObjectModelHelper.getRequest(objectModel);
111         final Session session = request.getSession();
112 
113         //
114         // Get the user name and password from our request.
115         String user = request.getParameter(USER_PARAM);
116         String community = request.getParameter(COMMUNITY_PARAM);
117         String pass = request.getParameter(PASS_PARAM);
118         user = checkParameter(user, log);
119         community = checkParameter(community, log);
120         pass = checkParameter(pass, log);
121 
122         log.debug("LoginAction:login()");
123         log.debug("  user : " + user);
124         log.debug("  community : " + community);
125         log.debug("  Pass : " + pass);
126 
127         final Ivorn ivorn;
128         try {
129             ivorn = CommunityAccountIvornFactory.createIvorn(community, user);
130         } catch (CommunityIdentifierException e1) {
131             log.error("Unable to create ivorn", e1);
132             throw new LoginException("Invalid user name or community - unable to create an Ivorn from those parameters", e1);
133         }
134         log.debug("  Ivorn : " + ivorn);
135         final String name = ivorn.toString();
136 
137         final CommunityPasswordResolver passwordResolver = new CommunityPasswordResolver();
138 
139         //
140         // Try logging in to the Community.
141         final SecurityToken token;
142         log.debug("Attempting to get token...");
143         try {
144             token = passwordResolver.checkPassword(name, pass);
145         } catch (CommunityServiceException e) {
146             log.debug("Security check failed",e);
147             return null; //failed to log in
148         } catch (CommunitySecurityException e) {
149             log.debug("Security check failed",e);
150             return null; //failed to log in
151         } catch (CommunityIdentifierException e) {
152             log.debug("Account identifier invalid",e);
153             return null; //failed to log in
154         } catch (CommunityResolverException e) {
155             //It's possible this should return null (ie a failed login)
156             //rather than be treated as an error, because it probably indicates
157             //that the user mistyped their community
158             // ADDENDUM: CHANGED BY KEA TO RETURN NULL
159             log.debug("CommunityResolverException from security delegate",e);
160             return null;  //failed to log in
161 /*
162             log.error("CommunityResolverException from security delegate",e);
163             throw new LoginException("CommunityResolverException from security delegate.  Please check that your community has been entered correctly and that your registry is properly configured.",e);
164 */
165         } catch (RegistryException e) {
166             log.error("RegistryException from security delegate",e);
167             throw new LoginException("RegistryException from security delegate",e);
168         }
169         
170         assert token!=null : "Token should not be null" ;
171 
172         log.debug("PASS : Got token");
173         log.debug("  Token   : " + token);
174         log.debug("  Token   : " + token.getToken());
175         log.debug("  Account : " + token.getAccount());
176         
177         // Get MySpace Manager end point.
178         Ivorn accountSpace = null;
179         try {
180           CommunityAccountSpaceResolver accSpaceResolver = new CommunityAccountSpaceResolver();
181           accountSpace = accSpaceResolver.resolve(ivorn);
182           
183           assert accountSpace != null : "Account Space should not be null";
184         }
185         catch(Exception e) {
186           accountSpace = null;
187           
188           throw new LoginException("Failed to resolve account space for <" + ivorn.toString() + ">", e);
189         }
190 
191         // We pass the tests so set the current account info in our session.
192         session.setAttribute(SessionKeys.USER, name);
193         session.setAttribute(
194             SessionKeys.CREDENTIAL,
195             "guest@is.this.needed?");
196         session.setAttribute(SessionKeys.COMMUNITY_ACCOUNT, token.getAccount());
197         session.setAttribute(
198             SessionKeys.COMMUNITY_NAME,
199             CommunityConfig.getCommunityName());
200         session.setAttribute(SessionKeys.IVORN, accountSpace);
201             
202         session.setAttribute("community_authority",community);
203         //
204         // Set the current account info in our request.
205         request.setAttribute(USER_PARAM, user);
206         //
207         // Add our results.
208         // Currently just use a non-null map to indicate success
209         final Map results = new HashMap();
210         return results;
211     }
212     /***
213      * These checks are also done by the sitemap now, but
214      * no harm in doing them again.
215      * @param param parameter to check
216      * @param log logfile
217      * @return trimmed param
218      * @throws LoginException if the param is null or empty
219      */
220     private String checkParameter(final String param, final Logger log) throws LoginException {
221         //
222         // Check for a null or blank parameter.
223         String newParam;
224         if (null == param) {
225             log.error("Null parameter");
226             throw new LoginException("parameter is null");
227         } else {
228             newParam = param.trim();
229             if (param.length() <= 0) {
230                 log.error("Empty parameter");
231                 throw new LoginException("parameter is empty");
232             }
233         }
234         return newParam;
235     }
236 
237     /***
238      * During unit tests the logger isn't setup properly, hence this method to
239      * use a console logger instead. 
240      *  
241      */
242     private void checkLogger() {
243         log = super.getLogger();
244         if (log == null) {
245             enableLogging(new ConsoleLogger());
246             log = super.getLogger();
247         }
248     }
249 }
250 /***
251  * <cvs:log>
252  * $Log: LoginAction.java,v $
253  * Revision 1.32  2005/01/31 19:39:00  jdt
254  * Merges from POR_JDT_882
255  *
256  * Revision 1.31.28.2  2005/01/31 11:48:49  jdt
257  * fixed some noncompiling tests - these need attention, and dropped the debug flag from the login action.
258  *
259  * Revision 1.31.28.1  2005/01/31 02:16:39  jdt
260  * Rationalised config properties
261  *
262  * Revision 1.31  2004/12/07 16:26:04  clq2
263  * portal_kea_719
264  *
265  * Revision 1.30.30.1  2004/12/06 17:56:23  kea
266  * Fix for exception when bad community name given.
267  *
268  * Revision 1.30  2004/10/22 14:40:22  gps
269  * - storing account space IVORN
270  *
271  * Revision 1.29  2004/10/05 14:32:55  gps
272  * - myspace end point changes
273  *
274  * Revision 1.28  2004/05/27 17:17:13  jdt
275  * removed obsolete reference to CommunityConfig
276  *
277  * Revision 1.27  2004/05/14 19:32:40  KevinBenson
278  * new temporary session variable for the community authority
279  *
280  * Revision 1.26  2004/04/21 16:59:39  jdt
281  * temporary change to accommodate bug 297
282  *
283  * Revision 1.25  2004/04/05 16:42:29  jdt
284  * reinstated the init method till we decide whether it is really required.
285  *
286  * Revision 1.24  2004/04/02 11:53:17  jdt
287  * Merge from PLGN_JDT_bz#281a
288  *
289  * 
290  * </cvs:log>
291  */