ajout backend UserAdmin
This commit is contained in:
parent
4e35764e4c
commit
68917bbcb0
@ -9,7 +9,6 @@ import io.vertx.ext.web.handler.CorsHandler;
|
||||
import io.vertx.ext.auth.jwt.JWTAuth;
|
||||
import io.vertx.ext.web.handler.JWTAuthHandler;
|
||||
|
||||
|
||||
public class MainVerticle extends AbstractVerticle {
|
||||
private DatabaseService databaseService;
|
||||
private Router router;
|
||||
@ -17,32 +16,32 @@ public class MainVerticle extends AbstractVerticle {
|
||||
@Override
|
||||
public void start(Promise<Void> startPromise) throws Exception {
|
||||
databaseService = new DatabaseService(vertx);
|
||||
|
||||
|
||||
// Initialisation du fournisseur JWT
|
||||
JWTAuth jwtAuth = JwtAuthProvider.createJwtAuth(vertx);
|
||||
|
||||
|
||||
// Initialisation du routeur
|
||||
router = Router.router(vertx);
|
||||
router.route().handler(BodyHandler.create());
|
||||
router.route().handler(CorsHandler.create()
|
||||
.addOrigin("*")
|
||||
.allowedMethod(HttpMethod.GET)
|
||||
.allowedMethod(HttpMethod.POST)
|
||||
.allowedHeader("Content-Type")
|
||||
.allowedHeader("Authorization"));
|
||||
|
||||
.addOrigin("*")
|
||||
.allowedMethod(HttpMethod.GET)
|
||||
.allowedMethod(HttpMethod.POST)
|
||||
.allowedHeader("Content-Type")
|
||||
.allowedHeader("Authorization"));
|
||||
|
||||
// Protéger toutes les routes commençant par "/api/"
|
||||
router.route("/api/*").handler(JWTAuthHandler.create(jwtAuth));
|
||||
|
||||
|
||||
// Initialisation des handlers de requêtes
|
||||
QueryObjects queryObjects = new QueryObjects(databaseService);
|
||||
QueryWeatherData queryWeather = new QueryWeatherData(databaseService);
|
||||
SetObjects setObjects = new SetObjects(databaseService);
|
||||
SetWeatherData setWeatherData = new SetWeatherData(databaseService);
|
||||
SetWeatherData setWeatherData = new SetWeatherData(databaseService);
|
||||
AuthHandler authHandler = new AuthHandler(databaseService, jwtAuth);
|
||||
|
||||
QueryUsers queryUsers = new QueryUsers(databaseService);
|
||||
SetUser setUser = new SetUser(databaseService);
|
||||
|
||||
// Déclaration des routes
|
||||
router.get("/objets").handler(queryObjects::getObjects);
|
||||
router.get("/objet").handler(queryObjects::getParticularObject);
|
||||
@ -53,22 +52,23 @@ public class MainVerticle extends AbstractVerticle {
|
||||
router.get("/getRange").handler(queryWeather::getRangeData);
|
||||
router.post("/modifRangeData").handler(setWeatherData::setRangeData);
|
||||
router.post("/deleteObject").handler(setObjects::deleteObject);
|
||||
|
||||
router.get("/users").handler(queryUsers::getUsers);
|
||||
router.post("/setUserPoints").handler(setUser::setUserPoints);
|
||||
// Routes d'authentification
|
||||
router.post("/signup").handler(authHandler::handleSignup);
|
||||
router.post("/login").handler(authHandler::handleLogin);
|
||||
|
||||
|
||||
// Création du serveur HTTP
|
||||
vertx.createHttpServer()
|
||||
.requestHandler(router)
|
||||
.listen(8888)
|
||||
.onSuccess(server -> {
|
||||
System.out.println("HTTP server started on port " + server.actualPort());
|
||||
startPromise.complete();
|
||||
})
|
||||
.onFailure(throwable -> {
|
||||
throwable.printStackTrace();
|
||||
startPromise.fail(throwable);
|
||||
});
|
||||
.requestHandler(router)
|
||||
.listen(8888)
|
||||
.onSuccess(server -> {
|
||||
System.out.println("HTTP server started on port " + server.actualPort());
|
||||
startPromise.complete();
|
||||
})
|
||||
.onFailure(throwable -> {
|
||||
throwable.printStackTrace();
|
||||
startPromise.fail(throwable);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
51
Back-end/src/main/java/com/example/starter/QueryUsers.java
Normal file
51
Back-end/src/main/java/com/example/starter/QueryUsers.java
Normal file
@ -0,0 +1,51 @@
|
||||
package com.example.starter;
|
||||
|
||||
import io.vertx.core.json.JsonArray;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import io.vertx.sqlclient.Row;
|
||||
|
||||
public class QueryUsers {
|
||||
private DatabaseService databaseService;
|
||||
|
||||
public QueryUsers(DatabaseService dtbS) {
|
||||
this.databaseService = dtbS;
|
||||
}
|
||||
|
||||
public void getUsers(RoutingContext context) {
|
||||
databaseService.pool
|
||||
.query("SELECT * FROM users;")
|
||||
.execute()
|
||||
.onFailure(e -> {
|
||||
System.err.println("Erreur de récupération de la BDD :" + e.getMessage());
|
||||
context.response()
|
||||
.setStatusCode(500)
|
||||
.end(new JsonObject().put("error", "Erreur de récupération de la BDD").encode());
|
||||
})
|
||||
.onSuccess(rows -> {
|
||||
JsonArray users = new JsonArray();
|
||||
for (Row row : rows) {
|
||||
int points=row.getInteger("points");
|
||||
JsonObject user = new JsonObject()
|
||||
.put("id", row.getInteger("id"))
|
||||
.put("name", row.getString("name"))
|
||||
.put("surname", row.getString("surname"))
|
||||
.put("email", row.getString("email"))
|
||||
.put("gender", row.getString("gender"))
|
||||
.put("points",points);
|
||||
if(points<=30){
|
||||
user.put("role", "user");
|
||||
}else if(points<=60){
|
||||
user.put("role", "complexe");
|
||||
}else if(points>=100){
|
||||
user.put("role", "admin");
|
||||
}
|
||||
users.add(user);
|
||||
}
|
||||
context.response()
|
||||
.putHeader("content-type", "application/json; charset=UTF-8")
|
||||
.end(users.encode());
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
48
Back-end/src/main/java/com/example/starter/SetUser.java
Normal file
48
Back-end/src/main/java/com/example/starter/SetUser.java
Normal file
@ -0,0 +1,48 @@
|
||||
package com.example.starter;
|
||||
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import io.vertx.sqlclient.Tuple;
|
||||
|
||||
public class SetUser {
|
||||
private DatabaseService databaseService;
|
||||
|
||||
public SetUser(DatabaseService ddbs) {
|
||||
this.databaseService = ddbs;
|
||||
}
|
||||
|
||||
public void setUserPoints(RoutingContext context) {
|
||||
JsonObject body = context.body().asJsonObject();
|
||||
if (body == null) {
|
||||
context.response()
|
||||
.setStatusCode(400)
|
||||
.end(new JsonObject().put("error", "Corps de la requête manquant").encode());
|
||||
return;
|
||||
}
|
||||
Integer id = body.getInteger("id");
|
||||
Integer points = body.getInteger("points");
|
||||
|
||||
databaseService.pool
|
||||
.preparedQuery(
|
||||
"UPDATE users SET points=? WHERE id=?")
|
||||
.execute(Tuple.of(points,id))
|
||||
.onFailure(e -> {
|
||||
System.err.println("Erreur de récupération de la BDD :" + e.getMessage());
|
||||
context.response()
|
||||
.setStatusCode(500)
|
||||
.end(new JsonObject().put("Erreur", "Erreur de récupération de la BDD").encode());
|
||||
})
|
||||
.onSuccess(rows -> {
|
||||
if (rows.rowCount() == 0) {
|
||||
context.response()
|
||||
.setStatusCode(404)
|
||||
.end(new JsonObject().put("error", "Utilisateur non trouvé").encode());
|
||||
return;
|
||||
}
|
||||
context.response()
|
||||
.putHeader("content-type", "application/json: charset=UTF-8")
|
||||
.end(new JsonObject().put("success", "Les points de l'utilisateur ont bien été mis à jour").encode());
|
||||
return;
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,8 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useState,useEffect } from "react";
|
||||
import Sidebar from "./sidebar.jsx";
|
||||
import { API_BASE_URL } from "../../config.js";
|
||||
import axios from "axios";
|
||||
|
||||
|
||||
const dashboardStyles = {
|
||||
mainContent: {
|
||||
@ -44,35 +47,7 @@ const dashboardStyles = {
|
||||
};
|
||||
|
||||
function Dashboard() {
|
||||
// États simulés (dans une vraie application, ils viendraient d'une API ou d'un store global)
|
||||
const [users, setUsers] = useState([
|
||||
{
|
||||
id: 1,
|
||||
username: "Alice",
|
||||
email: "alice@example.com",
|
||||
accessLevel: "Admin",
|
||||
},
|
||||
{ id: 2, username: "Bob", email: "bob@example.com", accessLevel: "User" },
|
||||
{
|
||||
id: 3,
|
||||
username: "Charlie",
|
||||
email: "charlie@example.com",
|
||||
accessLevel: "Guest",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
username: "David",
|
||||
email: "david@example.com",
|
||||
accessLevel: "User",
|
||||
},
|
||||
{ id: 5, username: "Eva", email: "eva@example.com", accessLevel: "User" },
|
||||
{
|
||||
id: 6,
|
||||
username: "Frank",
|
||||
email: "frank@example.com",
|
||||
accessLevel: "Admin",
|
||||
},
|
||||
]);
|
||||
const [users, setUsers] = useState([]);
|
||||
const [logs, setLogs] = useState([
|
||||
{
|
||||
id: 1,
|
||||
@ -87,7 +62,11 @@ function Dashboard() {
|
||||
timestamp: new Date().toLocaleString(),
|
||||
},
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
axios.get(`${API_BASE_URL}/users`).then((response) => {
|
||||
setUsers(response.data);
|
||||
});
|
||||
}, []);
|
||||
return (
|
||||
<div style={{ display: "flex", minHeight: "100vh" }}>
|
||||
<Sidebar />
|
||||
@ -118,15 +97,15 @@ function Dashboard() {
|
||||
<tr>
|
||||
<th style={dashboardStyles.tableHeader}>Username</th>
|
||||
<th style={dashboardStyles.tableHeader}>Email</th>
|
||||
<th style={dashboardStyles.tableHeader}>Access Level</th>
|
||||
<th style={dashboardStyles.tableHeader}>Niveau d'accès</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{users.slice(0, 5).map((user) => (
|
||||
<tr key={user.id}>
|
||||
<td style={dashboardStyles.tableCell}>{user.username}</td>
|
||||
<td style={dashboardStyles.tableCell}>{user.name}</td>
|
||||
<td style={dashboardStyles.tableCell}>{user.email}</td>
|
||||
<td style={dashboardStyles.tableCell}>{user.accessLevel}</td>
|
||||
<td style={dashboardStyles.tableCell}>{user.role}</td>
|
||||
</tr>
|
||||
))}
|
||||
{users.length === 0 && (
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useState,useEffect} from "react";
|
||||
import Sidebar from "./sidebar.jsx";
|
||||
import { API_BASE_URL } from "../../config.js";
|
||||
import axios from "axios";
|
||||
|
||||
const styles = {
|
||||
mainContent: {
|
||||
@ -46,47 +48,48 @@ const styles = {
|
||||
};
|
||||
|
||||
function User() {
|
||||
// États pour la gestion des utilisateurs, des logs, des champs du formulaire et des ajustements de points
|
||||
const [users, setUsers] = useState([]);
|
||||
const [logs, setLogs] = useState([]);
|
||||
const [username, setUsername] = useState("");
|
||||
const [name, setname] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [pointsInput, setPointsInput] = useState({});
|
||||
|
||||
// Ajout d'un utilisateur
|
||||
const handleAddUser = (e) => {
|
||||
e.preventDefault();
|
||||
const newUser = {
|
||||
id: Date.now(),
|
||||
username,
|
||||
name,
|
||||
email,
|
||||
accessLevel: "User", // Niveau d'accès par défaut
|
||||
accessLevel: "User",
|
||||
points: 0,
|
||||
};
|
||||
setUsers([...users, newUser]);
|
||||
logAction(username, "User added");
|
||||
setUsername("");
|
||||
logAction(name, "User added");
|
||||
setname("");
|
||||
setEmail("");
|
||||
};
|
||||
|
||||
// Suppression d'un utilisateur (fonction présente dans script.js)
|
||||
useEffect(() => {
|
||||
axios.get(`${API_BASE_URL}/users`).then((response) => {
|
||||
setUsers(response.data);
|
||||
});
|
||||
}, []);
|
||||
const handleDeleteUser = (userId) => {
|
||||
const user = users.find((u) => u.id === userId);
|
||||
if (user) {
|
||||
logAction(user.username, "User deleted");
|
||||
logAction(user.name, "User deleted");
|
||||
}
|
||||
setUsers(users.filter((u) => u.id !== userId));
|
||||
};
|
||||
|
||||
// Changement du niveau d'accès via le menu déroulant (fonction issue de script.js)
|
||||
const handleChangeAccessLevel = (userId, newLevel) => {
|
||||
setUsers(
|
||||
users.map((user) => {
|
||||
if (user.id === userId) {
|
||||
const oldLevel = user.accessLevel;
|
||||
user.accessLevel = newLevel;
|
||||
const oldLevel = user.role;
|
||||
user.role = newLevel;
|
||||
/*ToDO*/
|
||||
logAction(
|
||||
user.username,
|
||||
user.name,
|
||||
`Access level changed from ${oldLevel} to ${newLevel}`
|
||||
);
|
||||
}
|
||||
@ -95,26 +98,39 @@ function User() {
|
||||
);
|
||||
};
|
||||
|
||||
// Ajustement des points d'un utilisateur (fonction issue de script.js)
|
||||
const handleAdjustPoints = (userId) => {
|
||||
const pointsToAdd = parseInt(pointsInput[userId]) || 0;
|
||||
setUsers(
|
||||
users.map((user) => {
|
||||
if (user.id === userId) {
|
||||
user.points += pointsToAdd;
|
||||
logAction(user.username, `Points adjusted by ${pointsToAdd}`);
|
||||
axios
|
||||
.post(`${API_BASE_URL}/setUserPoints`, {
|
||||
id:user.id,
|
||||
points:user.points,
|
||||
})
|
||||
.then((response) => {
|
||||
setMessRequete("Les points ont bien été enregistré !");
|
||||
setEnregistre(true);
|
||||
console.log("Ajout des points réussit :", response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
setMessRequete("Il y a eu une erreur dans l'ajout des points!");
|
||||
console.error("Erreur lors de l'ajout des points :", error);
|
||||
});
|
||||
logAction(user.name, `Points ajustés par ${pointsToAdd}`);
|
||||
}
|
||||
return user;
|
||||
})
|
||||
);
|
||||
// Réinitialiser la valeur de l'input pour cet utilisateur
|
||||
setPointsInput({ ...pointsInput, [userId]: "" });
|
||||
};
|
||||
|
||||
// Fonction de journalisation des actions (définie dans script.js)
|
||||
const logAction = (username, action) => {
|
||||
const logAction = (name, action) => {
|
||||
/*TODO*/
|
||||
/*Ajouter le suivi dans un journal de log*/
|
||||
const timestamp = new Date().toLocaleString();
|
||||
setLogs([...logs, { id: Date.now(), username, action, timestamp }]);
|
||||
setLogs([...logs, { id: Date.now(), name, action, timestamp }]);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -129,10 +145,10 @@ function User() {
|
||||
<input
|
||||
style={styles.input}
|
||||
type="text"
|
||||
id="username"
|
||||
placeholder="Username"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
id="name"
|
||||
placeholder="name"
|
||||
value={name}
|
||||
onChange={(e) => setname(e.target.value)}
|
||||
required
|
||||
/>
|
||||
<input
|
||||
@ -152,9 +168,9 @@ function User() {
|
||||
<table style={styles.userTable}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Username</th>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Nom</th>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Email</th>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Access Level</th>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Niveau d'accès</th>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Points</th>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Actions</th>
|
||||
</tr>
|
||||
@ -162,20 +178,20 @@ function User() {
|
||||
<tbody>
|
||||
{users.map((user) => (
|
||||
<tr key={user.id}>
|
||||
<td style={styles.thTd}>{user.username}</td>
|
||||
<td style={styles.thTd}>{user.name}</td>
|
||||
<td style={styles.thTd}>{user.email}</td>
|
||||
<td style={styles.thTd}>
|
||||
{/* Menu déroulant pour changer le niveau d'accès */}
|
||||
<select
|
||||
value={user.accessLevel}
|
||||
value={user.role}
|
||||
onChange={(e) =>
|
||||
handleChangeAccessLevel(user.id, e.target.value)
|
||||
}
|
||||
style={{ padding: "5px", borderRadius: "5px" }}
|
||||
>
|
||||
<option value="Admin">Admin</option>
|
||||
<option value="User">User</option>
|
||||
<option value="Guest">Guest</option>
|
||||
<option value="admin">Admin</option>
|
||||
<option value="user">User</option>
|
||||
<option value="complexe">Complexe</option>
|
||||
</select>
|
||||
</td>
|
||||
<td style={styles.thTd}>
|
||||
@ -225,11 +241,11 @@ function User() {
|
||||
</section>
|
||||
{/* Tableau des logs */}
|
||||
<section className="user-logs" style={{ marginTop: "40px" }}>
|
||||
<h2>Login History and Action Logs</h2>
|
||||
<h2>Historique des connexions et journal des logs </h2>
|
||||
<table style={styles.userTable}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Username</th>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Nom</th>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Action</th>
|
||||
<th style={{ ...styles.thTd, ...styles.th }}>Timestamp</th>
|
||||
</tr>
|
||||
@ -237,7 +253,7 @@ function User() {
|
||||
<tbody>
|
||||
{logs.map((log) => (
|
||||
<tr key={log.id}>
|
||||
<td style={styles.thTd}>{log.username}</td>
|
||||
<td style={styles.thTd}>{log.name}</td>
|
||||
<td style={styles.thTd}>{log.action}</td>
|
||||
<td style={styles.thTd}>{log.timestamp}</td>
|
||||
</tr>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user