package com.aperture_software.glados_wiki.services;
import com.aperture_software.glados_wiki.entities.Group;
import com.aperture_software.glados_wiki.entities.User;
import com.aperture_software.glados_wiki.support.Sha256;
import com.google.common.base.Optional;
import com.google.common.primitives.Bytes;
import org.apache.commons.lang3.tuple.Pair;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Key;
import org.mongodb.morphia.query.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* User: jhyun
* Date: 13. 11. 26
* Time: 오후 3:57
*/
@Service
public class UserService {
private static Logger LOG = LoggerFactory.getLogger(UserService.class);
@Autowired
private Datastore datastore;
@Autowired
private GroupService groupService;
@Autowired
private Sha256 sha256;
public Optional<User> create(final String username, final String email) {
Optional<Group> g = groupService.getByName(GroupService.EVERYONE_ROLE);
//
User u = new User();
u.setUsername(username);
u.setEmail(email);
if (g.isPresent()) {
u.getGroups().add(g.get());
} else {
LOG.warn(String.format("EVERYONE GROUP [%s] NOT FOUND! (IGNORED.)", GroupService.EVERYONE_ROLE));
}
//
Key<User> k = datastore.save(u);
return this.getByUsername(u.getUsername());
}
public void delete(User u) {
datastore.delete(u);
}
public Optional<User> getByUsername(final String username) {
Key<User> k = new Key<User>(User.class, username);
User u = datastore.getByKey(User.class, k);
return Optional.fromNullable(u);
}
public Optional<User> update(User u) {
Key<User> k = datastore.save(u);
return this.getByUsername(u.getUsername());
}
public Optional<User> setPassword(User u, final String plainTextPassword) {
Pair<List<Byte>, String> p = sha256.getSaltAndHash(plainTextPassword);
u.setPassword(p.getRight());
u.setPasswordSalt(Bytes.toArray(p.getLeft()));
//
return this.update(u);
}
public List<User> list(final Optional<String> searchTerm,
final Optional<String> groupName,
final int offset, final int limit) {
//
Query<User> q = datastore.createQuery(User.class)
.offset(offset).limit(limit)
.order("-ctime");
//
queryApplySearch(searchTerm, groupName, q);
//
return q.asList();
}
private void queryApplySearch(Optional<String> searchTerm, Optional<String> groupName, Query<User> q) {
if (searchTerm.isPresent()) {
final String searchTerm_ = searchTerm.get();
q.or(
q.criteria("username").containsIgnoreCase(searchTerm_),
q.criteria("email").containsIgnoreCase(searchTerm_),
q.criteria("description").containsIgnoreCase(searchTerm_));
}
//
if (groupName.isPresent()) {
Optional<Group> g = groupService.getByName(groupName.get().toString());
if (g.isPresent()) {
q.criteria("groups").hasThisOne(g.get());
} else {
LOG.warn(String.format("GROUP [%s] NOT FOUND, IGNORED IN CRITERIA.", groupName));
}
}
}
public long count(final Optional<String> searchTerm,
final Optional<String> groupName) {
//
Query<User> q = datastore.createQuery(User.class);
queryApplySearch(searchTerm, groupName, q);
return q.countAll();
}
public long countByEmail(final String email) {
Query<User> q = datastore.createQuery(User.class);
q.criteria("email").equal(email);
return q.countAll();
}
}