Commit f52fec7d authored by Matija Obreza's avatar Matija Obreza
Browse files

Core (abstract) user service implementation

parent 0d4eb283
......@@ -48,7 +48,7 @@ import org.springframework.security.core.userdetails.UserDetails;
//@Table(name = "user")
//@Audited
@MappedSuperclass
public abstract class BasicUser<R> extends AuditedVersionedModel implements UserDetails {
public abstract class BasicUser<R extends GrantedAuthority> extends AuditedVersionedModel implements UserDetails {
private static final long serialVersionUID = -5318892732608111516L;
......
/*
* Copyright 2017 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys.blocks.security.service;
import java.util.Set;
import org.genesys.blocks.security.model.BasicUser;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetailsService;
public interface BasicUserService<R extends GrantedAuthority, T extends BasicUser<R>> extends UserDetailsService {
/**
* Get User by id
*
* @param id
* @return the user or <code>null</code>
*/
T getUser(long id);
/**
* Get User by email
*
* @param email
* @return the user
*/
T getUserByEmail(String email);
/**
* Create a new user account
*
* @param email unique email address
* @param fullName Full name
* @param password initial account password
* @param accountType TODO
* @return the new user
*/
T createUser(String email, String fullName, String password, BasicUser.AccountType accountType);
/**
* Grant specified roles to user. The {@link UserRole#USER} will be added if missing.
*
* @param user
* @param roles
* @return the updated user
*/
T setRoles(T user, Set<R> roles);
/**
* Update user information
*
* @param user the user
* @param email new email address
* @param fullName new fullName
* @return
*/
T updateUser(T user, String email, String fullName);
/**
* Change password
*
* @param user the user
* @param password new password
* @return
*/
T changePassword(T user, String password);
/**
* Try to delete user.
*
* @param user user to delete
*/
void deleteUser(T user);
/**
* Lock user account
*
* @param userID User ID
* @param locked Is account locked
*/
void setAccountLockLocal(long userId, boolean locked);
void setAccountLock(long userId, boolean locked);
}
/*
* Copyright 2017 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys.blocks.security.service.impl;
import java.util.Date;
import java.util.Set;
import org.genesys.blocks.security.model.BasicUser;
import org.genesys.blocks.security.service.BasicUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
@Transactional(readOnly = true)
public abstract class BasicUserServiceImpl<R extends GrantedAuthority, T extends BasicUser<R>> implements BasicUserService<R, T> {
public static final Logger LOG = LoggerFactory.getLogger(BasicUserServiceImpl.class);
private long accountLockoutTime = 5 * 60 * 1000;
@Autowired
private JpaRepository<T, Long> userRepository;
@Autowired
PasswordEncoder passwordEncoder;
public void setAccountLockoutTime(long accountLockoutTime) {
this.accountLockoutTime = accountLockoutTime;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return getUserByEmail(username);
}
@Override
public T getUser(long id) {
return userRepository.findOne(id);
}
@Override
@Transactional
public T updateUser(T user, String email, String fullName) {
user.setEmail(email);
user.setFullName(fullName);
return userRepository.save(user);
}
@Override
@Transactional
public void deleteUser(T user) {
userRepository.delete(user);
}
@Override
@Transactional
// FIXME Needs permission check
public T setRoles(T user, Set<R> newRoles) {
user = userRepository.findOne(user.getId());
// If roles match, do nothing
if (newRoles.containsAll(user.getRoles()) && user.getRoles().containsAll(newRoles)) {
LOG.debug("Roles {} match {}. No change.", newRoles, user.getRoles());
return user;
}
user.getRoles().clear();
user.getRoles().addAll(newRoles);
LOG.info("Setting roles for user {} to {}", user.getEmail(), user.getRoles());
return userRepository.save(user);
}
@Override
@Transactional
public T changePassword(final T user, final String password) {
setPassword(user, password);
return userRepository.save(user);
}
private void setPassword(final T user, final String password) {
user.setPassword(password == null ? null : passwordEncoder.encode(password));
}
/**
* For internal use only.
*/
@Override
@Transactional
public void setAccountLockLocal(long userId, boolean locked) {
final T user = getUser(userId);
if (locked) {
// Lock for account until some time
user.setLockedUntil(new Date(System.currentTimeMillis() + accountLockoutTime));
LOG.warn("Locking user account for user=" + user.getEmail() + " until=" + user.getLockedUntil());
} else {
LOG.warn("Unlocking user account for user=" + user.getEmail());
user.setLockedUntil(null);
}
userRepository.save(user);
}
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR')")
public void setAccountLock(long userId, boolean locked) {
setAccountLockLocal(userId, locked);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment