package org.carlspring.strongbox.users.service.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.apache.commons.lang.StringUtils;
import org.carlspring.strongbox.data.service.CommonCrudService;
import org.carlspring.strongbox.users.domain.User;
import org.carlspring.strongbox.users.security.SecurityTokenProvider;
import org.carlspring.strongbox.users.service.UserService;
import org.jose4j.lang.JoseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;
/**
* DAO implementation for {@link User} entities.
*
* @author Alex Oreshkevich
*/
@Service
@Transactional
public class UserServiceImpl extends CommonCrudService<User>
implements UserService
{
public static final Logger logger = LoggerFactory.getLogger(UserService.class);
public static final String USERS_CACHE = "users";
@Inject
CacheManager cacheManager;
@Inject
SecurityTokenProvider tokenProvider;
Cache usersCache;
@PostConstruct
public void init()
{
usersCache = cacheManager.getCache(USERS_CACHE);
if (usersCache == null)
{
throw new BeanCreationException("Unable create users cache");
}
}
@Override
public Class<User> getEntityClass()
{
return User.class;
}
@Override
@Cacheable(value = USERS_CACHE, key = "#name", sync = true)
public User findByUserName(String name)
{
String sQuery = String.format("select * from %s where userName=:userName", getEntityClass().getSimpleName());
OSQLSynchQuery<Long> oQuery = new OSQLSynchQuery<Long>(sQuery);
oQuery.setLimit(1);
HashMap<String, String> params = new HashMap<String, String>();
params.put("userName", name);
List<User> resultList = getDelegate().command(oQuery).execute(params);
return !resultList.isEmpty() ? resultList.iterator().next() : null;
}
@Override
public <S extends User> S save(S newUser)
{
S user = super.save(newUser);
usersCache.put(user.getUsername(), getDelegate().detachAll(user, true));
return user;
}
@Override
public Optional<User> findOne(String id)
{
if (id == null)
{
return Optional.empty();
}
Optional<User> optionalUser = super.findOne(id);
return optionalUser.map(u -> {
usersCache.put(u.getUsername(), getDelegate().detachAll(u, true));
return Optional.ofNullable(u);
}).orElse(optionalUser);
}
@Override
public void delete(String objectId)
{
findOne(objectId).ifPresent(user -> {
usersCache.evict(user.getUsername());
});
super.delete(objectId);
}
@Override
public void delete(User user)
{
usersCache.evict(user.getUsername());
super.delete(user);
}
@Override
public void deleteAll()
{
usersCache.clear();
super.deleteAll();
}
@Override
public String generateSecurityToken(String userName)
throws JoseException
{
User user = findByUserName(userName);
if (StringUtils.isEmpty(user.getSecurityTokenKey()))
{
return null;
}
Map<String, String> claimMap = new HashMap<>();
claimMap.put("security-token-key", user.getSecurityTokenKey());
return tokenProvider.getToken(userName, claimMap, null);
}
@Override
public String generateAuthenticationToken(String userName,
Integer expireMinutes)
throws JoseException
{
User user = findByUserName(userName);
Map<String, String> claimMap = new HashMap<>();
claimMap.put("credentials", user.getPassword());
return tokenProvider.getToken(userName, claimMap, expireMinutes);
}
@Override
public void verifySecurityToken(String userName,
String apiKey)
{
User user = findByUserName(userName);
Map<String, String> claimMap = new HashMap<>();
claimMap.put("security-token-key", user.getSecurityTokenKey());
tokenProvider.verifyToken(apiKey, userName, claimMap);
}
}