package net.frozenorb.apiv3.model; import com.google.common.collect.ImmutableSet; import lombok.Getter; import lombok.ToString; import net.frozenorb.apiv3.accessor.Grants; import org.bson.Document; import java.time.Instant; import java.util.Collection; import java.util.Set; import java.util.UUID; @ToString public final class Grant extends BaseModel { @Getter private String id; @Getter private UUID target; @Getter private String reason; @Getter private Set scopes; @Getter private String rank; @Getter private Instant expiresAt; @Getter private UUID addedBy; @Getter private Instant addedAt; @Getter private UUID removedBy; @Getter private Instant removedAt; @Getter private String removalReason; public Grant(Document json) { super(Grants.COLLECTION_NAME); this.id = json.getString("_id"); this.target = UUID.fromString(json.getString("target")); this.reason = json.getString("reason"); this.scopes = ImmutableSet.copyOf((Collection) json.get("scopes")); // This is a safe cast, the collection's type is always String this.rank = json.getString("rank"); this.expiresAt = (Instant) json.get("expiresAt"); this.addedBy = UUID.fromString(json.getString("addedBy")); this.addedAt = (Instant) json.get("addedAt"); if (json.containsKey("removedBy")) { this.removedBy = UUID.fromString(json.getString("removedBy")); this.removedAt = (Instant) json.get("removedAt"); this.removalReason = json.getString("removalReason"); } setId(id); } public void delete(UUID removedBy, String reason) { this.removedBy = removedBy; this.removedAt = Instant.now(); this.removalReason = reason; Document set = new Document(); set.put("removedBy", removedBy.toString()); set.put("removedAt", removedAt); set.put("removalReason", removalReason); super.update(new Document("$set", set), (result, error) -> {}); } public boolean isActive() { return !(isExpired() || isRemoved()); } public boolean isExpired() { if (expiresAt == null) { return false; // Never expires } else { return expiresAt.isAfter(Instant.now()); } } public boolean isRemoved() { return removedBy != null; } public Document toLiteJson() { Document json = new Document(); json.put("id", id); json.put("target", target.toString()); json.put("reason", reason); json.put("scopes", scopes); json.put("rank", rank); json.put("expiresAt", expiresAt == null ? null : expiresAt.toString()); json.put("addedBy", addedBy.toString()); json.put("addedAt", addedAt.toString()); Document statusJson = new Document(); statusJson.put("active", isActive()); statusJson.put("expired", isExpired()); statusJson.put("removed", isRemoved()); json.put("status", statusJson); if (removedBy != null) { json.put("removedBy", removedBy.toString()); json.put("removedAt", removedAt.toString()); json.put("removalReason", removalReason); } return json; } }