001 // Copyright 2008 Thiago H. de Paula Figueiredo
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package br.com.arsmachina.authentication.controller.impl;
016
017 import java.util.List;
018 import java.util.Random;
019
020 import org.springframework.transaction.annotation.Transactional;
021
022 import br.com.arsmachina.authentication.controller.PasswordEncrypter;
023 import br.com.arsmachina.authentication.controller.PermissionController;
024 import br.com.arsmachina.authentication.controller.PermissionGroupController;
025 import br.com.arsmachina.authentication.controller.UserController;
026 import br.com.arsmachina.authentication.dao.UserDAO;
027 import br.com.arsmachina.authentication.entity.Permission;
028 import br.com.arsmachina.authentication.entity.PermissionGroup;
029 import br.com.arsmachina.authentication.entity.Role;
030 import br.com.arsmachina.authentication.entity.User;
031 import br.com.arsmachina.controller.impl.SpringControllerImpl;
032
033 /**
034 * {@link UserController} implementation.
035 *
036 * @author Thiago H. de Paula Figueiredo
037 */
038 public class UserControllerImpl extends SpringControllerImpl<User, Integer> implements
039 UserController {
040
041 private Random random = new Random();
042
043 private UserDAO dao;
044
045 private PermissionGroup allUsersPermissionGroup;
046
047 private PasswordEncrypter passwordEncrypter;
048
049 private PermissionController permissionController;
050
051 private PermissionGroupController permissionGroupController;
052
053 /**
054 * Single constructor of this class.
055 *
056 * @param dao an {@link UserDAO}. It cannot be <code>null</code>.
057 * @param passwordEncrypter a {@link PasswordEncrypter}. It cannot be <code>null</code>.
058 * @param permissionController a {@link PermissionController}. It cannot be <code>null</code>. .
059 * @param permissionGroupController a {@link PermissionGroupController}. It cannot be
060 * <code>null</code>.
061 */
062 public UserControllerImpl(UserDAO dao, PasswordEncrypter passwordEncrypter,
063 PermissionController permissionController,
064 PermissionGroupController permissionGroupController) {
065
066 super(dao);
067 this.dao = dao;
068
069 if (permissionController == null) {
070 throw new IllegalArgumentException("Parameter permissionController cannot be null");
071 }
072
073 if (permissionGroupController == null) {
074 throw new IllegalArgumentException("Parameter permissionGroupController cannot be null");
075 }
076
077 if (passwordEncrypter == null) {
078 throw new IllegalArgumentException("Parameter passwordEncrypter cannot be null");
079 }
080
081 this.permissionController = permissionController;
082 this.permissionGroupController = permissionGroupController;
083 this.passwordEncrypter = passwordEncrypter;
084
085 }
086
087 /**
088 * Ensures basic permissions and group permissions exist.
089 *
090 * @param permissionController a {@link PermissionController}.
091 * @param permissionGroupController a {@link PermissionGroupController}.
092 */
093 private void ensureBasicPermissionsExist(PermissionController permissionController,
094 PermissionGroupController permissionGroupController) {
095
096 final String roleName = Permission.USER_ROLE_NAME;
097 Permission userPermission = permissionController.findByName(roleName);
098
099 if (userPermission == null) {
100
101 userPermission = new Permission();
102 userPermission.setName(Permission.USER_ROLE_NAME);
103 permissionController.save(userPermission);
104
105 }
106
107 final String groupName = PermissionGroup.ALL_USERS_PERMISSION_GROUP_NAME;
108 PermissionGroup group = permissionGroupController.findByName(groupName);
109
110 if (group == null) {
111
112 group = new PermissionGroup();
113 group.setName(groupName);
114 group.add(userPermission);
115 permissionGroupController.save(group);
116
117 }
118
119 allUsersPermissionGroup = group;
120
121 }
122
123 /**
124 * Invokes <code>dao.findByLoginAndPassword()<code>.
125 * @param login
126 * @param password
127 * @return
128 * @see br.com.arsmachina.authentication.dao.UserDAO#findByLoginAndPassword(java.lang.String, java.lang.String)
129 */
130 @Transactional(readOnly = true)
131 public User findByLoginAndPassword(String login, String password) {
132 return dao.findByLoginAndPassword(login, password);
133 }
134
135 /**
136 * Invokes <code>dao.findByLogin()<code>.
137 * @param login
138 * @return
139 * @see br.com.arsmachina.authentication.dao.UserDAO#findByLogin(java.lang.String)
140 */
141 @Transactional(readOnly = true)
142 public User findByLogin(String login) {
143 return dao.findByLogin(login);
144 }
145
146 /**
147 * Invokes <code>delegate.findByRole()<code>.
148 * @param <T>
149 * @param roleClass
150 * @return
151 * @see br.com.arsmachina.authentication.dao.UserDAO#findByRole(java.lang.Class)
152 */
153 @Transactional(readOnly = true)
154 public <T extends Role> List<User> findByRole(Class<T> roleClass) {
155 return dao.findByRole(roleClass);
156 }
157
158 /**
159 * @see br.com.arsmachina.controller.impl.SpringControllerImpl#save(java.lang.Object)
160 */
161 @Transactional
162 @Override
163 public void save(User user) {
164
165 if (allUsersPermissionGroup == null) {
166 ensureBasicPermissionsExist(permissionController, permissionGroupController);
167 }
168
169 if (user.getPermissionGroups().contains(allUsersPermissionGroup) == false) {
170 user.add(allUsersPermissionGroup);
171 }
172
173 setPasswordIfNeeded(user);
174
175 encryptPassword(user);
176
177 super.save(user);
178
179 }
180
181 /**
182 * Encrypts the password if it is not encrypted already and then updates the user.
183 *
184 * @param user an {@link User}.
185 * @return <code>user</code>.
186 * @see br.com.arsmachina.controller.impl.SpringControllerImpl#update(java.lang.Object)
187 */
188 @Override
189 @Transactional
190 public User update(User user) {
191
192 encryptPassword(user);
193 return super.update(user);
194
195 }
196
197
198
199 /**
200 * Invokes <code>delegate.hasUserWithLogin()<code>.
201 * @param login
202 * @return
203 * @see br.com.arsmachina.authentication.dao.UserDAO#hasUserWithLogin(java.lang.String)
204 */
205 public boolean hasUserWithLogin(String login) {
206 return dao.hasUserWithLogin(login);
207 }
208
209 private void encryptPassword(User user) {
210
211 String password = user.getPassword();
212 password = passwordEncrypter.encrypt(password);
213 user.setPassword(password);
214
215 }
216
217 /**
218 * Creates a temporary throw-away random password if it was not set yet.
219 *
220 * @param user an {@link User}.
221 */
222 private void setPasswordIfNeeded(User user) {
223
224 if (user.getPassword() == null) {
225 user.setPassword(Integer.toHexString(random.nextInt()));
226 }
227
228 }
229
230 }