feat: shit just work, time to eat
This commit is contained in:
parent
d1b048ffea
commit
1d16a2ad31
17
.vscode/settings.json
vendored
17
.vscode/settings.json
vendored
|
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
18
src/main/java/com/pixels/Frontend.java
Normal file
18
src/main/java/com/pixels/Frontend.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
30
src/main/java/com/pixels/adapters/PixelAdapter.java
Normal file
30
src/main/java/com/pixels/adapters/PixelAdapter.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
37
src/main/java/com/pixels/adapters/UserAdapter.java
Normal file
37
src/main/java/com/pixels/adapters/UserAdapter.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,32 +28,42 @@ public class User implements Serializable {
|
||||||
// addresse mail de l'utilisateur
|
// addresse mail de l'utilisateur
|
||||||
@NonNull
|
@NonNull
|
||||||
@NotBlank
|
@NotBlank
|
||||||
|
@Column(unique = true)
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
// mot de passe hashé en sha256
|
// mot de passe hashé en sha256
|
||||||
@NonNull
|
@NonNull
|
||||||
@NotBlank
|
@NotBlank
|
||||||
private String hashPassword;
|
private transient String password;
|
||||||
|
|
||||||
// portefeuille
|
// portefeuille
|
||||||
@OneToMany
|
@OneToMany(mappedBy = "owner")
|
||||||
private List<Pixel> pixels;
|
private List<Pixel> pixels;
|
||||||
|
|
||||||
// le solde de l'utilisateur
|
// le solde de l'utilisateur
|
||||||
@NotNull
|
@NotNull
|
||||||
private Integer balance = 0;
|
private Integer balance = 0;
|
||||||
|
|
||||||
// pixels possédés
|
private transient String sessionID;
|
||||||
@OneToMany(mappedBy = "owner")
|
|
||||||
private List<Pixel> owned;
|
|
||||||
|
|
||||||
public User(String username, String email, String password) {
|
public User(String username, String email, String password) {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.email = email;
|
this.email = email;
|
||||||
this.hashPassword = Hash.sha256(password);
|
this.password = Hash.sha256(password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHashPassword(String password) {
|
public void setPassword(String password) {
|
||||||
this.hashPassword = Hash.sha256(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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,30 @@
|
||||||
package com.pixels.services;
|
package com.pixels.services;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
import javax.ejb.Singleton;
|
import javax.ejb.Singleton;
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.PersistenceContext;
|
import javax.persistence.PersistenceContext;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.CookieParam;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.NotFoundException;
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.PUT;
|
import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.Cookie;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
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.Pixel;
|
||||||
|
import com.pixels.beans.Transaction;
|
||||||
|
import com.pixels.beans.User;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Path("/pixel")
|
@Path("/pixel")
|
||||||
|
@ -23,7 +33,10 @@ public class PixelService {
|
||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
private EntityManager em;
|
private EntityManager em;
|
||||||
|
|
||||||
Gson gson = new Gson();
|
Gson gson = new GsonBuilder()
|
||||||
|
.registerTypeAdapter(Pixel.class, new PixelAdapter())
|
||||||
|
.registerTypeAdapter(User.class, new UserAdapter())
|
||||||
|
.create();
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -54,4 +67,42 @@ public class PixelService {
|
||||||
em.merge(pixel);
|
em.merge(pixel);
|
||||||
return gson.toJson(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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,28 @@
|
||||||
package com.pixels.services;
|
package com.pixels.services;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.ejb.Singleton;
|
import javax.ejb.Singleton;
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.PersistenceContext;
|
import javax.persistence.PersistenceContext;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
import javax.persistence.NoResultException;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.CookieParam;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.NotFoundException;
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.Cookie;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
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.Pixel;
|
||||||
import com.pixels.beans.Transaction;
|
|
||||||
import com.pixels.beans.User;
|
import com.pixels.beans.User;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
|
@ -26,7 +32,12 @@ public class UserService {
|
||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
private EntityManager em;
|
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
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@ -36,45 +47,69 @@ public class UserService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}")
|
@Path("{username}")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public String single(@PathParam("id") Long id) {
|
public String single(@PathParam("username") String username) {
|
||||||
User user = em.find(User.class, id);
|
User user = em.find(User.class, username);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
} else {
|
} else {
|
||||||
|
LOGGER.info(gson.toJson(user.getPixels()));
|
||||||
return gson.toJson(user);
|
return gson.toJson(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@POST
|
||||||
@Path("{id_user}/buy/{id_pixel}")
|
@Path("signup")
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
public void signup(@CookieParam("JSESSIONID") Cookie cookie, String json) {
|
||||||
public String buy_pixel(@PathParam("id") Long id_pixel, @PathParam("id") Long id_user, String json) {
|
User json_user = gson.fromJson(json, User.class);
|
||||||
// on récupère les informations du changement
|
User new_user = new User(
|
||||||
Pixel pixel_new_infos = gson.fromJson(json, Pixel.class);
|
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
|
@POST
|
||||||
Pixel pixel = em.find(Pixel.class, id_pixel);
|
@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
|
// on trouve le user à partir de son username
|
||||||
User user = em.find(User.class, id_user);
|
user = em.find(User.class, json_user.getUsername());
|
||||||
|
|
||||||
// on update le pixel
|
// si les identifiants sont valides
|
||||||
pixel.setOwner(user);
|
if (user.validPassword(json_user.getPassword())) {
|
||||||
pixel.setColor(pixel_new_infos.getColor());
|
user.setSessionID(cookie.getValue());
|
||||||
pixel.setDescription(pixel_new_infos.getDescription());
|
em.merge(user);
|
||||||
pixel.setPrice(pixel.getPrice() + 1);
|
LOGGER.info(user.getUsername() + " logged in");
|
||||||
|
} else {
|
||||||
|
LOGGER.info("incorrect creds for " + user.getUsername());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// on ajoute la transaction
|
@POST
|
||||||
Date now = new Date(System.currentTimeMillis());
|
@Path("logout")
|
||||||
Transaction new_transaction = new Transaction(now, pixel);
|
public void logout(@CookieParam("JSESSIONID") Cookie cookie) {
|
||||||
em.persist(new_transaction);
|
try {
|
||||||
|
User user = User.fromSessionID(cookie.getValue(), em);
|
||||||
// on update le pixel dans la db
|
user.setSessionID(null);
|
||||||
em.merge(pixel);
|
LOGGER.info(user.getUsername() + " logged out");
|
||||||
|
} catch (NoResultException e) {
|
||||||
return gson.toJson(pixel);
|
LOGGER.info("user not logged in, cannot logout");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue