Forbid logins from disabled users.
[pithos] / src / gr / ebs / gss / server / webdav / login / GssWebDAVLoginModule.java
1 /*\r
2  * Copyright 2005, 2008, 2009 Electronic Business Systems Ltd.\r
3  *\r
4  * This file is part of GSS.\r
5  *\r
6  * GSS is free software: you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation, either version 3 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * GSS is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with GSS.  If not, see <http://www.gnu.org/licenses/>.\r
18  */\r
19 package gr.ebs.gss.server.webdav.login;\r
20 \r
21 import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;\r
22 import gr.ebs.gss.client.exceptions.RpcException;\r
23 import gr.ebs.gss.server.domain.User;\r
24 import gr.ebs.gss.server.ejb.ExternalAPI;\r
25 import gr.ebs.gss.server.ejb.TransactionHelper;\r
26 \r
27 import java.io.UnsupportedEncodingException;\r
28 import java.security.Principal;\r
29 import java.security.acl.Group;\r
30 import java.util.Date;\r
31 import java.util.HashSet;\r
32 import java.util.concurrent.Callable;\r
33 \r
34 import javax.naming.Context;\r
35 import javax.naming.InitialContext;\r
36 import javax.naming.NamingException;\r
37 import javax.rmi.PortableRemoteObject;\r
38 import javax.security.auth.login.FailedLoginException;\r
39 import javax.security.auth.login.LoginException;\r
40 \r
41 import org.apache.commons.codec.binary.Base64;\r
42 import org.apache.commons.logging.Log;\r
43 import org.apache.commons.logging.LogFactory;\r
44 import org.jboss.security.auth.spi.UsernamePasswordLoginModule;\r
45 \r
46 \r
47 /**\r
48  * The custom login module for the GSS WebDAV implementation.\r
49  */\r
50 public class GssWebDAVLoginModule extends UsernamePasswordLoginModule {\r
51 \r
52         /**\r
53          * Logger for this class\r
54          */\r
55         private static final Log logger = LogFactory.getLog(GssWebDAVLoginModule.class);\r
56 \r
57         /**\r
58          * A helper method that retrieves a reference to the ExternalAPI bean and\r
59          * stores it for future use.\r
60          *\r
61          * @return an ExternalAPI instance\r
62          * @throws RpcException in case an error occurs\r
63          */\r
64         private ExternalAPI getService() throws RpcException {\r
65                 try {\r
66                         final Context ctx = new InitialContext();\r
67                         final Object ref = ctx.lookup(getConfiguration().getString("externalApiPath"));\r
68                         return (ExternalAPI) PortableRemoteObject.narrow(ref, ExternalAPI.class);\r
69                 } catch (final NamingException e) {\r
70                         logger.error("Unable to retrieve the ExternalAPI EJB", e);\r
71                         throw new RpcException("An error occurred while contacting the naming service");\r
72                 }\r
73         }\r
74 \r
75         @Override\r
76         protected String getUsersPassword() throws LoginException {\r
77                 String username = getUsername();\r
78                 try {\r
79                         final User user = getService().findUser(username);\r
80                         if (user == null) throw new FailedLoginException("User '" + username + "' not found.");\r
81                         if (!user.isActive()) throw new FailedLoginException("User '" + username + "' is disabled.");\r
82                         if (user.getWebDAVPassword() != null && user.getWebDAVPassword().length() > 0)\r
83                                 return user.getWebDAVPassword();\r
84                         // If no password has ever been generated, use token instead\r
85                         String tokenEncoded = new String(Base64.encodeBase64(user.getAuthToken()), "US-ASCII");\r
86                         user.setWebDAVPassword(tokenEncoded);\r
87                         new TransactionHelper<Void>().tryExecute(new Callable<Void>() {\r
88                                 @Override\r
89                                 public Void call() throws Exception {\r
90                                         getService().updateUser(user);\r
91                                         return null;\r
92                                 }\r
93                         });\r
94                         return tokenEncoded;\r
95                 } catch (RpcException e) {\r
96                         String error = "An error occurred while communicating with the service";\r
97                         logger.error(error, e);\r
98                         throw new LoginException(e.getMessage());\r
99                 } catch (UnsupportedEncodingException e) {\r
100             logger.error("", e);\r
101             throw new LoginException(e.getMessage());\r
102                 } catch (Exception e) {\r
103             logger.error("", e);\r
104                         throw new LoginException(e.getMessage());\r
105                 }\r
106         }\r
107 \r
108         /**\r
109          * Overrides parent's implementation by returning only the simpleUser\r
110          * role for any successful login.\r
111          *\r
112          * @return Group[] that contains only the authenticatedUser group (role)\r
113          * @throws LoginException\r
114          * @see org.jboss.security.auth.spi.AbstractServerLoginModule#getRoleSets()\r
115          */\r
116         @Override\r
117         protected Group[] getRoleSets() throws LoginException {\r
118                 Principal principal;\r
119                 try {\r
120                         principal = createIdentity("simpleUser");\r
121                 } catch (Exception e) {\r
122                         logger.error("", e);\r
123                         throw new LoginException(e.getMessage());\r
124                 }\r
125                 Group rolesGroup = null;\r
126                 rolesGroup = createGroup("Roles", new HashSet());\r
127                 rolesGroup.addMember(principal);\r
128                 Group[] roles = new Group[1];\r
129                 roles[0] = rolesGroup;\r
130                 // Update the last login.\r
131                 try {\r
132                         new TransactionHelper<Void>().tryExecute(new Callable<Void>() {\r
133                                 @Override\r
134                                 public Void call() throws Exception {\r
135                                         User user = getService().findUser(getUsername());\r
136                                         user.setLastLogin(new Date());\r
137                                         getService().updateUser(user);\r
138                                         return null;\r
139                                 }\r
140                         });\r
141                 } catch (Exception e) {\r
142                         logger.error("", e);\r
143                         throw new LoginException(e.getMessage());\r
144                 }\r
145                 return roles;\r
146         }\r
147 \r
148 }\r