feat: shit just work, time to eat

This commit is contained in:
Laureηt 2022-05-21 18:45:51 +02:00
parent d1b048ffea
commit 1d16a2ad31
No known key found for this signature in database
GPG key ID: D88C6B294FD40994
7 changed files with 237 additions and 41 deletions

19
.vscode/settings.json vendored
View file

@ -1,3 +1,18 @@
{
"java.configuration.updateBuildConfiguration": "automatic"
}
"java.configuration.updateBuildConfiguration": "automatic",
"sqltools.connections": [
{
"mysqlOptions": {
"authProtocol": "default"
},
"previewLimit": 50,
"server": "localhost",
"port": 3306,
"driver": "MariaDB",
"name": "pixel",
"database": "pixel",
"username": "mysql",
"password": "mysql"
}
]
}

View file

@ -0,0 +1,18 @@
package com.pixels;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name = "Frontend", urlPatterns = { "" }, loadOnStartup = 1)
public class Frontend extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getSession();
request.getRequestDispatcher("index.html").forward(request, response);
}
}

View file

@ -0,0 +1,30 @@
package com.pixels.adapters;
import java.lang.reflect.Type;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.pixels.beans.Pixel;
import com.pixels.beans.User;
public class PixelAdapter implements JsonSerializer<Pixel> {
@Override
public JsonElement serialize(Pixel src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject json = new JsonObject();
json.addProperty("id", src.getId());
json.addProperty("price", src.getPrice());
json.addProperty("color", src.getColor());
json.addProperty("description", src.getDescription());
User owner = src.getOwner();
if (owner != null) {
json.addProperty("owner_username", owner.getUsername());
}
return json;
}
}

View file

@ -0,0 +1,37 @@
package com.pixels.adapters;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.pixels.beans.Pixel;
import com.pixels.beans.User;
public class UserAdapter implements JsonSerializer<User> {
Gson gson = new GsonBuilder().create();
@Override
public JsonElement serialize(User src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject json = new JsonObject();
json.addProperty("user", src.getUsername());
json.addProperty("email", src.getEmail());
json.addProperty("balance", src.getBalance());
List<Long> list = new ArrayList<>();
for (Pixel pixel : src.getPixels()) {
list.add(pixel.getId());
}
json.add("pixels", gson.toJsonTree(list));
return json;
}
}

View file

@ -28,32 +28,42 @@ public class User implements Serializable {
// addresse mail de l'utilisateur
@NonNull
@NotBlank
@Column(unique = true)
private String email;
// mot de passe hashé en sha256
@NonNull
@NotBlank
private String hashPassword;
private transient String password;
// portefeuille
@OneToMany
@OneToMany(mappedBy = "owner")
private List<Pixel> pixels;
// le solde de l'utilisateur
@NotNull
private Integer balance = 0;
// pixels possédés
@OneToMany(mappedBy = "owner")
private List<Pixel> owned;
private transient String sessionID;
public User(String username, String email, String password) {
this.username = username;
this.email = email;
this.hashPassword = Hash.sha256(password);
this.password = Hash.sha256(password);
}
public void setHashPassword(String password) {
this.hashPassword = Hash.sha256(password);
public void setPassword(String password) {
this.password = Hash.sha256(password);
}
public boolean validPassword(String password) {
return this.password.equals(Hash.sha256(password));
}
public static User fromSessionID(String sessionID, EntityManager em) {
return em.createQuery("SELECT u FROM User u WHERE sessionID = :session_id", User.class)
.setParameter("session_id", sessionID)
.getSingleResult();
}
}

View file

@ -1,20 +1,30 @@
package com.pixels.services;
import java.util.Date;
import javax.ejb.Singleton;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.ws.rs.Consumes;
import javax.ws.rs.CookieParam;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.MediaType;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.pixels.adapters.PixelAdapter;
import com.pixels.adapters.UserAdapter;
import com.pixels.beans.Pixel;
import com.pixels.beans.Transaction;
import com.pixels.beans.User;
@Singleton
@Path("/pixel")
@ -23,7 +33,10 @@ public class PixelService {
@PersistenceContext
private EntityManager em;
Gson gson = new Gson();
Gson gson = new GsonBuilder()
.registerTypeAdapter(Pixel.class, new PixelAdapter())
.registerTypeAdapter(User.class, new UserAdapter())
.create();
@GET
@Produces(MediaType.APPLICATION_JSON)
@ -54,4 +67,42 @@ public class PixelService {
em.merge(pixel);
return gson.toJson(pixel);
}
@POST
@Path("{id}/buy/")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public String buy_pixel(@PathParam("id") Long id, @CookieParam("JSESSIONID") Cookie cookie, String json) {
// on récupère les informations du changement
Pixel pixel_json = gson.fromJson(json, Pixel.class);
// on récupère le pixel de la db via son id
Pixel pixel = em.find(Pixel.class, id);
// on récupère le nouveau proprio
User user = User.fromSessionID(cookie.getValue(), em);
if (user.getBalance() >= pixel.getPrice() && pixel_json.getPrice() > pixel.getPrice()) {
// on update le pixel
pixel.setOwner(user);
pixel.setColor(pixel_json.getColor());
pixel.setDescription(pixel_json.getDescription());
pixel.setPrice(pixel_json.getPrice());
// on débite le user
user.setBalance(user.getBalance() - pixel_json.getPrice());
// on ajoute la transaction
Date now = new Date(System.currentTimeMillis());
Transaction new_transaction = new Transaction(now, pixel);
em.persist(new_transaction);
// on update le pixel dans la db
em.merge(pixel);
em.merge(user);
}
return gson.toJson(pixel);
}
}

View file

@ -1,22 +1,28 @@
package com.pixels.services;
import java.util.Date;
import java.util.logging.Logger;
import javax.ejb.Singleton;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.NoResultException;
import javax.ws.rs.Consumes;
import javax.ws.rs.CookieParam;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.MediaType;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.pixels.adapters.PixelAdapter;
import com.pixels.adapters.UserAdapter;
import com.pixels.beans.Pixel;
import com.pixels.beans.Transaction;
import com.pixels.beans.User;
@Singleton
@ -26,7 +32,12 @@ public class UserService {
@PersistenceContext
private EntityManager em;
Gson gson = new Gson();
private final Logger LOGGER = Logger.getLogger("UserService");
Gson gson = new GsonBuilder()
.registerTypeAdapter(Pixel.class, new PixelAdapter())
.registerTypeAdapter(User.class, new UserAdapter())
.create();
@GET
@Produces(MediaType.APPLICATION_JSON)
@ -36,45 +47,69 @@ public class UserService {
}
@GET
@Path("{id}")
@Path("{username}")
@Produces(MediaType.APPLICATION_JSON)
public String single(@PathParam("id") Long id) {
User user = em.find(User.class, id);
public String single(@PathParam("username") String username) {
User user = em.find(User.class, username);
if (user == null) {
throw new NotFoundException();
} else {
LOGGER.info(gson.toJson(user.getPixels()));
return gson.toJson(user);
}
}
@GET
@Path("{id_user}/buy/{id_pixel}")
@POST
@Path("signup")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public String buy_pixel(@PathParam("id") Long id_pixel, @PathParam("id") Long id_user, String json) {
// on récupère les informations du changement
Pixel pixel_new_infos = gson.fromJson(json, Pixel.class);
public void signup(@CookieParam("JSESSIONID") Cookie cookie, String json) {
User json_user = gson.fromJson(json, User.class);
User new_user = new User(
json_user.getUsername(),
json_user.getEmail(),
json_user.getPassword());
new_user.setSessionID(cookie.getValue());
em.persist(new_user);
LOGGER.info("new user: " + new_user.getUsername());
}
// on récupère le pixel de la db via son id
Pixel pixel = em.find(Pixel.class, id_pixel);
@POST
@Path("login")
@Consumes(MediaType.APPLICATION_JSON)
public void login(@CookieParam("JSESSIONID") Cookie cookie, String json) {
User user;
try {
// si on trouve l'utilsateur via son sessionID
user = User.fromSessionID(cookie.getValue(), em);
LOGGER.info(user.getUsername() + " already logged in");
// TODO: renvoyer un json avec les creds
} catch (NoResultException e) {
// on parse le json en objet User
User json_user = gson.fromJson(json, User.class);
// on récupère le nouveau proprio
User user = em.find(User.class, id_user);
// on trouve le user à partir de son username
user = em.find(User.class, json_user.getUsername());
// on update le pixel
pixel.setOwner(user);
pixel.setColor(pixel_new_infos.getColor());
pixel.setDescription(pixel_new_infos.getDescription());
pixel.setPrice(pixel.getPrice() + 1);
// si les identifiants sont valides
if (user.validPassword(json_user.getPassword())) {
user.setSessionID(cookie.getValue());
em.merge(user);
LOGGER.info(user.getUsername() + " logged in");
} else {
LOGGER.info("incorrect creds for " + user.getUsername());
}
}
}
// on ajoute la transaction
Date now = new Date(System.currentTimeMillis());
Transaction new_transaction = new Transaction(now, pixel);
em.persist(new_transaction);
// on update le pixel dans la db
em.merge(pixel);
return gson.toJson(pixel);
@POST
@Path("logout")
public void logout(@CookieParam("JSESSIONID") Cookie cookie) {
try {
User user = User.fromSessionID(cookie.getValue(), em);
user.setSessionID(null);
LOGGER.info(user.getUsername() + " logged out");
} catch (NoResultException e) {
LOGGER.info("user not logged in, cannot logout");
}
}
}