General API work

This commit is contained in:
Colin McDonald 2016-04-28 16:57:44 -04:00
parent a07d9f524b
commit 3780ead458
41 changed files with 196 additions and 157 deletions

View File

@ -7,8 +7,9 @@ import com.mongodb.MongoClient;
import com.mongodb.MongoCredential; import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress; import com.mongodb.ServerAddress;
import lombok.Getter; import lombok.Getter;
import net.frozenorb.apiv3.models.Rank; import net.frozenorb.apiv3.filters.ActorAttributeFilter;
import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.filters.AuthorizationFilter;
import net.frozenorb.apiv3.filters.ContentTypeFilter;
import net.frozenorb.apiv3.routes.GETDump; import net.frozenorb.apiv3.routes.GETDump;
import net.frozenorb.apiv3.routes.GETRoutes; import net.frozenorb.apiv3.routes.GETRoutes;
import net.frozenorb.apiv3.routes.announcements.GETAnnouncements; import net.frozenorb.apiv3.routes.announcements.GETAnnouncements;
@ -28,27 +29,30 @@ import net.frozenorb.apiv3.routes.serverGroups.GETServerGroups;
import net.frozenorb.apiv3.routes.servers.GETServer; import net.frozenorb.apiv3.routes.servers.GETServer;
import net.frozenorb.apiv3.routes.servers.GETServers; import net.frozenorb.apiv3.routes.servers.GETServers;
import net.frozenorb.apiv3.routes.users.*; import net.frozenorb.apiv3.routes.users.*;
import net.frozenorb.apiv3.weirdStuff.*; import net.frozenorb.apiv3.serialization.FollowAnnotationExclusionStrategy;
import net.frozenorb.apiv3.serialization.ObjectIdTypeAdapter;
import org.bson.types.ObjectId; import org.bson.types.ObjectId;
import org.mongodb.morphia.Datastore; import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Morphia; import org.mongodb.morphia.Morphia;
import spark.Request;
import spark.Spark;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import static spark.Spark.*; import static spark.Spark.*;
public final class APIv3 { public final class APIv3 {
// TODO: Cleanup main class
@Getter private static Datastore datastore; @Getter private static Datastore datastore;
private final Gson gson = new GsonBuilder().registerTypeAdapter(ObjectId.class, new ObjectIdTypeAdapter()).setExclusionStrategies(new FollowAnnotationExclusionStrategy()).create(); @Getter private static Properties config = new Properties();
private final Properties config = new Properties(); private final Gson gson = new GsonBuilder()
.registerTypeAdapter(ObjectId.class, new ObjectIdTypeAdapter())
.setExclusionStrategies(new FollowAnnotationExclusionStrategy())
.create();
APIv3() { APIv3() {
try { try {
// TODO: Load
config.load(APIv3.class.getClassLoader().getResourceAsStream("apiv3.properties")); config.load(APIv3.class.getClassLoader().getResourceAsStream("apiv3.properties"));
} catch (Exception ex) { } catch (Exception ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
@ -56,40 +60,12 @@ public final class APIv3 {
setupDatabase(); setupDatabase();
setupHttp(); setupHttp();
ServerGroup scope = ServerGroup.byId("HCTeams");
Map<ServerGroup, Rank> userRanks = new HashMap<>();
ServerGroup global = ServerGroup.byId("Global");
Map<String, Boolean> calculatedPermissions = global.getPermissions(userRanks.get(global));
// for global calculations
for (ServerGroup serverGroup : ServerGroup.values()) {
if (serverGroup != global) {
mergePermissions(serverGroup, userRanks.get(serverGroup), calculatedPermissions);
}
}
// for scoped calculations
mergePermissions(scope, userRanks.get(scope), calculatedPermissions);
}
public void mergePermissions(ServerGroup serverGroup, Rank rank, Map<String, Boolean> current) {
Map<String, Boolean> groupPermissions = serverGroup.getPermissions(rank);
groupPermissions.forEach((permissionNode, grant) -> {
if (!current.containsKey(permissionNode) || !current.get(permissionNode)) {
current.put(permissionNode, grant);
}
});
} }
private void setupDatabase() { private void setupDatabase() {
MongoClient mongoClient = new MongoClient(new ServerAddress((String) config.get("mongo.address"), (Integer) config.get("mongo.port")), MongoClient mongoClient = new MongoClient(new ServerAddress(
(String) config.get("mongo.address"),
(Integer) config.get("mongo.port")),
ImmutableList.of( ImmutableList.of(
MongoCredential.createCredential( MongoCredential.createCredential(
(String) config.get("mongo.username"), (String) config.get("mongo.username"),
@ -109,6 +85,7 @@ public final class APIv3 {
port((Integer) config.get("http.port")); port((Integer) config.get("http.port"));
before(new ContentTypeFilter()); before(new ContentTypeFilter());
before(new ActorAttributeFilter()); before(new ActorAttributeFilter());
before(new AuthorizationFilter());
get("/announcements", new GETAnnouncements(), gson::toJson); get("/announcements", new GETAnnouncements(), gson::toJson);
@ -134,11 +111,12 @@ public final class APIv3 {
get("/server/:id", new GETServer(), gson::toJson); get("/server/:id", new GETServer(), gson::toJson);
get("/servers", new GETServers(), gson::toJson); get("/servers", new GETServers(), gson::toJson);
delete("/user/:id/meta", new DELETEUserMeta(), gson::toJson);
get("/staff", new GETStaff(), gson::toJson); get("/staff", new GETStaff(), gson::toJson);
get("/user/:id", new GETUser(), gson::toJson); get("/user/:id", new GETUser(), gson::toJson);
get("/user/:id/details", new GETUserDetails(), gson::toJson); get("/user/:id/details", new GETUserDetails(), gson::toJson);
get("/user/:id/meta/:serverGroup", new GETUserMeta(), gson::toJson); get("/user/:id/meta/:serverGroup", new GETUserMeta(), gson::toJson);
get("/users", new GETUsers(), gson::toJson); post("/user/:id/login", new POSTUserLogin(), gson::toJson);
post("/user/:id/notify", new POSTUserNotify(), gson::toJson); post("/user/:id/notify", new POSTUserNotify(), gson::toJson);
post("/user/:id/register", new POSTUserRegister(), gson::toJson); post("/user/:id/register", new POSTUserRegister(), gson::toJson);
put("/user/:id/meta/:serverGroup", new PUTUserMeta(), gson::toJson); put("/user/:id/meta/:serverGroup", new PUTUserMeta(), gson::toJson);
@ -147,11 +125,4 @@ public final class APIv3 {
get("/routes", new GETRoutes()); get("/routes", new GETRoutes());
} }
public static void requireAuthorizedActor(Request req) {
Actor actor = req.attribute("actor");
if (!actor.isAuthorized()) {
Spark.halt();
}
}
} }

View File

@ -1,5 +1,6 @@
package net.frozenorb.apiv3.weirdStuff; package net.frozenorb.apiv3.filters;
import net.frozenorb.apiv3.unsorted.Actor;
import spark.Filter; import spark.Filter;
import spark.Request; import spark.Request;
import spark.Response; import spark.Response;

View File

@ -0,0 +1,20 @@
package net.frozenorb.apiv3.filters;
import net.frozenorb.apiv3.unsorted.Actor;
import net.frozenorb.apiv3.utils.ErrorUtils;
import spark.Filter;
import spark.Request;
import spark.Response;
import spark.Spark;
public final class AuthorizationFilter implements Filter {
public void handle(Request req, Response res) {
Actor actor = req.attribute("actor");
if (!actor.isAuthorized()) {
Spark.halt(ErrorUtils.error("Unauthorized access: Please authenticate as either a server, the website, or an authorized user.").toJson());
}
}
}

View File

@ -1,4 +1,4 @@
package net.frozenorb.apiv3.weirdStuff; package net.frozenorb.apiv3.filters;
import spark.Filter; import spark.Filter;
import spark.Request; import spark.Request;

View File

@ -1,14 +1,13 @@
package net.frozenorb.apiv3.models; package net.frozenorb.apiv3.models;
import lombok.Getter; import lombok.Getter;
import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.unsorted.Actor;
import org.bson.Document; import org.bson.Document;
import org.bson.types.ObjectId; import org.bson.types.ObjectId;
import org.mongodb.morphia.annotations.Entity; import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id; import org.mongodb.morphia.annotations.Id;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.UUID; import java.util.UUID;
@Entity(value = "auditLog", noClassnameStored = true) @Entity(value = "auditLog", noClassnameStored = true)
@ -17,19 +16,17 @@ public final class AuditLogEntry {
@Getter @Id private ObjectId id; @Getter @Id private ObjectId id;
@Getter private UUID performedBy; @Getter private UUID performedBy;
@Getter private Date performedAt; @Getter private Date performedAt;
@Getter private String performedFrom; @Getter private String actorName;
@Getter private String actionType; @Getter private String actionType;
@Getter private String description;
@Getter private Document actionData; @Getter private Document actionData;
public AuditLogEntry() {} // For Morphia public AuditLogEntry() {} // For Morphia
public AuditLogEntry(User performedBy, String performedFrom, String actionType, String description, Document actionData) { public AuditLogEntry(User performedBy, Actor actor, String actionType, Document actionData) {
this.performedBy = performedBy.getId(); this.performedBy = performedBy.getId();
this.performedAt = new Date(); this.performedAt = new Date();
this.performedFrom = performedFrom; this.actorName = actor.getName();
this.actionType = actionType; this.actionType = actionType;
this.description = description;
this.actionData = actionData; this.actionData = actionData;
} }

View File

@ -7,7 +7,10 @@ import org.bson.types.ObjectId;
import org.mongodb.morphia.annotations.Entity; import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id; import org.mongodb.morphia.annotations.Id;
import java.util.*; import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@Entity(value = "grants", noClassnameStored = true) @Entity(value = "grants", noClassnameStored = true)
public final class Grant { public final class Grant {
@ -66,4 +69,12 @@ public final class Grant {
return removedBy != null; return removedBy != null;
} }
public boolean appliesOn(Server server) {
return scopes.contains(server.getId());
}
public boolean appliesOn(ServerGroup serverGroup) {
return scopes.contains(serverGroup.getId());
}
} }

View File

@ -7,7 +7,6 @@ import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id; import org.mongodb.morphia.annotations.Id;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.UUID; import java.util.UUID;
@Entity(value = "ipLog", noClassnameStored = true) @Entity(value = "ipLog", noClassnameStored = true)

View File

@ -5,10 +5,7 @@ import net.frozenorb.apiv3.APIv3;
import org.mongodb.morphia.annotations.Entity; import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id; import org.mongodb.morphia.annotations.Id;
import java.util.Date;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID;
@Entity(value = "notificationTemplates", noClassnameStored = true) @Entity(value = "notificationTemplates", noClassnameStored = true)
public final class NotificationTemplate { public final class NotificationTemplate {
@ -16,8 +13,6 @@ public final class NotificationTemplate {
@Getter @Id private String id; @Getter @Id private String id;
@Getter private String subject; @Getter private String subject;
@Getter private String body; @Getter private String body;
@Getter private Date lastUpdatedAt;
@Getter private UUID lastUpdatedBy;
public static NotificationTemplate byId(String id) { public static NotificationTemplate byId(String id) {
return APIv3.getDatastore().createQuery(NotificationTemplate.class).field("id").equalIgnoreCase(id).get(); return APIv3.getDatastore().createQuery(NotificationTemplate.class).field("id").equalIgnoreCase(id).get();
@ -25,18 +20,14 @@ public final class NotificationTemplate {
public NotificationTemplate() {} // For Morphia public NotificationTemplate() {} // For Morphia
public NotificationTemplate(String subject, String body, User creator) { public NotificationTemplate(String subject, String body) {
this.subject = subject; this.subject = subject;
this.body = body; this.body = body;
this.lastUpdatedAt = new Date();
this.lastUpdatedBy = creator.getId();
} }
public void update(String subject, String body, User updatedBy) { public void update(String subject, String body) {
this.subject = subject; this.subject = subject;
this.body = body; this.body = body;
this.lastUpdatedAt = new Date();
this.lastUpdatedBy = updatedBy.getId();
APIv3.getDatastore().save(this); APIv3.getDatastore().save(this);
} }

View File

@ -7,7 +7,6 @@ import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id; import org.mongodb.morphia.annotations.Id;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.UUID; import java.util.UUID;
@Entity(value = "punishments", noClassnameStored = true) @Entity(value = "punishments", noClassnameStored = true)

View File

@ -18,7 +18,7 @@ public final class Rank {
@Getter private boolean staffRank; @Getter private boolean staffRank;
public static Rank byId(String id) { public static Rank byId(String id) {
return APIv3.getDatastore().createQuery(Rank.class).field("id").equalIgnoreCase(id).get(); return APIv3.getDatastore().createQuery(Rank.class).order("weight").field("id").equalIgnoreCase(id).get();
} }
public static List<Rank> values() { public static List<Rank> values() {

View File

@ -3,7 +3,7 @@ package net.frozenorb.apiv3.models;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.weirdStuff.ExcludeFromReplies; import net.frozenorb.apiv3.serialization.ExcludeFromReplies;
import org.bson.Document; import org.bson.Document;
import org.mindrot.jbcrypt.BCrypt; import org.mindrot.jbcrypt.BCrypt;
import org.mongodb.morphia.annotations.Entity; import org.mongodb.morphia.annotations.Entity;
@ -130,4 +130,28 @@ public final class User {
return BCrypt.checkpw(new String(unencrypted), password); return BCrypt.checkpw(new String(unencrypted), password);
} }
public Map<String, Boolean> calculateGlobalPermissions() {
return null;
}
public Map<String, Boolean> calculatePermissions(ServerGroup serverGroup) {
/*ServerGroup scope = ServerGroup.byId("HCTeams");
Map<ServerGroup, Rank> userRanks = new HashMap<>();
//ServerGroup global = ServerGroup.byId("Global");
Map<String, Boolean> calculatedPermissions = global.getPermissions(userRanks.get(global));
// for global calculations
for (ServerGroup serverGroup : ServerGroup.values()) {
mergePermissions(serverGroup, userRanks.get(serverGroup), calculatedPermissions);
}
// for scoped calculations
mergePermissions(scope, userRanks.get(scope), calculatedPermissions);*/
return null;
}
} }

View File

@ -8,7 +8,6 @@ import org.bson.types.ObjectId;
import org.mongodb.morphia.annotations.Entity; import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id; import org.mongodb.morphia.annotations.Id;
import java.util.List;
import java.util.UUID; import java.util.UUID;
@Entity(value = "userMeta", noClassnameStored = true) @Entity(value = "userMeta", noClassnameStored = true)

View File

@ -3,7 +3,7 @@ package net.frozenorb.apiv3.routes;
import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.models.Grant; import net.frozenorb.apiv3.models.Grant;
import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.models.Punishment;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils; import net.frozenorb.apiv3.utils.ErrorUtils;
import spark.Request; import spark.Request;
import spark.Response; import spark.Response;
import spark.Route; import spark.Route;

View File

@ -3,7 +3,7 @@ package net.frozenorb.apiv3.routes;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils; import net.frozenorb.apiv3.utils.ErrorUtils;
import org.bson.Document; import org.bson.Document;
import spark.Request; import spark.Request;
import spark.Response; import spark.Response;

View File

@ -2,9 +2,9 @@ package net.frozenorb.apiv3.routes.grants;
import net.frozenorb.apiv3.models.Grant; import net.frozenorb.apiv3.models.Grant;
import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.AuditLog; import net.frozenorb.apiv3.unsorted.AuditLog;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils; import net.frozenorb.apiv3.unsorted.Permissions;
import net.frozenorb.apiv3.weirdStuff.Permissions; import net.frozenorb.apiv3.utils.ErrorUtils;
import org.bson.Document; import org.bson.Document;
import spark.Request; import spark.Request;
import spark.Response; import spark.Response;
@ -30,11 +30,10 @@ public final class DELETEGrant implements Route {
return ErrorUtils.unauthorized(requiredPermission); return ErrorUtils.unauthorized(requiredPermission);
} }
String removedByIp = req.queryParams("removedByIp");
String reason = req.queryParams("removalReason"); String reason = req.queryParams("removalReason");
grant.delete(removedBy, reason); grant.delete(removedBy, reason);
AuditLog.log(removedBy, removedByIp, "grant.remove", "Removed a " + grant.getRank() + " grant from " + grant.getTarget() + " for \" " + reason + "\"", new Document("grantId", grant.getId())); AuditLog.log(removedBy, req.attribute("actor"), "grant.remove", new Document("grantId", grant.getId()));
return grant; return grant;
} }

View File

@ -1,7 +1,7 @@
package net.frozenorb.apiv3.routes.grants; package net.frozenorb.apiv3.routes.grants;
import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils; import net.frozenorb.apiv3.utils.ErrorUtils;
import spark.Request; import spark.Request;
import spark.Response; import spark.Response;
import spark.Route; import spark.Route;

View File

@ -5,8 +5,8 @@ import net.frozenorb.apiv3.models.Grant;
import net.frozenorb.apiv3.models.Rank; import net.frozenorb.apiv3.models.Rank;
import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.models.ServerGroup;
import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils; import net.frozenorb.apiv3.unsorted.Permissions;
import net.frozenorb.apiv3.weirdStuff.Permissions; import net.frozenorb.apiv3.utils.ErrorUtils;
import spark.Request; import spark.Request;
import spark.Response; import spark.Response;
import spark.Route; import spark.Route;

View File

@ -1,7 +1,7 @@
package net.frozenorb.apiv3.routes.ipLog; package net.frozenorb.apiv3.routes.ipLog;
import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils; import net.frozenorb.apiv3.utils.ErrorUtils;
import spark.Request; import spark.Request;
import spark.Response; import spark.Response;
import spark.Route; import spark.Route;

View File

@ -2,9 +2,9 @@ package net.frozenorb.apiv3.routes.punishments;
import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.models.Punishment;
import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.AuditLog; import net.frozenorb.apiv3.unsorted.AuditLog;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils; import net.frozenorb.apiv3.unsorted.Permissions;
import net.frozenorb.apiv3.weirdStuff.Permissions; import net.frozenorb.apiv3.utils.ErrorUtils;
import org.bson.Document; import org.bson.Document;
import spark.Request; import spark.Request;
import spark.Response; import spark.Response;
@ -30,11 +30,10 @@ public final class DELETEPunishment implements Route {
return ErrorUtils.unauthorized(requiredPermission); return ErrorUtils.unauthorized(requiredPermission);
} }
String removedByIp = req.queryParams("removedByIp");
String reason = req.queryParams("removalReason"); String reason = req.queryParams("removalReason");
punishment.delete(removedBy, reason); punishment.delete(removedBy, reason);
AuditLog.log(removedBy, removedByIp, "punishment.remove", "Removed a " + punishment.getType().name().toLowerCase() + " from " + punishment.getTarget() + " for \" " + reason + "\"", new Document("punishmentId", punishment.getId())); AuditLog.log(removedBy, req.attribute("actor"), "punishment.remove", new Document("punishmentId", punishment.getId()));
return punishment; return punishment;
} }

View File

@ -4,8 +4,8 @@ import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.models.Punishment;
import net.frozenorb.apiv3.models.Server; import net.frozenorb.apiv3.models.Server;
import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils; import net.frozenorb.apiv3.unsorted.Permissions;
import net.frozenorb.apiv3.weirdStuff.Permissions; import net.frozenorb.apiv3.utils.ErrorUtils;
import spark.Request; import spark.Request;
import spark.Response; import spark.Response;
import spark.Route; import spark.Route;

View File

@ -3,7 +3,7 @@ package net.frozenorb.apiv3.routes.users;
import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.models.ServerGroup;
import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.models.UserMetaEntry; import net.frozenorb.apiv3.models.UserMetaEntry;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils; import net.frozenorb.apiv3.utils.ErrorUtils;
import spark.Request; import spark.Request;
import spark.Response; import spark.Response;
import spark.Route; import spark.Route;

View File

@ -2,7 +2,7 @@ package net.frozenorb.apiv3.routes.users;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils; import net.frozenorb.apiv3.utils.ErrorUtils;
import spark.Request; import spark.Request;
import spark.Response; import spark.Response;
import spark.Route; import spark.Route;

View File

@ -3,7 +3,7 @@ package net.frozenorb.apiv3.routes.users;
import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.models.ServerGroup;
import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.models.UserMetaEntry; import net.frozenorb.apiv3.models.UserMetaEntry;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils; import net.frozenorb.apiv3.utils.ErrorUtils;
import spark.Request; import spark.Request;
import spark.Response; import spark.Response;
import spark.Route; import spark.Route;

View File

@ -1,14 +0,0 @@
package net.frozenorb.apiv3.routes.users;
import net.frozenorb.apiv3.models.User;
import spark.Request;
import spark.Response;
import spark.Route;
public final class GETUsers implements Route {
public Object handle(Request req, Response res) {
return User.values();
}
}

View File

@ -0,0 +1,27 @@
package net.frozenorb.apiv3.routes.users;
import com.google.common.collect.ImmutableMap;
import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.utils.ErrorUtils;
import spark.Request;
import spark.Response;
import spark.Route;
public final class POSTUserLogin implements Route {
public Object handle(Request req, Response res) {
User user = User.byIdOrName(req.params("id"));
if (user == null) {
return ErrorUtils.notFound("User", req.params("id"));
}
return ImmutableMap.of(
"user", user,
"access", user.getGrants(),
"rank", user.getIPLog(),
"permissions", user.getPunishments()
);
}
}

View File

@ -2,8 +2,8 @@ package net.frozenorb.apiv3.routes.users;
import net.frozenorb.apiv3.models.NotificationTemplate; import net.frozenorb.apiv3.models.NotificationTemplate;
import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils; import net.frozenorb.apiv3.unsorted.Notification;
import net.frozenorb.apiv3.weirdStuff.Notification; import net.frozenorb.apiv3.utils.ErrorUtils;
import org.bson.Document; import org.bson.Document;
import spark.Request; import spark.Request;
import spark.Response; import spark.Response;

View File

@ -4,8 +4,8 @@ import com.google.common.collect.ImmutableMap;
import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.models.NotificationTemplate; import net.frozenorb.apiv3.models.NotificationTemplate;
import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils; import net.frozenorb.apiv3.unsorted.Notification;
import net.frozenorb.apiv3.weirdStuff.Notification; import net.frozenorb.apiv3.utils.ErrorUtils;
import org.bson.Document; import org.bson.Document;
import spark.Request; import spark.Request;
import spark.Response; import spark.Response;

View File

@ -2,7 +2,7 @@ package net.frozenorb.apiv3.routes.users;
import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.models.ServerGroup;
import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils; import net.frozenorb.apiv3.utils.ErrorUtils;
import org.bson.Document; import org.bson.Document;
import spark.Request; import spark.Request;
import spark.Response; import spark.Response;

View File

@ -1,4 +1,4 @@
package net.frozenorb.apiv3.weirdStuff; package net.frozenorb.apiv3.serialization;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@ -1,4 +1,4 @@
package net.frozenorb.apiv3.weirdStuff; package net.frozenorb.apiv3.serialization;
import com.google.gson.ExclusionStrategy; import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes; import com.google.gson.FieldAttributes;

View File

@ -1,4 +1,4 @@
package net.frozenorb.apiv3.weirdStuff; package net.frozenorb.apiv3.serialization;
import com.google.gson.TypeAdapter; import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;

View File

@ -1,4 +1,4 @@
package net.frozenorb.apiv3.weirdStuff; package net.frozenorb.apiv3.unsorted;
public interface Actor { public interface Actor {
@ -8,7 +8,7 @@ public interface Actor {
enum Type { enum Type {
WEBSITE, SERVER, UNKNOWN WEBSITE, SERVER, USER, UNKNOWN
} }

View File

@ -0,0 +1,22 @@
package net.frozenorb.apiv3.unsorted;
import lombok.experimental.UtilityClass;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.models.AuditLogEntry;
import net.frozenorb.apiv3.models.User;
import org.bson.Document;
@UtilityClass
public class AuditLog {
// TODO: Store user IPs
public static void log(User performedBy, Actor actor, String actionType) {
log(performedBy, actor, actionType, new Document());
}
public static void log(User performedBy, Actor actor, String actionType, Document actionData) {
APIv3.getDatastore().save(new AuditLogEntry(performedBy, actor, actionType, actionData));
}
}

View File

@ -1,4 +1,4 @@
package net.frozenorb.apiv3.weirdStuff; package net.frozenorb.apiv3.unsorted;
import com.cribbstechnologies.clients.mandrill.exception.RequestFailedException; import com.cribbstechnologies.clients.mandrill.exception.RequestFailedException;
import com.cribbstechnologies.clients.mandrill.model.MandrillHtmlMessage; import com.cribbstechnologies.clients.mandrill.model.MandrillHtmlMessage;
@ -6,6 +6,7 @@ import com.cribbstechnologies.clients.mandrill.model.MandrillMessageRequest;
import com.cribbstechnologies.clients.mandrill.model.MandrillRecipient; import com.cribbstechnologies.clients.mandrill.model.MandrillRecipient;
import com.cribbstechnologies.clients.mandrill.request.MandrillMessagesRequest; import com.cribbstechnologies.clients.mandrill.request.MandrillMessagesRequest;
import net.frozenorb.apiv3.models.NotificationTemplate; import net.frozenorb.apiv3.models.NotificationTemplate;
import net.frozenorb.apiv3.utils.MandrillUtils;
import sun.reflect.generics.reflectiveObjects.NotImplementedException; import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import java.io.IOException; import java.io.IOException;
@ -20,7 +21,7 @@ public final class Notification {
public Notification(NotificationTemplate template, Map<String, Object> subjectReplacements, Map<String, Object> bodyReplacements) { public Notification(NotificationTemplate template, Map<String, Object> subjectReplacements, Map<String, Object> bodyReplacements) {
this.subject = template.fillSubject(subjectReplacements); this.subject = template.fillSubject(subjectReplacements);
this.body = template.fillSubject(bodyReplacements); this.body = template.fillBody(bodyReplacements);
} }
public void sendAsEmail(String email) throws IOException { public void sendAsEmail(String email) throws IOException {

View File

@ -1,4 +1,4 @@
package net.frozenorb.apiv3.weirdStuff; package net.frozenorb.apiv3.unsorted;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;

View File

@ -1,4 +1,4 @@
package net.frozenorb.apiv3.weirdStuff; package net.frozenorb.apiv3.utils;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import org.bson.Document; import org.bson.Document;

View File

@ -1,29 +1,20 @@
package net.frozenorb.apiv3.weirdStuff; package net.frozenorb.apiv3.utils;
import com.cribbstechnologies.clients.mandrill.request.MandrillMessagesRequest; import com.cribbstechnologies.clients.mandrill.request.MandrillMessagesRequest;
import com.cribbstechnologies.clients.mandrill.request.MandrillRESTRequest; import com.cribbstechnologies.clients.mandrill.request.MandrillRESTRequest;
import com.cribbstechnologies.clients.mandrill.util.MandrillConfiguration; import com.cribbstechnologies.clients.mandrill.util.MandrillConfiguration;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import net.frozenorb.apiv3.APIv3;
import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClientBuilder;
import java.util.Properties;
@UtilityClass @UtilityClass
public class MandrillUtils { public class MandrillUtils {
public static MandrillMessagesRequest createMessagesRequest() { public static MandrillMessagesRequest createMessagesRequest() {
Properties props = new Properties();
try {
props.load(MandrillUtils.class.getClassLoader().getResourceAsStream("mandrill.properties"));
} catch (Exception ex) {
throw new RuntimeException(ex);
}
MandrillConfiguration config = new MandrillConfiguration(); MandrillConfiguration config = new MandrillConfiguration();
config.setApiKey(props.getProperty("apiKey")); config.setApiKey(APIv3.getConfig().getProperty("mandrill.apiKey"));
config.setApiVersion("1.0"); config.setApiVersion("1.0");
config.setBaseURL("https://mandrillapp.com/api"); config.setBaseURL("https://mandrillapp.com/api");

View File

@ -0,0 +1,22 @@
package net.frozenorb.apiv3.utils;
import lombok.experimental.UtilityClass;
import net.frozenorb.apiv3.models.Rank;
import net.frozenorb.apiv3.models.ServerGroup;
import java.util.Map;
@UtilityClass
public class PermissionUtils {
public static void mergePermissions(ServerGroup serverGroup, Rank rank, Map<String, Boolean> current) {
Map<String, Boolean> groupPermissions = serverGroup.getPermissions(rank);
groupPermissions.forEach((permissionNode, grant) -> {
if (!current.containsKey(permissionNode) || !current.get(permissionNode)) {
current.put(permissionNode, grant);
}
});
}
}

View File

@ -1,20 +0,0 @@
package net.frozenorb.apiv3.weirdStuff;
import lombok.experimental.UtilityClass;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.models.AuditLogEntry;
import net.frozenorb.apiv3.models.User;
import org.bson.Document;
@UtilityClass
public class AuditLog {
public static void log(User performedBy, String performedFrom, String actionType, String description) {
log(performedBy, performedFrom, actionType, description, new Document());
}
public static void log(User performedBy, String performedFrom, String actionType, String description, Document actionData) {
APIv3.getDatastore().save(new AuditLogEntry(performedBy, performedFrom, actionType, description, actionData));
}
}

View File

@ -5,3 +5,4 @@ mongo.username=test
mongo.password=test mongo.password=test
http.address= http.address=
http.port=80 http.port=80
mandrill.apiKey=0OYtwymqJP6oqvszeJu0vQ

View File

@ -1 +0,0 @@
apiKey=0OYtwymqJP6oqvszeJu0vQ