package net.frozenorb.apiv3.models; import com.google.common.collect.Collections2; import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.DeleteResult; import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.AllArgsConstructor; import lombok.Getter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.utils.SyncUtils; import org.bson.Document; import org.bson.types.ObjectId; import java.util.*; @AllArgsConstructor public final class Grant { private static final MongoCollection grantsCollection = APIv3.getDatabase().getCollection("grants", Grant.class); @Getter @Id private String id; @Getter private UUID user; @Getter private String reason; @Getter private Set scopes = new HashSet<>(); // So on things w/o scopes we still load properly (Morphia drops empty sets) @Getter private String rank; @Getter private Date expiresAt; @Getter private UUID addedBy; @Getter private Date addedAt; @Getter private UUID removedBy; @Getter private Date removedAt; @Getter private String removalReason; public static List findAllSync() { return SyncUtils.blockMulti(grantsCollection.find()); } public static List findAllPaginatedSync(int skip, int pageSize) { return SyncUtils.blockMulti(grantsCollection.find().sort(new Document("addedAt", 1)).skip(skip).limit(pageSize)); } public static List findByRankSync(Iterable ranks) { return SyncUtils.blockMulti(grantsCollection.find(new Document("rank", new Document("$in", ranks)))); } public static Grant findByIdSync(String id) { return SyncUtils.blockOne(grantsCollection.find(new Document("_id", id))); } public static List findByUserSync(User user) { return findByUserSync(user.getId()); } public static List findByUserSync(UUID user) { return SyncUtils.blockMulti(grantsCollection.find(new Document("user", user))); } public static void findAll(SingleResultCallback> callback) { grantsCollection.find().into(new ArrayList<>(), callback); } public static void findAllPaginated(int skip, int pageSize, SingleResultCallback> callback) { grantsCollection.find().sort(new Document("addedAt", 1)).skip(skip).limit(pageSize).into(new ArrayList<>(), callback); } public static void findByRank(Iterable ranks, SingleResultCallback> callback) { grantsCollection.find(new Document("rank", new Document("$in", ranks))).into(new ArrayList<>(), callback); } public static void findById(String id, SingleResultCallback callback) { grantsCollection.find(new Document("_id", id)).first(callback); } public static void findByUser(User user, SingleResultCallback> callback) { findByUser(user.getId(), callback); } public static void findByUser(UUID user, SingleResultCallback> callback) { grantsCollection.find(new Document("user", user)).into(new ArrayList<>(), callback); } public static void findByUserGrouped(Iterable users, SingleResultCallback>> callback) { grantsCollection.find(new Document("user", new Document("$in", users))).into(new ArrayList<>(), (grants, error) -> { if (error != null) { callback.onResult(null, error); } else { Map> result = new HashMap<>(); for (UUID user : users) { result.put(user, new ArrayList<>()); } for (Grant grant : grants) { result.get(grant.getUser()).add(grant); } callback.onResult(result, null); } }); } public Grant() {} // For Morphia public Grant(User user, String reason, Set scopes, Rank rank, Date expiresAt, User addedBy) { this.id = new ObjectId().toString(); this.user = user.getId(); this.reason = reason; this.scopes = new HashSet<>(Collections2.transform(scopes, ServerGroup::getId)); this.rank = rank.getId(); this.expiresAt = expiresAt; this.addedBy = addedBy == null ? null : addedBy.getId(); this.addedAt = new Date(); } public boolean isActive() { return !(isExpired() || isRemoved()); } public boolean isExpired() { if (expiresAt == null) { return false; // Never expires } else { return expiresAt.before(new Date()); } } public boolean isRemoved() { return removedBy != null; } public boolean appliesOn(ServerGroup serverGroup) { return isGlobal() || scopes.contains(serverGroup.getId()); } public boolean isGlobal() { return scopes.isEmpty(); } public void insert() { BlockingCallback callback = new BlockingCallback<>(); grantsCollection.insertOne(this, callback); callback.get(); } public void delete(User removedBy, String reason) { this.removedBy = removedBy.getId(); this.removedAt = new Date(); this.removalReason = reason; BlockingCallback callback = new BlockingCallback<>(); grantsCollection.deleteOne(new Document("_id", id), callback); callback.get(); } }