package controllers; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newHashMap; import static service.filestore.roles.Admin.isAdmin; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.jcr.RepositoryException; import javax.jcr.Session; import models.GroupManager; import models.User; import models.UserDAO; import org.apache.jackrabbit.api.security.user.Authorizable; import org.apache.jackrabbit.api.security.user.Group; import org.jcrom.Jcrom; import org.specs2.specification.GroupsLike.group; import play.libs.F; import play.mvc.Result; import play.mvc.With; import providers.CacheableUserProvider; import service.JcrSessionFactory; import service.filestore.JsonBuilder; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.inject.Inject; @With(UncacheableAction.class) public class GroupController extends SessionAwareController { @Inject public GroupController(JcrSessionFactory sessionFactory, Jcrom jcrom, CacheableUserProvider subjectHandler) { super(sessionFactory, jcrom, subjectHandler); } @SubjectPresent public Result list() { return inUserSession(new F.Function<Session, Result>() { @Override public final Result apply(Session session) throws RepositoryException { final ArrayNode json = JsonNodeFactory.instance.arrayNode(); final GroupManager groupManager = new GroupManager(session); for (final Group group : groupManager.list()) { json.add(groupJson(session, group)); } return ok(json).as("application/json; charset=utf-8"); } }); } @SubjectPresent public Result create() { final JsonNode json = request().body().asJson(); if (!json.has("name")) { return badRequest("New groups require a name."); } return adminOnly(new F.Function<Session, Result>() { @Override public final Result apply(Session session) throws RepositoryException { final GroupManager groupManager = new GroupManager(session); final Group g = groupManager.create(json.get("name").asText()); return created(groupJson(session, g)) .as("application/json; charset=utf-8"); } }); } @SubjectPresent public Result update(final String id) { final JsonNode json = request().body().asJson(); if (!json.has("members") || !json.get("members").isArray()) { return badRequest("Updating groups require a member list."); } return adminOnly(new F.Function<Session, Result>() { @Override public final Result apply(Session session) throws RepositoryException { final UserDAO dao = new UserDAO(session, jcrom); final GroupManager groupManager = new GroupManager(session); final Group g = groupManager.find(id); final Set<String> userIds = Sets.newLinkedHashSet(); for (JsonNode userIdNode : json.get("members")) { userIds.add(userIdNode.asText()); } final Map<String, User> currentMembers = newHashMap(); { Iterator<Authorizable> iter = g.getDeclaredMembers(); while (iter.hasNext()) { final Authorizable auth = iter.next(); final User user = dao.findByJackrabbitID(auth.getID()); if (user != null) { currentMembers.put(user.getId(), user); } } } for (String userId : userIds) { if (!currentMembers.containsKey(userId)) { final User user = dao.loadById(userId); g.addMember(dao.jackrabbitUser(user)); } } for (User user : currentMembers.values()) { if (!userIds.contains(user.getId())) { g.removeMember(dao.jackrabbitUser(user)); } } session.save(); return ok(groupJson(session, g)) .as("application/json; charset=utf-8"); } }); } @SubjectPresent public Result delete(final String id) { return adminOnly(new F.Function<Session, Result>() { @Override public final Result apply(Session session) throws RepositoryException { final GroupManager groupManager = new GroupManager(session); groupManager.delete(id); return noContent(); } }); } @SubjectPresent public Result get(final String id) { return inUserSession(new F.Function<Session, Result>() { @Override public final Result apply(Session session) throws RepositoryException { final GroupManager groupManager = new GroupManager(session); final Group g = groupManager.find(id); return ok(groupJson(session, g)).as("application/json; charset=utf-8"); } }); } protected JsonNode groupJson(Session session, final Group g) throws RepositoryException { final JsonBuilder jb = new JsonBuilder(); final UserDAO dao = new UserDAO(session, jcrom); List<User> members = newArrayList(); Iterator<Authorizable> iter = g.getMembers(); while (iter.hasNext()) { final String jackrabbitUserId = iter.next().getID(); final User user = dao.findByJackrabbitID(jackrabbitUserId); if (user != null) { members.add(user); } } return jb.toJson(g, members); } protected Result adminOnly( final F.Function<Session, Result> operation) { return inUserSession(new F.Function<Session, Result>() { @Override public final Result apply(Session session) throws Throwable { final UserDAO dao = new UserDAO(session, jcrom); if (!isAdmin(session, dao, dao.get(getUser()))) { return forbidden(); } return operation.apply(session); } }); } }