Compare commits

..

8 Commits

5 changed files with 104 additions and 69 deletions

View File

@@ -13,6 +13,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
public class JodelPost {
// id of the post
public Long id;
// Parent id
public Optional<Long> parent = Optional.empty();
// id of the author in db
private final Long authorID;
// anonymized authorID
@@ -25,31 +27,24 @@ public class JodelPost {
public Timestamp date;
// location if the post
public Location location;
// list of all comments for the post
public Vector<JodelPost> comments = new Vector<>();
// the own reaction (null = none, true = positive, false = negative)
public Optional<Boolean> reaction;
// all other reactions
public Reactions reactions;
// Parent id
public Optional<Long> parent = Optional.empty();
// list of all comments for the post
public Vector<JodelPost> comments = new Vector<>();
// anonymize function to recursively anonymize the posts
public void anonymize(Optional<Vector<Long>> idCache) {
// check if this is the first post in this process
if (idCache.isEmpty()) {
// create a new Vector as cache
idCache = Optional.of(new Vector<>());
}
public void anonymize(Vector<Long> idCache) {
// get the anonymized id as index in cached authorIDs
int i = idCache.get().indexOf(this.authorID);
int i = idCache.indexOf(this.authorID);
// if the index is -1 the authorID has not been cached jet
if (i == -1) {
// set the current anonymousID as length of the cache (== next index)
this.anonymousID = (long) idCache.get().size();
this.anonymousID = (long) idCache.size();
// push the current authorID to to cache
idCache.get().add(this.authorID);
idCache.add(this.authorID);
}
// the authorID has been anonymized once before, so we can get it from cache
else this.anonymousID = (long) i;
@@ -88,7 +83,7 @@ public class JodelPost {
this.content = rs.getString("content");
this.date = rs.getTimestamp("postdate");
this.location = new Location(rs.getFloat("longitude"), rs.getFloat("latitude"));
this.reaction = Optional.of(rs.getBoolean("reaction"));
this.reaction = rs.getString("reaction") == null ? Optional.empty() : Optional.of(rs.getBoolean("reaction"));
this.reactions = new Reactions(rs.getLong("positive"), rs.getLong("negative"));
this.parent = Optional.of(rs.getLong("parent"));
}
@@ -104,7 +99,7 @@ public class JodelPost {
@JsonProperty("date") Timestamp date,
@JsonProperty("location") Location location,
@JsonProperty("parent") Optional<Long> parent) {
this.authorID = User.getUserID(); // TODO: getter from Keycloak
this.authorID = User.getID(); // TODO: getter from Keycloak
this.title = title;
this.content = content;
this.date = date;

View File

@@ -4,8 +4,8 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Location {
public float longitude;
public float latitude;
public float longitude;
@JsonCreator
public Location(@JsonProperty("longitude") float longitude, @JsonProperty("latitude") float latitude ) {

View File

@@ -13,11 +13,14 @@ import java.util.Vector;
@CrossOrigin(origins = "*", allowedHeaders = "*", maxAge = 3600)
public class Routes {
@GetMapping("/posts/{longitude}/{latitude}")
@GetMapping("/posts/{latitude}/{longitude}")
public Vector<JodelPost> getPostsByLocation(@PathVariable("longitude") float longitude, @PathVariable("latitude") float latitude) {
// list of all posts (not comments) in range
Vector<JodelPost> posts = new Vector<>();
// get UserID
Long userID = User.getID();
// DB connection and statement
Connection c;
PreparedStatement stmt;
@@ -44,8 +47,8 @@ public class Routes {
posts.title,
posts.content,
posts.postdate,
posts.postlocation[0] AS longitude,
posts.postlocation[1] AS latitude,
posts.postlocation[0] AS latitude,
posts.postlocation[1] AS longitude,
(SELECT count(*) FROM reactions WHERE reactions.post = posts.id AND reactions.positive = TRUE) AS positive,
(SELECT count(*) FROM reactions WHERE reactions.post = posts.id AND reactions.positive = FALSE) AS negative
FROM
@@ -75,9 +78,9 @@ public class Routes {
)
SELECT * FROM targets LEFT JOIN (SELECT post, positive as reaction FROM reactions WHERE userid = (?)) ON post = id;""");
stmt.setObject(1, longitude);
stmt.setObject(2, latitude);
stmt.setObject(3, User.getUserID());
stmt.setObject(1, latitude);
stmt.setObject(2, longitude);
stmt.setObject(3, userID);
// query recursively for posts inside a 10km radius
ResultSet rs = stmt.executeQuery();
@@ -116,7 +119,12 @@ public class Routes {
}
// calculate anonymous IDs for the posts
posts.forEach(post -> post.anonymize(Optional.empty()));
Vector<Long> anonymousIDs = new Vector<Long>();
anonymousIDs.add(userID);
posts.forEach(post -> {
post.anonymize(anonymousIDs);
});
// return the posts
return posts;
}
@@ -126,6 +134,9 @@ public class Routes {
// list of all posts (not comments) in range
Optional<JodelPost> root_post = Optional.empty();
// get UserID
Long userID = User.getID();
// DB connection and statement
Connection c;
PreparedStatement stmt;
@@ -152,8 +163,8 @@ public class Routes {
posts.title,
posts.content,
posts.postdate,
posts.postlocation[0] AS longitude,
posts.postlocation[1] AS latitude,
posts.postlocation[0] AS latitude,
posts.postlocation[1] AS longitude,
(SELECT count(*) FROM reactions WHERE reactions.post = posts.id AND reactions.positive = TRUE) AS positive,
(SELECT count(*) FROM reactions WHERE reactions.post = posts.id AND reactions.positive = FALSE) AS negative
FROM
@@ -181,7 +192,7 @@ public class Routes {
SELECT * FROM targets LEFT JOIN (SELECT post, positive as reaction FROM reactions WHERE userid = (?)) ON post = id;""");
stmt.setObject(1, id);
stmt.setObject(2, User.getUserID());
stmt.setObject(2, userID);
// query recursively for posts inside a 10km radius
ResultSet rs = stmt.executeQuery();
@@ -220,7 +231,9 @@ public class Routes {
}
// calculate anonymous IDs for the post
root_post.ifPresent(root -> root.anonymize(Optional.empty()));
Vector<Long> anonymousIDs = new Vector<Long>();
anonymousIDs.add(userID);
root_post.ifPresent(root -> root.anonymize(anonymousIDs));
// return the posts
if (root_post.isEmpty()) throw new ResponseStatusException(HttpStatus.NOT_FOUND, "No post found");
@@ -253,8 +266,8 @@ public class Routes {
stmt.setObject(2, post.title);
stmt.setObject(3, post.content);
stmt.setObject(4, post.date);
stmt.setObject(5, post.location.longitude);
stmt.setObject(6, post.location.latitude);
stmt.setObject(5, post.location.latitude);
stmt.setObject(6, post.location.longitude);
// insert post and get its id
ResultSet rs = stmt.executeQuery();
@@ -296,11 +309,73 @@ public class Routes {
post.reaction = Optional.empty();
// anonymize code
post.anonymize(Optional.empty());
Vector<Long> anonymousIDs = new Vector<Long>();
anonymousIDs.add(0L);
post.anonymize(anonymousIDs);
return post;
}
@PatchMapping("/post/{id}")
public void reactToPost(@PathVariable long id, @RequestBody JodelPost post) {
System.out.println(post.reaction);
long userID = User.getID();
// DB connection and statement
Connection c;
PreparedStatement stmt;
// try to get data from db
try {
// check for the driver
Class.forName("org.postgresql.Driver");
// get the connection with credentials from env variables
c = DriverManager
.getConnection("jdbc:postgresql://"+
System.getenv("POSTGRES_IP")+"/"+System.getenv("POSTGRES_DB"),
System.getenv("POSTGRES_USER"), System.getenv("POSTGRES_PASSWORD"));
// disable auto commits
c.setAutoCommit(false);
// create a new statement
stmt = c.prepareStatement("UPDATE Reactions SET positive = (?) WHERE post = (?) AND userid = (?) RETURNING id, positive");
stmt.setObject(1, post.reaction.orElse(null));
stmt.setObject(2, id);
stmt.setObject(3, userID);
// insert post and get its id
ResultSet rs = stmt.executeQuery();
// check if there is a parent
if (!rs.next()) {
// create a new statement
stmt = c.prepareStatement("INSERT INTO Reactions(userid, post, positive) VALUES ((?), (?), (?))");
// fill statement
stmt.setObject(1, userID);
stmt.setObject(2, id);
stmt.setObject(3, post.reaction.orElse(null));
// execute statement
stmt.execute();
}
// commit the changes
c.commit();
// close all connections to db
stmt.close();
c.close();
}
// else log the error
catch ( Exception e ) {
System.err.println( e.getClass().getName()+": "+ e.getMessage() );
throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, "Database is offline");
}
}
@DeleteMapping("/post/{id}")
public void deletePost(@PathVariable long id) {
// DB connection and statement
@@ -323,7 +398,7 @@ public class Routes {
stmt = c.prepareStatement("UPDATE Posts SET deleted = now() WHERE id = ? AND author = (?) AND deleted IS NULL");
stmt.setObject(1, id);
stmt.setObject(2, User.getUserID());
stmt.setObject(2, User.getID());
// insert delete time
stmt.execute();

View File

@@ -14,9 +14,9 @@ public class User {
return SecurityContextHolder.getContext().getAuthentication().getName();
}
static public Long getUserID () {
static public Long getID() {
String uuid = SecurityContextHolder.getContext().getAuthentication().getName();
Long id = -1L;
long id;
// DB connection and statement
Connection c;

View File

@@ -3,44 +3,9 @@ package de.anxietyprime.swajodel;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Optional;
import java.util.Vector;
@SpringBootTest
class SwaJodelApplicationTests {
@Test
void anonymousTest() {
JodelPost post = new JodelPost(1000);
post.comments.add(new JodelPost(1001));
post.comments.add(new JodelPost(1002));
post.comments.get(0).comments.add(new JodelPost(1000));
post.comments.get(0).comments.add(new JodelPost(1001));
post.comments.get(0).comments.add(new JodelPost(1000));
post.comments.add(new JodelPost(1003));
post.comments.get(2).comments.add(new JodelPost(1001));
post.comments.get(2).comments.add(new JodelPost(1002));
post.comments.get(2).comments.add(new JodelPost(1003));
post.comments.get(2).comments.add(new JodelPost(1000));
post.comments.add(new JodelPost(1000));
post.comments.add(new JodelPost(1001));
post.comments.add(new JodelPost(1001));
post.anonymize(Optional.empty());
assert (post.anonymousID == 0);
assert (post.comments.get(0).anonymousID == 1);
assert (post.comments.get(1).anonymousID == 2);
assert (post.comments.get(2).anonymousID == 3);
assert (post.comments.get(3).anonymousID == 0);
assert (post.comments.get(4).anonymousID == 1);
assert (post.comments.get(5).anonymousID == 1);
assert (post.comments.get(0).comments.get(0).anonymousID == 0);
assert (post.comments.get(0).comments.get(1).anonymousID == 1);
assert (post.comments.get(0).comments.get(2).anonymousID == 0);
assert (post.comments.get(2).comments.get(0).anonymousID == 1);
assert (post.comments.get(2).comments.get(1).anonymousID == 2);
assert (post.comments.get(2).comments.get(2).anonymousID == 3);
assert (post.comments.get(2).comments.get(3).anonymousID == 0);
}
}