package net.frozenorb.apiv3.models; import com.google.common.collect.Collections2; import lombok.AllArgsConstructor; import lombok.Getter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.utils.UUIDUtils; import org.bson.types.ObjectId; import org.mongodb.morphia.annotations.Entity; import org.mongodb.morphia.annotations.Id; import org.mongodb.morphia.annotations.Indexed; import java.util.*; @Entity(value = "grants", noClassnameStored = true) @AllArgsConstructor public final class Grant { @Getter @Id private String id; @Getter @Indexed 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 @Indexed private String rank; @Getter private Date expiresAt; @Getter private UUID addedBy; @Getter @Indexed private Date addedAt; @Getter private UUID removedBy; @Getter private Date removedAt; @Getter private String removalReason; public static Grant byId(String id) { return APIv3.getDatastore().createQuery(Grant.class).field("id").equal(id).get(); } public static Map> byUserGrouped(Iterable ids) { Map> result = new HashMap<>(); Set uuidsToSearch = new HashSet<>(); for (UUID id : ids) { result.put(id, new ArrayList<>()); if (UUIDUtils.isAcceptableUUID(id)) { uuidsToSearch.add(id); } } APIv3.getDatastore().createQuery(Grant.class).field("user").in(uuidsToSearch).forEach((grant) -> { result.get(grant.getUser()).add(grant); }); return result; } 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 void delete(User removedBy, String reason) { this.removedBy = removedBy.getId(); this.removedAt = new Date(); this.removalReason = reason; APIv3.getDatastore().save(this); } 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(); } }