diff --git a/pom.xml b/pom.xml
index 1492269..9fdd9e2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -79,6 +79,11 @@
rest-assured
test
+
+ io.quarkiverse.docker
+ quarkus-docker-client
+ 0.0.5
+
org.projectlombok
lombok
diff --git a/shell.nix b/shell.nix
index 1bc0e59..15a8a5b 100644
--- a/shell.nix
+++ b/shell.nix
@@ -1,30 +1,32 @@
{ pkgs ? import {} }:
-
pkgs.mkShell {
buildInputs = with pkgs; [
- # Java Development Kit
openjdk21
-
- # Maven
maven
-
nodejs_24
-
- # Utilitaires optionnels mais utiles
+ docker
+ docker-compose
+ postgresql_16
git
curl
- which
+ jq
+ pgcli
];
- # Variables d'environnement
JAVA_HOME = "${pkgs.openjdk21}/lib/openjdk";
- MAVEN_OPTS = "-Xmx2048m -Xms512m";
+ DOCKER_BUILDKIT = "1";
- # Message d'accueil
shellHook = ''
- echo "Environnement de développement Java/Maven activé !"
- echo "Java version: $(java -version 2>&1 | head -n 1)"
- echo "Maven version: $(mvn -version | head -n 1)"
- echo "JAVA_HOME: $JAVA_HOME"
+ source ~/.bashrc
+ echo "Quarkus dev environment ready!"
+ echo "Java: $(java -version 2>&1 | head -n 1)"
+ export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
+ dockerd-rootless &
+ # Fix Docker socket
+ if [ ! -S /var/run/docker.sock ]; then
+ echo "⚠️ Docker not started. Run:"
+ echo " sudo systemctl start docker"
+ echo " sudo usermod -aG docker $USER"
+ fi
'';
}
diff --git a/src/main/java/fr/la_banquise/backend/data/model/Container.java b/src/main/java/fr/la_banquise/backend/data/model/Container.java
new file mode 100644
index 0000000..b84dbb0
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/data/model/Container.java
@@ -0,0 +1,72 @@
+/**package fr.la_banquise.backend.data.model;
+
+import com.fasterxml.jackson.annotation.JsonBackReference;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.github.dockerjava.api.DockerClient;
+import com.github.dockerjava.api.command.CreateContainerResponse;
+import com.github.dockerjava.api.command.InspectContainerResponse.ContainerState;
+import com.github.dockerjava.api.model.ExposedPort;
+import com.github.dockerjava.api.model.HostConfig;
+import com.github.dockerjava.api.model.Ports;
+import jakarta.inject.Inject;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.SequenceGenerator;
+import jakarta.persistence.Table;
+import java.util.List;
+import lombok.NoArgsConstructor;
+
+/**
+ * Instances
+
+@Entity
+@NoArgsConstructor
+@Table(name = "dockerfile")
+public class Dockerfile {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @SequenceGenerator(name = "DockerfileSeq",
+ sequenceName = "dockerfile_id_seq", allocationSize = 1,
+ initialValue = 1)
+ public Long id;
+ @Column(unique = true) public String name;
+ public String text;
+
+ @JsonIgnore
+ public List instances;
+
+ public Dockerfile(String name, String text) {
+ this.name = name;
+ this.text = text;
+ }
+
+ public Dockerfile() {}
+
+ public boolean isCreated() { return containerId != null && status != null; }
+
+ public boolean createContainer(String containerName, int port) {
+ ExposedPort tcpSsh = ExposedPort.tcp(80);
+
+ Ports portBindings = new Ports();
+ portBindings.bind(tcpSsh, Ports.Binding.bindPort(port));
+
+ HostConfig hostConfig =
+ HostConfig.newHostConfig().withPortBindings(portBindings);
+
+ CreateContainerResponse container =
+ dockerClient.createContainerCmd("nginx:latest")
+ .withName(containerName)
+ .withExposedPorts(tcpSsh)
+ .withHostConfig(hostConfig)
+ .exec();
+
+ this.containerId = container.getId();
+
+ return true;
+ };
+}**/
diff --git a/src/main/java/fr/la_banquise/backend/data/model/Instance.java b/src/main/java/fr/la_banquise/backend/data/model/Instance.java
index 42da592..18fbb92 100644
--- a/src/main/java/fr/la_banquise/backend/data/model/Instance.java
+++ b/src/main/java/fr/la_banquise/backend/data/model/Instance.java
@@ -1,7 +1,9 @@
package fr.la_banquise.backend.data.model;
-import com.fasterxml.jackson.annotation.JsonBackReference;
+import java.util.Set;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
@@ -10,6 +12,7 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
+import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
/**
@@ -17,32 +20,34 @@ import lombok.NoArgsConstructor;
*/
@Entity
@NoArgsConstructor
+@AllArgsConstructor
@Table(name = "instance")
public class Instance {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
- @SequenceGenerator(name = "InstanceSeq", sequenceName = "instance_id_seq", allocationSize = 1, initialValue = 1)
+ @SequenceGenerator(name = "InstanceSeq", sequenceName = "instance_id_seq",
+ allocationSize = 1, initialValue = 1)
public Long id;
- public String name;
- public String ssh;
- public Long port;
- public String pwd;
- @JsonBackReference
+ @Column(unique = true, nullable = false)
+ public String name;
+ // So people cant have more than one
+ // container per JI because name will be login-jiId
+
+ public int port;
+
+ //@JsonBackReference
+ @JsonIgnore
@ManyToOne
@JoinColumn(name = "user_id", nullable = false)
- public User user;
+ public User owner;
- @ManyToOne
- @JoinColumn(name = "practical_id")
- public Tp tp;
+ //@ManyToOne @JoinColumn(name = "ji_id", nullable = false) public Ji ji;
- public Instance(String name, String ssh, String pwd, Long port, User user, Tp tp) {
+ public Instance(String name, int port, User user ) {//, Ji ji) {
this.name = name;
- this.ssh = ssh;
- this.pwd = pwd;
this.port = port;
- this.user = user;
- this.tp = tp;
+ this.owner = user;
+ //this.ji = ji;
}
}
diff --git a/src/main/java/fr/la_banquise/backend/data/model/Ji.java b/src/main/java/fr/la_banquise/backend/data/model/Ji.java
new file mode 100644
index 0000000..852ca12
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/data/model/Ji.java
@@ -0,0 +1,54 @@
+package fr.la_banquise.backend.data.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.JoinTable;
+import jakarta.persistence.ManyToMany;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.SequenceGenerator;
+import jakarta.persistence.Table;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+
+@Entity
+@NoArgsConstructor
+@AllArgsConstructor
+@Table(name = "ji")
+public class Ji {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @SequenceGenerator(name = "JiSeq", sequenceName = "ji_id_seq",
+ allocationSize = 1, initialValue = 1)
+ public Long id;
+ public String name;
+ public String description;
+
+ @JsonIgnore
+ @ManyToMany
+ @JoinTable(name = "ji_respos", // Table de liaison
+ joinColumns = @JoinColumn(name = "ji_id"),
+ inverseJoinColumns = @JoinColumn(name = "user_id"))
+ public List respos;
+ public String date;
+
+ @ManyToOne
+ @JoinColumn(name = "site_id") //@JsonIgnore
+ public Site site;
+
+ @OneToMany @JoinColumn(name = "instance_id") public List instances;
+
+ public Ji(String name, String description, List respos, String date,
+ Site site) {
+ this.name = name;
+ this.description = description;
+ this.respos = respos;
+ this.date = date;
+ this.site = site;
+ }
+}
diff --git a/src/main/java/fr/la_banquise/backend/data/model/RolesAsso.java b/src/main/java/fr/la_banquise/backend/data/model/RolesAsso.java
new file mode 100644
index 0000000..ee4d0ac
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/data/model/RolesAsso.java
@@ -0,0 +1,20 @@
+package fr.la_banquise.backend.data.model;
+
+public enum RolesAsso {
+ ROOT("ROOT"), // ROOT should always be the first
+ MODO("MODO"),
+ PINGOUIN("PINGOUIN"),
+ JI("JI"),
+ NONE("NONE");
+
+ private final String roleName;
+
+ RolesAsso(String roleName) { this.roleName = roleName; }
+
+ public String getRoleName() { return roleName; }
+
+ @Override
+ public String toString() {
+ return roleName;
+ }
+}
diff --git a/src/main/java/fr/la_banquise/backend/data/model/Site.java b/src/main/java/fr/la_banquise/backend/data/model/Site.java
new file mode 100644
index 0000000..8dc60e9
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/data/model/Site.java
@@ -0,0 +1,48 @@
+package fr.la_banquise.backend.data.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.SequenceGenerator;
+import jakarta.persistence.Table;
+import jakarta.persistence.UniqueConstraint;
+import java.util.ArrayList;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+@Entity
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+@Table(name = "site",
+ uniqueConstraints = { @UniqueConstraint(columnNames = "name") })
+public class Site {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @SequenceGenerator(name = "SiteSeq", sequenceName = "site_id_seq",
+ allocationSize = 1, initialValue = 1)
+ public Long id;
+
+ @Column(unique = true, nullable = false) public String name;
+ public String description;
+ public String address;
+
+ /*@OneToMany(mappedBy = "ji", cascade = CascadeType.ALL)
+ public List instances;*/
+
+ @OneToMany(mappedBy = "site") @JsonIgnore public List jiInSite;
+
+ public Site(String name, String description, String address) {
+ this.name = name;
+ this.description = description;
+ this.address = address;
+ this.jiInSite = new ArrayList();
+ }
+}
diff --git a/src/main/java/fr/la_banquise/backend/data/model/Sujet.java b/src/main/java/fr/la_banquise/backend/data/model/Sujet.java
new file mode 100644
index 0000000..d12f7f9
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/data/model/Sujet.java
@@ -0,0 +1,52 @@
+package fr.la_banquise.backend.data.model;
+
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.JoinTable;
+import jakarta.persistence.ManyToMany;
+import jakarta.persistence.SequenceGenerator;
+import jakarta.persistence.Table;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+
+/**
+ * Tp
+ */
+@Entity
+@NoArgsConstructor
+@AllArgsConstructor
+@Table(name = "Sujet")
+public class Sujet {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @SequenceGenerator(name = "SujetSeq", sequenceName = "sujet_id_seq",
+ allocationSize = 1, initialValue = 1)
+ public Long id;
+ public String name;
+ public String description;
+ public String pdfLink;
+ @ManyToMany
+ @JoinTable(
+ name = "sujet_user", // Table de liaison
+ joinColumns = @JoinColumn(name = "sujet_id"),
+ inverseJoinColumns = @JoinColumn(name = "user_id")
+ )
+ @JsonIgnore
+ public List respos;
+
+ public Sujet(String name, String description, String pdfLink,
+ List respos) {
+ this.name = name;
+ this.description = description;
+ this.pdfLink = pdfLink;
+ this.respos = respos;
+ }
+}
diff --git a/src/main/java/fr/la_banquise/backend/data/model/Tp.java b/src/main/java/fr/la_banquise/backend/data/model/Tp.java
deleted file mode 100644
index 8eeb3b6..0000000
--- a/src/main/java/fr/la_banquise/backend/data/model/Tp.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package fr.la_banquise.backend.data.model;
-
-import io.quarkus.hibernate.orm.panache.PanacheEntity;
-import jakarta.persistence.Entity;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.SequenceGenerator;
-import jakarta.persistence.Table;
-import lombok.AllArgsConstructor;
-import lombok.NoArgsConstructor;
-
-/**
- * Tp
- */
-@Entity
-@NoArgsConstructor
-@AllArgsConstructor
-@Table(name = "tp")
-public class Tp {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- @SequenceGenerator(name = "TpSeq", sequenceName = "tp_id_seq", allocationSize = 1, initialValue = 1)
- public Long id;
- public String name;
- public String description;
- public String pdfLink;
- public String respo;
- public String date;
-
- public Tp(String name, String description, String pdfLink, String respo, String date) {
- this.name = name;
- this.description = description;
- this.pdfLink = pdfLink;
- this.respo = respo;
- this.date = date;
- }
-}
diff --git a/src/main/java/fr/la_banquise/backend/data/model/User.java b/src/main/java/fr/la_banquise/backend/data/model/User.java
index 325e749..3bd8f5e 100644
--- a/src/main/java/fr/la_banquise/backend/data/model/User.java
+++ b/src/main/java/fr/la_banquise/backend/data/model/User.java
@@ -1,21 +1,30 @@
package fr.la_banquise.backend.data.model;
-import java.util.List;
-
-import com.fasterxml.jackson.annotation.JsonManagedReference;
-
import io.quarkus.security.jpa.Password;
import io.quarkus.security.jpa.Roles;
+import io.quarkus.security.jpa.RolesValue;
import io.quarkus.security.jpa.UserDefinition;
import io.quarkus.security.jpa.Username;
import jakarta.persistence.CascadeType;
+import jakarta.persistence.CollectionTable;
+import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
+import jakarta.persistence.ManyToMany;
import jakarta.persistence.OneToMany;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -34,24 +43,44 @@ import lombok.Setter;
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
- @SequenceGenerator(name = "UserSeq", sequenceName = "user_id_seq", allocationSize = 1, initialValue = 1)
+ @SequenceGenerator(name = "UserSeq", sequenceName = "user_id_seq",
+ allocationSize = 1, initialValue = 1)
public Long id;
- @Username
- public String name;
- @Password
- public String password;
- @Roles
- public String role;
+ @Username public String name;
+ @Password public String password;
- @JsonManagedReference
- @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
+ @Enumerated(EnumType.STRING)
+ @ElementCollection(fetch = FetchType.EAGER)
+ @CollectionTable(name = "user_roles")
+ public Set role;
+
+ //@JsonManagedReference
+ @OneToMany(mappedBy = "owner", cascade = CascadeType.ALL)
public List instances;
- public User(String name, String password, String role, List instances) {
- this.name = name;
- this.password = password;
- this.role = role;
- this.instances = instances;
+ @ManyToMany(mappedBy = "respos", cascade = CascadeType.ALL)
+ public List sujetRespo;
+
+ @ManyToMany(mappedBy = "respos", cascade = CascadeType.ALL)
+ public List jiRespo;
+
+ // Méthode pour Quarkus Security - conversion simple
+ @RolesValue
+ @Roles
+ public Set getRoles() {
+ return role.stream()
+ .filter(r -> r != RolesAsso.NONE)
+ .map(Enum::name)
+ .collect(Collectors.toSet());
}
+ public User(String name, String password, RolesAsso role) {
+ this.name = name;
+ this.password = password;
+ if (role == RolesAsso.NONE)
+ this.role = new HashSet<>();
+ else
+ this.role = new HashSet<>(Arrays.asList(role));
+ this.instances = new ArrayList<>();
+ }
}
diff --git a/src/main/java/fr/la_banquise/backend/data/repository/ContainerRepository.java b/src/main/java/fr/la_banquise/backend/data/repository/ContainerRepository.java
new file mode 100644
index 0000000..114fe18
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/data/repository/ContainerRepository.java
@@ -0,0 +1,12 @@
+/**package fr.la_banquise.backend.data.repository;
+
+import fr.la_banquise.backend.data.model.Container;
+import io.quarkus.hibernate.orm.panache.PanacheRepository;
+import jakarta.enterprise.context.ApplicationScoped;
+
+/**
+ * InstanceRepository
+
+@ApplicationScoped
+public class ContainerRepository implements PanacheRepository {
+}*/
diff --git a/src/main/java/fr/la_banquise/backend/data/repository/JiRepository.java b/src/main/java/fr/la_banquise/backend/data/repository/JiRepository.java
new file mode 100644
index 0000000..c2025c5
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/data/repository/JiRepository.java
@@ -0,0 +1,9 @@
+package fr.la_banquise.backend.data.repository;
+
+import fr.la_banquise.backend.data.model.Ji;
+import io.quarkus.hibernate.orm.panache.PanacheRepository;
+import jakarta.enterprise.context.ApplicationScoped;
+
+@ApplicationScoped
+public class JiRepository implements PanacheRepository {
+}
diff --git a/src/main/java/fr/la_banquise/backend/data/repository/SiteRepository.java b/src/main/java/fr/la_banquise/backend/data/repository/SiteRepository.java
new file mode 100644
index 0000000..0dc3a52
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/data/repository/SiteRepository.java
@@ -0,0 +1,8 @@
+package fr.la_banquise.backend.data.repository;
+
+import fr.la_banquise.backend.data.model.Site;
+import io.quarkus.hibernate.orm.panache.PanacheRepository;
+import jakarta.enterprise.context.ApplicationScoped;
+
+@ApplicationScoped
+public class SiteRepository implements PanacheRepository {}
diff --git a/src/main/java/fr/la_banquise/backend/data/repository/TpRepository.java b/src/main/java/fr/la_banquise/backend/data/repository/SujetRepository.java
similarity index 63%
rename from src/main/java/fr/la_banquise/backend/data/repository/TpRepository.java
rename to src/main/java/fr/la_banquise/backend/data/repository/SujetRepository.java
index c395dfc..85aa285 100644
--- a/src/main/java/fr/la_banquise/backend/data/repository/TpRepository.java
+++ b/src/main/java/fr/la_banquise/backend/data/repository/SujetRepository.java
@@ -1,6 +1,6 @@
package fr.la_banquise.backend.data.repository;
-import fr.la_banquise.backend.data.model.Tp;
+import fr.la_banquise.backend.data.model.Sujet;
import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped;
@@ -8,5 +8,4 @@ import jakarta.enterprise.context.ApplicationScoped;
* TpRepository
*/
@ApplicationScoped
-public class TpRepository implements PanacheRepository {
-}
+public class SujetRepository implements PanacheRepository {}
diff --git a/src/main/java/fr/la_banquise/backend/rest/ContainerResource.java b/src/main/java/fr/la_banquise/backend/rest/ContainerResource.java
new file mode 100644
index 0000000..0a5bd48
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/rest/ContainerResource.java
@@ -0,0 +1,98 @@
+package fr.la_banquise.backend.rest;
+
+import fr.la_banquise.backend.services.DockerService;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import java.util.Map;
+
+@Path("/containers")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class ContainerResource {
+
+ @Inject DockerService dockerService;
+
+ @POST
+ @Path("/nginx")
+ public Response launchNginx() {
+ try {
+ String id = dockerService.createAndStartNginx();
+ return Response.ok(Map.of("containerId", id, "status", "running"))
+ .build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+
+ @POST
+ @Path("/create")
+ public Response createContainer(@QueryParam("name") String name,
+ @QueryParam("port") int port) {
+ try {
+ String id = dockerService.createContainer(name, port);
+ return Response.ok(Map.of("containerId", id)).build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+
+ @GET
+ @Path("/all")
+ public Response listContainers() {
+ try {
+ String id = dockerService.listAllContainers();
+ return Response.ok(id).build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+
+ @POST
+ @Path("/start")
+ public Response start(@QueryParam("id") String id) {
+ try {
+ dockerService.start(id);
+ return Response.ok(Map.of("containerId", id, "status", "Running"))
+ .build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+
+ @POST
+ @Path("/stop")
+ public Response stop(@QueryParam("id") String id) {
+ try {
+ dockerService.stop(id);
+ return Response.ok(Map.of("containerId", id, "status", "removed"))
+ .build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+ @DELETE
+ @Path("/remove")
+ public Response remove(@QueryParam("id") String id) {
+ try {
+ dockerService.remove(id);
+ return Response.ok(Map.of("containerId", id, "status", "removed"))
+ .build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+}
diff --git a/src/main/java/fr/la_banquise/backend/rest/Endpoints.java b/src/main/java/fr/la_banquise/backend/rest/Endpoints.java
index ce4da5f..3918dec 100644
--- a/src/main/java/fr/la_banquise/backend/rest/Endpoints.java
+++ b/src/main/java/fr/la_banquise/backend/rest/Endpoints.java
@@ -2,7 +2,8 @@ package fr.la_banquise.backend.rest;
import fr.la_banquise.backend.rest.response.DashboardResponse;
import fr.la_banquise.backend.services.InstanceService;
-import fr.la_banquise.backend.services.TpService;
+import fr.la_banquise.backend.services.SujetService;
+import io.quarkus.security.Authenticated;
import io.quarkus.security.identity.SecurityIdentity;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
@@ -15,27 +16,21 @@ import jakarta.ws.rs.core.Response;
@Path("api")
public class Endpoints {
- @Inject
- SecurityIdentity identity;
+ @Inject SecurityIdentity identity;
- @Inject
- InstanceService instanceService;
+ @Inject InstanceService instanceService;
- @Inject
- TpService tpService;
+ @Inject SujetService sujetService;
@GET
+ @Authenticated
@Path("dashboard")
public Response getDashboard() {
String username = identity.getPrincipal().getName();
DashboardResponse dashboard = new DashboardResponse();
- if (identity.getRoles().contains("root")) {
- dashboard.tps = tpService.getAllTpsAdmin();
- } else {
-
- dashboard.tps = tpService.getAllTps(identity.getPrincipal().getName());
- }
- dashboard.instances = instanceService.getAllInstances(username);
+ dashboard.tps =
+ sujetService.getAllSujetsRespo(identity.getPrincipal().getName());
+ // dashboard.instances = instanceService.getAllInstances(username);
return Response.ok(dashboard).build();
}
}
diff --git a/src/main/java/fr/la_banquise/backend/rest/InstanceEndpoints.java b/src/main/java/fr/la_banquise/backend/rest/InstanceEndpoints.java
index 39b7d7b..23c7339 100644
--- a/src/main/java/fr/la_banquise/backend/rest/InstanceEndpoints.java
+++ b/src/main/java/fr/la_banquise/backend/rest/InstanceEndpoints.java
@@ -1,38 +1,57 @@
package fr.la_banquise.backend.rest;
-import fr.la_banquise.backend.rest.request.InstanceRequest;
import fr.la_banquise.backend.services.InstanceService;
+import fr.la_banquise.backend.services.JiService;
import io.quarkus.security.identity.SecurityIdentity;
+import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
/**
* InstanceEndpoints
*/
-@Path("/api/instances")
+@Path("/api/ji/")
@Produces(MediaType.APPLICATION_JSON)
public class InstanceEndpoints {
- @Inject
- SecurityIdentity identity;
+ @Inject SecurityIdentity identity;
- @Inject
- InstanceService instanceService;
+ @Inject JiService jiService;
+ @Inject InstanceService instanceService;
@GET
+ @RolesAllowed("ROOT")
+ @Path("/instances")
public Response getAllInstances() {
- String username = identity.getPrincipal().getName();
- return Response.ok(instanceService.getAllInstances(username)).build();
+ return Response.ok(instanceService.getAllInstances()).build();
}
@POST
- public Response createInstance(InstanceRequest request) {
- instanceService.createInstance(request.name, request.ssh, request.pwd, request.port, request.username, request.tpId);
+ @Path("/{id}/instance")
+ public Response createInstance(@PathParam("id") Long jiId,
+ @QueryParam("username") String username) {
+ jiService.createInstance(jiId, username);
return Response.ok().build();
}
+
+ @POST
+ @Path("/{id}/instance/container")
+ public Response createContainer(@PathParam("id") Long jiId,
+ @QueryParam("username") String username) {
+ return Response.ok(jiService.createContainer(jiId, username)).build();
+ }
+
+ @GET
+ @Path("/{id}/instance/container")
+ public Response getStatusContainer(@PathParam("id") Long jiId,
+ @QueryParam("username") String username) {
+ return Response.ok(jiService.getStatusContainer(jiId, username)).build();
+ }
}
diff --git a/src/main/java/fr/la_banquise/backend/rest/JiResource.java b/src/main/java/fr/la_banquise/backend/rest/JiResource.java
new file mode 100644
index 0000000..6cf75b0
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/rest/JiResource.java
@@ -0,0 +1,91 @@
+package fr.la_banquise.backend.rest;
+
+import fr.la_banquise.backend.data.model.Ji;
+import fr.la_banquise.backend.services.JiService;
+import io.quarkus.security.identity.SecurityIdentity;
+import jakarta.annotation.security.RolesAllowed;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import java.util.List;
+import java.util.Map;
+import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
+import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
+
+@Path("/api/ji")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class JiResource {
+
+ @Inject SecurityIdentity identity;
+
+ @Inject JiService jiService;
+
+ @GET
+ @Path("/listall")
+ @Produces(MediaType.APPLICATION_JSON)
+ @RolesAllowed("ROOT")
+ public Response listall() {
+ try {
+ List ji = jiService.getAllJiAdmin();
+ return Response.ok(ji).build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+
+ @POST
+ @Path("/create")
+ @RolesAllowed("ROOT")
+ public Response createJi(@QueryParam("name") String name,
+ @QueryParam("date") String date,
+ @QueryParam("respo") String respo,
+ @QueryParam("site") String name_site) {
+ try {
+ Ji jsp = jiService.createJi(name, date, respo, name_site);
+ return Response.ok(Map.of("created", jsp)).build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+
+ @GET
+ @Path("/getbyname")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response getJiByName(@QueryParam("name") String name) {
+ try {
+ Ji ji = jiService.getJiByName(name);
+ return Response.ok(ji.toString()).build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+
+ @DELETE
+ @Path("/del")
+ @RolesAllowed("ROOT")
+ @APIResponses({
+ @APIResponse(responseCode = "200", description = "Successfully deleted")
+ , @APIResponse(responseCode = "500",
+ description =
+ "Internal server error, usually site not found")
+ })
+ public Response
+ deleteJiByName(@QueryParam("name") String name) {
+ try {
+ jiService.deleteJi(name);
+ return Response.ok().build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+}
diff --git a/src/main/java/fr/la_banquise/backend/rest/SiteEndpoints.java b/src/main/java/fr/la_banquise/backend/rest/SiteEndpoints.java
new file mode 100644
index 0000000..2a11467
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/rest/SiteEndpoints.java
@@ -0,0 +1,130 @@
+package fr.la_banquise.backend.rest;
+
+import fr.la_banquise.backend.data.model.Site;
+import fr.la_banquise.backend.services.SiteService;
+import io.quarkus.security.Authenticated;
+import io.quarkus.security.identity.SecurityIdentity;
+import jakarta.annotation.security.RolesAllowed;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.*;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import java.util.List;
+import java.util.Map;
+import org.eclipse.microprofile.openapi.annotations.Operation;
+import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
+import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
+
+@Path("/api/sites")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class SiteEndpoints {
+
+ @Inject SecurityIdentity identity;
+
+ @Inject SiteService siteService;
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @RolesAllowed("ROOT")
+ @Operation(summary = "Lists all existing sites",
+ description = "Lists all sites. Root role required.")
+ @APIResponses({
+ @APIResponse(responseCode = "200", description = "Successfull")
+ , @APIResponse(responseCode = "500",
+ description = "Internal server error")
+ })
+ public Response
+ listall() {
+ try {
+ List sites = siteService.getAllSites();
+ return Response.ok(sites).build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+
+ @POST
+ @RolesAllowed("ROOT")
+ @Operation(summary = "Creates a site",
+ description = "Creates a site if no name is not a duplicate.")
+ @APIResponses({
+ @APIResponse(responseCode = "200", description = "Successfully created")
+ , @APIResponse(
+ responseCode = "500",
+ description =
+ "Internal server error, usually site name already taken")
+ })
+ public Response
+ createSite(@QueryParam("name") String name, @QueryParam("desc") String desc,
+ @QueryParam("address") String address) {
+ try {
+ String jsp = siteService.createSite(name, desc, address).toString();
+ return Response.ok(Map.of("created", jsp)).build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+
+ @GET
+ @Path("/{name}")
+ @Produces(MediaType.APPLICATION_JSON)
+ @Authenticated
+ @Operation(summary = "Gets a site with its name", description = "")
+ @APIResponses({
+ @APIResponse(responseCode = "200", description = "Site found")
+ , @APIResponse(responseCode = "500",
+ description =
+ "Internal server error, usually site not found")
+ })
+
+ public Response
+ getSiteByName(@PathParam("name") String name) {
+ try {
+ Site site = siteService.getSiteByName(name);
+ return Response.ok(site.toString()).build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+
+ @DELETE
+ @RolesAllowed("root")
+ @Operation(summary = "Deletes a site",
+ description =
+ "Permanently removes a site if no Ji are associated to it.")
+ @APIResponses({
+ @APIResponse(responseCode = "200", description = "Successfully deleted")
+ ,
+ @APIResponse(responseCode = "409",
+ description =
+ "Cannot delete site, it has associated JI records")
+ ,
+ @APIResponse(responseCode = "500",
+ description =
+ "Internal server error, usually site not found")
+ })
+ public Response
+ deleteSiteByName(@QueryParam("name") String name) {
+ try {
+ boolean retour = siteService.deleteSiteByName(name);
+ if (retour) {
+ return Response.ok().build();
+ }
+ return Response.status(409)
+ .entity(Map.of("Cannot delete site",
+ "it has associated JI records"))
+ .build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+}
diff --git a/src/main/java/fr/la_banquise/backend/rest/SujetEndpoints.java b/src/main/java/fr/la_banquise/backend/rest/SujetEndpoints.java
new file mode 100644
index 0000000..ce0e71b
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/rest/SujetEndpoints.java
@@ -0,0 +1,90 @@
+package fr.la_banquise.backend.rest;
+
+import fr.la_banquise.backend.rest.request.SujetRequest;
+import fr.la_banquise.backend.services.SujetService;
+import io.quarkus.security.Authenticated;
+import io.quarkus.security.identity.SecurityIdentity;
+import jakarta.annotation.security.RolesAllowed;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import java.util.Map;
+
+/**
+ * TpEndpoints
+ */
+@Path("/api/subjects")
+public class SujetEndpoints {
+
+ @Inject SecurityIdentity identity;
+
+ @Inject SujetService sujetService;
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Authenticated
+ public Response getAllSujetsRespo() {
+ if (identity.getRoles().contains("root")) {
+ return Response.ok(sujetService.getAllSujetsAdmin()).build();
+ }
+ return Response
+ .ok(sujetService.getAllSujetsRespo(
+ identity.getPrincipal().getName()))
+ .build();
+ }
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @RolesAllowed("ROOT")
+ public Response createSujet(SujetRequest sujet) {
+ return Response.ok(sujetService.createSujet(sujet)).build();
+ }
+
+ @POST
+ @Path("/respo")
+ @Produces(MediaType.APPLICATION_JSON)
+ @RolesAllowed("ROOT")
+ public Response addRespoSujet(@QueryParam("nameSujet") String nameSujet,
+ @QueryParam("nameUser") String nameUser) {
+ try {
+ if (sujetService.addRespo(nameSujet, nameUser)) {
+ return Response.ok("Respo added sucessfully.").build();
+ }
+ return Response.status(404)
+ .entity("Already respo of this subject")
+ .build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+
+ @DELETE
+ @Path("/respo")
+ @Produces(MediaType.APPLICATION_JSON)
+ @RolesAllowed("ROOT")
+ public Response rmRespoSujet(@QueryParam("nameSujet") String nameSujet,
+ @QueryParam("nameUser") String nameUser) {
+ try {
+ if (sujetService.rmRespo(nameSujet, nameUser)) {
+ return Response.ok("Respo removed sucessfully.").build();
+ }
+ return Response.status(404)
+ .entity("No corresponding respo not found (already removed ?)")
+ .build();
+ } catch (Exception e) {
+ return Response.status(500)
+ .entity(Map.of("error", e.getMessage()))
+ .build();
+ }
+ }
+}
diff --git a/src/main/java/fr/la_banquise/backend/rest/TpEndpoints.java b/src/main/java/fr/la_banquise/backend/rest/TpEndpoints.java
deleted file mode 100644
index edd058f..0000000
--- a/src/main/java/fr/la_banquise/backend/rest/TpEndpoints.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package fr.la_banquise.backend.rest;
-
-import fr.la_banquise.backend.services.TpService;
-import io.quarkus.security.identity.SecurityIdentity;
-import fr.la_banquise.backend.rest.request.TpRequest;
-import jakarta.annotation.security.RolesAllowed;
-import jakarta.inject.Inject;
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-
-/**
- * TpEndpoints
- */
-@Path("/api/tps")
-public class TpEndpoints {
-
- @Inject
- SecurityIdentity identity;
-
- @Inject
- TpService tpService;
-
- @GET
- @Produces(MediaType.APPLICATION_JSON)
- public Response getAllTps() {
- if (identity.getRoles().contains("root")) {
- return Response.ok(tpService.getAllTpsAdmin()).build();
- }
- return Response.ok(tpService.getAllTps(identity.getPrincipal().getName())).build();
- }
-
- @GET
- @Produces(MediaType.APPLICATION_JSON)
- @Path("{id}")
- public Response getTp(@PathParam("id") Long id) {
- if (identity.getRoles().contains("root")) {
- return Response.ok(tpService.getTpAdmin(id)).build();
- }
- return Response.ok(tpService.getTp(id, identity.getPrincipal().getName())).build();
- }
-
- @POST
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- @RolesAllowed("root")
- public Response createTp(TpRequest tp) {
- System.out.println(tp.date);
- return Response.ok(tpService.createTp(tp)).build();
- }
-}
diff --git a/src/main/java/fr/la_banquise/backend/rest/UserEndpoints.java b/src/main/java/fr/la_banquise/backend/rest/UserEndpoints.java
index f8cd258..d9c2d94 100644
--- a/src/main/java/fr/la_banquise/backend/rest/UserEndpoints.java
+++ b/src/main/java/fr/la_banquise/backend/rest/UserEndpoints.java
@@ -1,9 +1,15 @@
package fr.la_banquise.backend.rest;
-import fr.la_banquise.backend.rest.request.BulkUserRequest;
+import fr.la_banquise.backend.data.model.RolesAsso;
+import fr.la_banquise.backend.data.model.User;
+import fr.la_banquise.backend.rest.request.BulkUserDelRequest;
+import fr.la_banquise.backend.rest.request.BulkUserPostRequest;
import fr.la_banquise.backend.rest.request.UserRequest;
+import fr.la_banquise.backend.rest.response.BulkUserDelResponse;
+import fr.la_banquise.backend.rest.response.BulkUserPostResponse;
import fr.la_banquise.backend.rest.response.LoggedUserResponse;
import fr.la_banquise.backend.services.UserService;
+import io.quarkus.security.Authenticated;
import io.quarkus.security.identity.SecurityIdentity;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
@@ -13,67 +19,95 @@ import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
+import java.util.HashMap;
+import java.util.Map;
/**
* UserEndpoints
*/
-@Path("/api/users")
+@Path("/api/user")
@Produces(MediaType.APPLICATION_JSON)
public class UserEndpoints {
- @Inject
- SecurityIdentity identity;
+ @Inject SecurityIdentity identity;
- @Inject
- UserService userService;
+ @Inject UserService userService;
@GET
@Path("/me")
+ @Authenticated
public Response getCurrentUser() {
- LoggedUserResponse user = new LoggedUserResponse(identity.getPrincipal().getName(), identity.getRoles());
+ LoggedUserResponse user = new LoggedUserResponse(
+ identity.getPrincipal().getName(), identity.getRoles());
return Response.ok(user).build();
}
@GET
- @RolesAllowed("root")
- public Response getAllUsers() {
- return Response.ok(userService.getAllUsers()).build();
- }
-
- @GET
- @RolesAllowed("root")
+ @RolesAllowed("ROOT")
@Path("{id}")
public Response getUser(@PathParam("id") Long id) {
return Response.ok(userService.getUser(id)).build();
}
+ @GET
+ @RolesAllowed("ROOT")
+ @Path("{id}/roles")
+ public Response getRoles(@PathParam("id") Long userId) {
+ try {
+ User user = userService.getUser(userId);
+ return Response.ok(user.role).build();
+ } catch (Exception e) {
+ return Response.status(404)
+ .entity(Map.of("User or Role not found", e))
+ .build();
+ }
+ }
+
@POST
- @RolesAllowed("root")
+ @RolesAllowed("ROOT")
+ @Path("{id}/roles")
+ public Response addRole(@PathParam("id") Long userId,
+ @QueryParam("role") String role) {
+ try {
+ User user = userService.getUser(userId);
+ user.role.add(userService.fromString(role));
+ return Response.ok(user.role).build();
+ } catch (Exception e) {
+ return Response.status(404)
+ .entity(Map.of("User or Role not found", e))
+ .build();
+ }
+ }
+
+ @DELETE
+ @RolesAllowed("ROOT")
+ @Path("{id}/roles")
+ public Response removeRole(@PathParam("id") Long userId,
+ @QueryParam("role") String role) {
+ try {
+ User user = userService.getUser(userId);
+ user.role.remove(userService.fromString(role));
+ return Response.ok(user.role).build();
+ } catch (Exception e) {
+ return Response.status(404)
+ .entity(Map.of("User or Role not found", e))
+ .build();
+ }
+ }
+
+
+ @POST
+ @RolesAllowed("ROOT")
public Response createUser(UserRequest user) {
return Response.ok(userService.createUser(user)).build();
}
- @POST
- @RolesAllowed("root")
- @Path("/jdmi")
- public Response createJdmiUsers(BulkUserRequest users) {
- userService.createJdmiUser(users);
- return Response.ok().build();
- }
-
@DELETE
- @RolesAllowed("root")
- public Response deleteJDMI() {
- userService.deleteJDMI();
- return Response.ok().build();
- }
-
- @DELETE
- @RolesAllowed("root")
- @Path("/{id}")
- public Response deleteUser(@PathParam("id") Long id) {
+ @RolesAllowed("ROOT")
+ public Response deleteUser(@QueryParam("id") Long id) {
userService.deleteUser(id);
return Response.ok().build();
}
diff --git a/src/main/java/fr/la_banquise/backend/rest/UsersEndpoints.java b/src/main/java/fr/la_banquise/backend/rest/UsersEndpoints.java
new file mode 100644
index 0000000..e6fa0f2
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/rest/UsersEndpoints.java
@@ -0,0 +1,74 @@
+package fr.la_banquise.backend.rest;
+
+import fr.la_banquise.backend.data.model.RolesAsso;
+import fr.la_banquise.backend.data.model.User;
+import fr.la_banquise.backend.rest.request.BulkUserDelRequest;
+import fr.la_banquise.backend.rest.request.BulkUserPostRequest;
+import fr.la_banquise.backend.rest.request.UserRequest;
+import fr.la_banquise.backend.rest.response.BulkUserDelResponse;
+import fr.la_banquise.backend.rest.response.BulkUserPostResponse;
+import fr.la_banquise.backend.rest.response.LoggedUserResponse;
+import fr.la_banquise.backend.services.UserService;
+import io.quarkus.security.Authenticated;
+import io.quarkus.security.identity.SecurityIdentity;
+import jakarta.annotation.security.RolesAllowed;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * UserEndpoints
+ */
+@Path("/api/users")
+@Produces(MediaType.APPLICATION_JSON)
+public class UsersEndpoints {
+
+ @Inject SecurityIdentity identity;
+
+ @Inject UserService userService;
+
+ @GET
+ @RolesAllowed("ROOT")
+ public Response getAllUsers() {
+ return Response.ok(userService.getAllUsers()).build();
+ }
+
+ @POST
+ @RolesAllowed("ROOT") // TODO: respos JI doivent aussi pouvoir faire ca
+ // INFO: if response is empty => required associated jiId was not found in
+ // existing JIs
+ public Response createUsersBulk(BulkUserPostRequest users) {
+ BulkUserPostResponse response = userService.createUsers(
+ users);
+ if (response.success_names.size() == users.users.size())
+ return Response.ok().build();
+ return Response.status(202)
+ .entity(Map.of("These users were already created : ",
+ response.already_created))
+ .build();
+ }
+
+ @DELETE
+ @RolesAllowed("ROOT")
+ public Response deleteUserBulk(BulkUserDelRequest users) {
+ BulkUserDelResponse response = userService.deleteUsers(users);
+ if (response.success_names.size() == users.usernames.size())
+ return Response.ok().build();
+
+ Map retour = new HashMap();
+ for (int id = 0; id < response.failed_names.size(); id++) {
+ retour.put(response.failed_names.get(id),
+ response.failed_reasons.get(id));
+ }
+ return Response.status(202).entity(retour).build();
+ }
+}
diff --git a/src/main/java/fr/la_banquise/backend/rest/request/BulkUserDelRequest.java b/src/main/java/fr/la_banquise/backend/rest/request/BulkUserDelRequest.java
new file mode 100644
index 0000000..e247b79
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/rest/request/BulkUserDelRequest.java
@@ -0,0 +1,7 @@
+package fr.la_banquise.backend.rest.request;
+
+import java.util.List;
+
+public class BulkUserDelRequest {
+ public List usernames;
+}
diff --git a/src/main/java/fr/la_banquise/backend/rest/request/BulkUserRequest.java b/src/main/java/fr/la_banquise/backend/rest/request/BulkUserPostRequest.java
similarity index 50%
rename from src/main/java/fr/la_banquise/backend/rest/request/BulkUserRequest.java
rename to src/main/java/fr/la_banquise/backend/rest/request/BulkUserPostRequest.java
index cef006b..b179b27 100644
--- a/src/main/java/fr/la_banquise/backend/rest/request/BulkUserRequest.java
+++ b/src/main/java/fr/la_banquise/backend/rest/request/BulkUserPostRequest.java
@@ -2,11 +2,7 @@ package fr.la_banquise.backend.rest.request;
import java.util.List;
-/**
- * UserRequest
- */
-public class BulkUserRequest {
+public class BulkUserPostRequest {
public List users;
- public String password;
- public Long tpId;
+ public Long jiId;
}
diff --git a/src/main/java/fr/la_banquise/backend/rest/request/InstanceRequest.java b/src/main/java/fr/la_banquise/backend/rest/request/InstanceRequest.java
index a157c97..a3e6b62 100644
--- a/src/main/java/fr/la_banquise/backend/rest/request/InstanceRequest.java
+++ b/src/main/java/fr/la_banquise/backend/rest/request/InstanceRequest.java
@@ -1,16 +1,9 @@
package fr.la_banquise.backend.rest.request;
-import io.smallrye.common.constraint.Nullable;
-
/**
* InstanceRequest
*/
public class InstanceRequest {
- public String name;
- public String ssh;
- public String pwd;
public String username;
- public Long port;
- @Nullable
- public Long tpId;
+ public Long jiId;
}
diff --git a/src/main/java/fr/la_banquise/backend/rest/request/TpRequest.java b/src/main/java/fr/la_banquise/backend/rest/request/SujetRequest.java
similarity index 53%
rename from src/main/java/fr/la_banquise/backend/rest/request/TpRequest.java
rename to src/main/java/fr/la_banquise/backend/rest/request/SujetRequest.java
index e886261..5de582a 100644
--- a/src/main/java/fr/la_banquise/backend/rest/request/TpRequest.java
+++ b/src/main/java/fr/la_banquise/backend/rest/request/SujetRequest.java
@@ -3,12 +3,8 @@ package fr.la_banquise.backend.rest.request;
/**
* TpRequest
*/
-public class TpRequest {
+public class SujetRequest {
public String title;
public String description;
public String pdf;
- public Long duration;
- public String tools;
- public String difficulty;
- public String date;
}
diff --git a/src/main/java/fr/la_banquise/backend/rest/request/UserDelRequest.java b/src/main/java/fr/la_banquise/backend/rest/request/UserDelRequest.java
new file mode 100644
index 0000000..e1223b3
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/rest/request/UserDelRequest.java
@@ -0,0 +1,5 @@
+package fr.la_banquise.backend.rest.request;
+
+public class UserDelRequest {
+ public String name;
+}
diff --git a/src/main/java/fr/la_banquise/backend/rest/request/UserRequest.java b/src/main/java/fr/la_banquise/backend/rest/request/UserRequest.java
index f73a23e..9c2e690 100644
--- a/src/main/java/fr/la_banquise/backend/rest/request/UserRequest.java
+++ b/src/main/java/fr/la_banquise/backend/rest/request/UserRequest.java
@@ -1,14 +1,7 @@
package fr.la_banquise.backend.rest.request;
-/**
- * UserRequest
- */
public class UserRequest {
public String name;
public String email;
public String password;
- public String instance_name;
- public String instance_ssh;
- public Long instance_port;
- public String instance_pwd;
}
diff --git a/src/main/java/fr/la_banquise/backend/rest/response/BulkUserDelResponse.java b/src/main/java/fr/la_banquise/backend/rest/response/BulkUserDelResponse.java
new file mode 100644
index 0000000..cf74ffe
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/rest/response/BulkUserDelResponse.java
@@ -0,0 +1,19 @@
+package fr.la_banquise.backend.rest.response;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RegisterForReflection
+public class BulkUserDelResponse {
+ public List success_names;
+ public List failed_names;
+ public List failed_reasons;
+
+ public BulkUserDelResponse() {
+ this.success_names = new ArrayList();
+ this.failed_names = new ArrayList();
+ this.failed_reasons = new ArrayList();
+ }
+}
diff --git a/src/main/java/fr/la_banquise/backend/rest/response/BulkUserPostResponse.java b/src/main/java/fr/la_banquise/backend/rest/response/BulkUserPostResponse.java
new file mode 100644
index 0000000..8e02599
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/rest/response/BulkUserPostResponse.java
@@ -0,0 +1,17 @@
+package fr.la_banquise.backend.rest.response;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+
+@RegisterForReflection
+public class BulkUserPostResponse {
+ public List success_names;
+ public List already_created;
+
+ public BulkUserPostResponse() {
+ this.success_names = new ArrayList();
+ this.already_created = new ArrayList();
+ }
+}
diff --git a/src/main/java/fr/la_banquise/backend/rest/response/DashboardResponse.java b/src/main/java/fr/la_banquise/backend/rest/response/DashboardResponse.java
index 23c500b..fcc3fde 100644
--- a/src/main/java/fr/la_banquise/backend/rest/response/DashboardResponse.java
+++ b/src/main/java/fr/la_banquise/backend/rest/response/DashboardResponse.java
@@ -3,7 +3,7 @@ package fr.la_banquise.backend.rest.response;
import java.util.List;
import fr.la_banquise.backend.data.model.Instance;
-import fr.la_banquise.backend.data.model.Tp;
+import fr.la_banquise.backend.data.model.Sujet;
import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.AllArgsConstructor;
@@ -12,6 +12,6 @@ import lombok.AllArgsConstructor;
*/
@RegisterForReflection
public class DashboardResponse {
- public List tps;
+ public List tps;
public List instances;
}
diff --git a/src/main/java/fr/la_banquise/backend/rest/response/LoggedUserResponse.java b/src/main/java/fr/la_banquise/backend/rest/response/LoggedUserResponse.java
index cccf399..aad3ee9 100644
--- a/src/main/java/fr/la_banquise/backend/rest/response/LoggedUserResponse.java
+++ b/src/main/java/fr/la_banquise/backend/rest/response/LoggedUserResponse.java
@@ -1,16 +1,20 @@
package fr.la_banquise.backend.rest.response;
-import java.util.Set;
-
import io.quarkus.runtime.annotations.RegisterForReflection;
+import java.util.Set;
import lombok.AllArgsConstructor;
/**
* LoggedUserResponse
*/
-@AllArgsConstructor
+//@AllArgsConstructor
@RegisterForReflection
public class LoggedUserResponse {
public String username;
public Set roles;
+
+ public LoggedUserResponse(String username, Set roles) {
+ this.username = username;
+ this.roles = roles;
+ }
}
diff --git a/src/main/java/fr/la_banquise/backend/rest/response/PracticalResponse.java b/src/main/java/fr/la_banquise/backend/rest/response/PracticalResponse.java
index 762535c..766804f 100644
--- a/src/main/java/fr/la_banquise/backend/rest/response/PracticalResponse.java
+++ b/src/main/java/fr/la_banquise/backend/rest/response/PracticalResponse.java
@@ -1,7 +1,9 @@
package fr.la_banquise.backend.rest.response;
+import fr.la_banquise.backend.data.model.User;
import io.quarkus.runtime.annotations.RegisterForReflection;
import io.smallrye.common.constraint.Nullable;
+import java.util.List;
import lombok.AllArgsConstructor;
/**
@@ -13,15 +15,26 @@ public class PracticalResponse {
public String name;
public String description;
public String pdfLink;
- public String respo;
- public String endDate;
+ public List respos;
- @Nullable
- public String instanceName;
- @Nullable
- public String pwd;
- @Nullable
- public String ssh;
- @Nullable
- public Long port;
+ @Nullable public String instanceName;
+ @Nullable public String pwd;
+ @Nullable public String ssh;
+ @Nullable public Long port;
+
+ /*public PracticalResponse(String name, String description, String pdfLink,
+ String respo, String date,
+ @Nullable String InstanceName,
+ @Nullable String pwd, @Nullable String ssh,
+ @Nullable Long port) {
+ this.name = name;
+ this.endDate = date;
+ this.description = description;
+ this.pdfLink = pdfLink;
+ this.respo = respo;
+ this.instanceName = InstanceName;
+ this.port = port;
+ this.ssh = ssh;
+ this.pwd = pwd;
+ }*/
}
diff --git a/src/main/java/fr/la_banquise/backend/services/ContainerService.java b/src/main/java/fr/la_banquise/backend/services/ContainerService.java
new file mode 100644
index 0000000..3c2565d
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/services/ContainerService.java
@@ -0,0 +1,179 @@
+/*package fr.la_banquise.backend.services;
+
+import com.github.dockerjava.api.DockerClient;
+import com.github.dockerjava.api.command.CreateContainerResponse;
+import com.github.dockerjava.api.command.InspectContainerResponse;
+import com.github.dockerjava.api.model.ContainerPort;
+import com.github.dockerjava.api.model.ExposedPort;
+import com.github.dockerjava.api.model.HostConfig;
+import com.github.dockerjava.api.model.PortBinding;
+import com.github.dockerjava.api.model.Ports;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@ApplicationScoped
+public class ContainerService {
+
+ @Inject DockerClient dockerClient;
+
+ public String createAndStartNginx() {
+ ExposedPort tcp80 = ExposedPort.tcp(80);
+
+ Ports portBindings = new Ports();
+ portBindings.bind(tcp80, Ports.Binding.bindPort(8081));
+
+ HostConfig hostConfig =
+ HostConfig.newHostConfig().withPortBindings(portBindings);
+ Map labels = new HashMap<>();
+ labels.put("test", "banquise");
+ labels.put("environment", "development");
+ labels.put("version", "1.0");
+ labels.put("created-by", "java-docker-api");
+
+ CreateContainerResponse container =
+ dockerClient.createContainerCmd("nginx:latest")
+ .withName("my-nginx")
+ .withLabels(labels)
+ .withExposedPorts(tcp80)
+ .withHostConfig(hostConfig)
+ .exec();
+
+ dockerClient.startContainerCmd(container.getId()).exec();
+ return container.getId();
+ }
+
+ /*public Container createContainer() {
+ Container container =
+ dockerClient
+ .createContainerCmd("nginx:latest")
+
+ // dockerClient.startContainerCmd(container.getId()).exec();
+ return container.createContainer();
+ }
+ /*
+ public String listAllContainers() {
+ StringBuilder json = new StringBuilder();
+ List containers = dockerClient.listContainersCmd()
+ .withShowAll(true)
+ .exec();
+
+ json.append("[");
+
+ for (int i = 0; i < containers.size(); i++) {
+ Container container = containers.get(i);
+
+ json.append("{");
+ json.append("\"name\":\"").append(container.getNames()[0].substring(1)).append("\",");
+ json.append("\"id\":\"").append(container.getId()).append("\",");
+ json.append("\"image\":\"").append(container.getImage()).append("\",");
+ json.append("\"status\":\"").append(container.getStatus()).append("\",");
+
+ // Ports
+ InspectContainerResponse inspectResponse =
+ dockerClient.inspectContainerCmd(container.getId()).exec();
+ json.append("\"ports\":[");
+ if (container.getPorts() != null && container.getPorts().length > 0) {
+ for (int j = 0; j < .length; j+=2) {
+ ContainerPort port = container.getPorts()[j];
+ json.append("[\"");
+ json.append(port.getPrivatePort()).append("->").append(port.getPublicPort()).append("/"+port.getType()+"\",\"");
+ json.append(port.getIp()).append(",").append((container.getPorts()[j+1]).getIp());
+ if (port.getType() != null) {
+ json.append("/").append(port.getType());
+ }
+ if (port.getPublicPort() != null) {
+ json.append("->").append(port.getPublicPort());
+ }*
+ json.append("\"]");
+ if (j < container.getPorts().length - 2) {
+ json.append(",");
+ }
+ }
+ }
+ json.append("]");
+
+ // Ports
+ String ports = "[]";
+ try {
+ InspectContainerResponse inspectResponse =
+ dockerClient.inspectContainerCmd(container.getId()).exec(); if
+ (inspectResponse.getConfig().getExposedPorts() != null) { ports =
+ inspectResponse.getConfig().getExposedPorts().toString();
+ }
+ } catch (Exception e) {
+ // Fallback vers les ports runtime si inspect échoue
+ if (container.getPorts() != null && container.getPorts().length
+ > 0) { ports = java.util.Arrays.toString(container.getPorts());
+ }
+ }
+ json.append("\"ports\":\"").append(ports).append("\"");
+ json.append("}");
+ if (i < containers.size() - 1) {
+ json.append(",");
+ }
+
+ json.append("}");
+
+ if (i < containers.size() - 1) {
+ json.append(",");
+ }
+ }
+
+ json.append("]");
+ return json.toString();
+ }
+ public String listAllContainers() {
+ StringBuilder json = new StringBuilder();
+ List containers = dockerClient.listContainersCmd()
+ .withShowAll(true)
+ .exec();
+ json.append("[");
+ for (int i = 0; i < containers.size(); i++) {
+ Container container = containers.get(i);
+ // Ports
+ List portsList = new ArrayList<>();
+ try {
+ var inspectResponse =
+ dockerClient.inspectContainerCmd(container.getId()).exec(); if
+ (inspectResponse.getConfig().getExposedPorts() != null) { var exposedPorts =
+ inspectResponse.getConfig().getExposedPorts(); int count = 0; for (var port
+ : exposedPorts) { if (count > 0) portsList.append(",");
+ portsList.append(String.format("\"%s\"",
+ port.toString())); count = 1;
+ }
+ portsList.append("]");
+ ports = portsList.toString();
+ }
+ } catch (Exception e) {
+ // Fallback vers les ports runtime si inspect échoue
+ if (container.getPorts() != null && container.getPorts().length
+ > 0) { ports = java.util.Arrays.toString(container.getPorts());
+ }
+ }
+
+ //json.append(containerJson);
+
+ if (i < containers.size() - 1) {
+ json.append(",");
+ }
+ }
+ json.append("]");
+ return json.toString();
+ }/
+ public String listAllContainers() { return ""; }
+
+ public void start(String containerId) {
+ dockerClient.startContainerCmd(containerId).exec();
+ }
+
+ public void stop(String containerId) {
+ dockerClient.stopContainerCmd(containerId).exec();
+ }
+
+ public void remove(String containerId) {
+ dockerClient.removeContainerCmd(containerId).exec();
+ }
+}*/
diff --git a/src/main/java/fr/la_banquise/backend/services/DockerService.java b/src/main/java/fr/la_banquise/backend/services/DockerService.java
new file mode 100644
index 0000000..7456d54
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/services/DockerService.java
@@ -0,0 +1,192 @@
+package fr.la_banquise.backend.services;
+
+import com.github.dockerjava.api.DockerClient;
+import com.github.dockerjava.api.command.CreateContainerResponse;
+import com.github.dockerjava.api.command.InspectContainerResponse;
+import com.github.dockerjava.api.model.Container;
+import com.github.dockerjava.api.model.ContainerPort;
+import com.github.dockerjava.api.model.ExposedPort;
+import com.github.dockerjava.api.model.HostConfig;
+import com.github.dockerjava.api.model.PortBinding;
+import com.github.dockerjava.api.model.Ports;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@ApplicationScoped
+public class DockerService {
+
+ @Inject DockerClient dockerClient;
+
+ public String createAndStartNginx() {
+ ExposedPort tcp80 = ExposedPort.tcp(80);
+
+ Ports portBindings = new Ports();
+ portBindings.bind(tcp80, Ports.Binding.bindPort(8081));
+
+ HostConfig hostConfig =
+ HostConfig.newHostConfig().withPortBindings(portBindings);
+ Map labels = new HashMap<>();
+ labels.put("test", "banquise");
+ labels.put("environment", "development");
+ labels.put("version", "1.0");
+ labels.put("created-by", "java-docker-api");
+
+ CreateContainerResponse container =
+ dockerClient.createContainerCmd("nginx:latest")
+ .withName("my-nginx")
+ .withLabels(labels)
+ .withExposedPorts(tcp80)
+ .withHostConfig(hostConfig)
+ .exec();
+
+ dockerClient.startContainerCmd(container.getId()).exec();
+ return container.getId();
+ }
+
+ public String createContainer(String containerName, int port) {
+ StringBuilder result = new StringBuilder();
+ ExposedPort tcpSsh = ExposedPort.tcp(80);
+
+ Ports portBindings = new Ports();
+ portBindings.bind(tcpSsh, Ports.Binding.bindPort(port));
+
+ HostConfig hostConfig =
+ HostConfig.newHostConfig().withPortBindings(portBindings);
+
+ CreateContainerResponse container =
+ dockerClient.createContainerCmd("nginx:latest")
+ .withName(containerName)
+ .withExposedPorts(tcpSsh)
+ .withHostConfig(hostConfig)
+ .exec();
+
+ // dockerClient.startContainerCmd(container.getId()).exec();
+ return container.getId();
+ }
+ /*
+ public String listAllContainers() {
+ StringBuilder json = new StringBuilder();
+ List containers = dockerClient.listContainersCmd()
+ .withShowAll(true)
+ .exec();
+
+ json.append("[");
+
+ for (int i = 0; i < containers.size(); i++) {
+ Container container = containers.get(i);
+
+ json.append("{");
+ json.append("\"name\":\"").append(container.getNames()[0].substring(1)).append("\",");
+ json.append("\"id\":\"").append(container.getId()).append("\",");
+ json.append("\"image\":\"").append(container.getImage()).append("\",");
+ json.append("\"status\":\"").append(container.getStatus()).append("\",");
+
+ // Ports
+ InspectContainerResponse inspectResponse =
+ dockerClient.inspectContainerCmd(container.getId()).exec();
+ json.append("\"ports\":[");
+ if (container.getPorts() != null && container.getPorts().length > 0) {
+ for (int j = 0; j < .length; j+=2) {
+ ContainerPort port = container.getPorts()[j];
+ json.append("[\"");
+ json.append(port.getPrivatePort()).append("->").append(port.getPublicPort()).append("/"+port.getType()+"\",\"");
+ json.append(port.getIp()).append(",").append((container.getPorts()[j+1]).getIp());
+ if (port.getType() != null) {
+ json.append("/").append(port.getType());
+ }
+ if (port.getPublicPort() != null) {
+ json.append("->").append(port.getPublicPort());
+ }*
+ json.append("\"]");
+ if (j < container.getPorts().length - 2) {
+ json.append(",");
+ }
+ }
+ }
+ json.append("]");
+
+ // Ports
+ String ports = "[]";
+ try {
+ InspectContainerResponse inspectResponse =
+ dockerClient.inspectContainerCmd(container.getId()).exec(); if
+ (inspectResponse.getConfig().getExposedPorts() != null) { ports =
+ inspectResponse.getConfig().getExposedPorts().toString();
+ }
+ } catch (Exception e) {
+ // Fallback vers les ports runtime si inspect échoue
+ if (container.getPorts() != null && container.getPorts().length
+ > 0) { ports = java.util.Arrays.toString(container.getPorts());
+ }
+ }
+ json.append("\"ports\":\"").append(ports).append("\"");
+ json.append("}");
+ if (i < containers.size() - 1) {
+ json.append(",");
+ }
+
+ json.append("}");
+
+ if (i < containers.size() - 1) {
+ json.append(",");
+ }
+ }
+
+ json.append("]");
+ return json.toString();
+ }
+ public String listAllContainers() {
+ StringBuilder json = new StringBuilder();
+ List containers = dockerClient.listContainersCmd()
+ .withShowAll(true)
+ .exec();
+ json.append("[");
+ for (int i = 0; i < containers.size(); i++) {
+ Container container = containers.get(i);
+ // Ports
+ List portsList = new ArrayList<>();
+ try {
+ var inspectResponse =
+ dockerClient.inspectContainerCmd(container.getId()).exec(); if
+ (inspectResponse.getConfig().getExposedPorts() != null) { var exposedPorts =
+ inspectResponse.getConfig().getExposedPorts(); int count = 0; for (var port
+ : exposedPorts) { if (count > 0) portsList.append(",");
+ portsList.append(String.format("\"%s\"",
+ port.toString())); count = 1;
+ }
+ portsList.append("]");
+ ports = portsList.toString();
+ }
+ } catch (Exception e) {
+ // Fallback vers les ports runtime si inspect échoue
+ if (container.getPorts() != null && container.getPorts().length
+ > 0) { ports = java.util.Arrays.toString(container.getPorts());
+ }
+ }
+
+ //json.append(containerJson);
+
+ if (i < containers.size() - 1) {
+ json.append(",");
+ }
+ }
+ json.append("]");
+ return json.toString();
+ }*/
+ public String listAllContainers() { return ""; }
+
+ public void start(String containerId) {
+ dockerClient.startContainerCmd(containerId).exec();
+ }
+
+ public void stop(String containerId) {
+ dockerClient.stopContainerCmd(containerId).exec();
+ }
+
+ public void remove(String containerId) {
+ dockerClient.removeContainerCmd(containerId).exec();
+ }
+}
diff --git a/src/main/java/fr/la_banquise/backend/services/InstanceService.java b/src/main/java/fr/la_banquise/backend/services/InstanceService.java
index 25a123f..b02d6a2 100644
--- a/src/main/java/fr/la_banquise/backend/services/InstanceService.java
+++ b/src/main/java/fr/la_banquise/backend/services/InstanceService.java
@@ -1,81 +1,149 @@
package fr.la_banquise.backend.services;
-import java.util.List;
+import com.github.dockerjava.api.DockerClient;
+import com.github.dockerjava.api.command.CreateContainerResponse;
+import com.github.dockerjava.api.command.InspectContainerResponse;
+import com.github.dockerjava.api.model.ExposedPort;
+import com.github.dockerjava.api.model.HostConfig;
+import com.github.dockerjava.api.model.Ports;
import fr.la_banquise.backend.data.model.Instance;
-import fr.la_banquise.backend.data.model.Tp;
+import fr.la_banquise.backend.data.model.Ji;
import fr.la_banquise.backend.data.model.User;
import fr.la_banquise.backend.data.repository.InstanceRepository;
-import fr.la_banquise.backend.data.repository.TpRepository;
+import fr.la_banquise.backend.data.repository.JiRepository;
import fr.la_banquise.backend.data.repository.UserRepository;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
/**
* InstanceService
*/
@ApplicationScoped
public class InstanceService {
- @Inject
- InstanceRepository instanceRepository;
+ @Inject InstanceRepository instanceRepository;
- @Inject
- UserRepository userRepository;
+ @Inject UserRepository userRepository;
- @Inject
- TpRepository tpRepository;
+ @Inject JiRepository jiRepository;
+
+ @Inject DockerClient dockerClient;
public List getAllInstances() {
return instanceRepository.findAll().list();
}
- public List getAllInstances(String username) {
+ public List getInstancesByOwner(String username) {
User user = userRepository.findByName(username);
- return instanceRepository.find("user", user).list();
+ return instanceRepository.find("owner", user).list();
}
public Instance getInstance(Long id) {
return instanceRepository.findById(id);
}
+ public InspectContainerResponse.ContainerState getStatusContainer(Long id) {
+ Instance instance = instanceRepository.findById(id);
+ InspectContainerResponse container =
+ dockerClient.inspectContainerCmd(instance.name).exec();
+ return container.getState();
+ }
+
@Transactional
- public Instance createInstance(String name, String ssh, String pwd, Long port, String username, Long tpId) {
+ public Instance createInstance(String username, Ji ji) {
User user = userRepository.findByName(username);
- Tp tp = tpRepository.findById(tpId);
- Instance instance = new Instance(name, ssh, pwd, port, user, tp);
+ String name = username + "-" + ji.id;
+ int port = getFreePort(1).iterator().next();
+ Instance instance = new Instance(name, port, user);
instanceRepository.persist(instance);
return instance;
}
- @Transactional
- public Instance createInstance(String name, String ssh, String pwd, Long port, User user, Long tpId) {
- Tp tp = tpRepository.findById(tpId);
- Instance instance = new Instance(name, ssh, pwd, port, user, tp);
- instanceRepository.persist(instance);
- return instance;
+ public String createContainer(Long instanceId) {
+ Instance instance = instanceRepository.findById(instanceId);
+
+ ExposedPort tcpSsh = ExposedPort.tcp(22);
+
+ Ports portBindings = new Ports();
+ portBindings.bind(tcpSsh, Ports.Binding.bindPort(instance.port));
+
+ HostConfig hostConfig =
+ HostConfig.newHostConfig().withPortBindings(portBindings);
+ Map labels = new HashMap<>();
+ labels.put("test", "banquise");
+ labels.put("environment", "development");
+ labels.put("version", "1.0");
+ labels.put("created-by", "java-docker-api");
+
+ CreateContainerResponse container =
+ dockerClient.createContainerCmd("nginx:latest")
+ .withName(instance.name)
+ .withLabels(labels)
+ .withExposedPorts(tcpSsh)
+ .withHostConfig(hostConfig)
+ .exec();
+
+ return container.getId();
+ }
+
+ public boolean deleteContainer(String containerName) {
+ try {
+ dockerClient.removeContainerCmd(containerName).exec();
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
}
@Transactional
public boolean deleteInstance(Long id) {
- return instanceRepository.deleteById(id);
- }
-
- @Transactional
- public boolean deleteAllInstances() {
- instanceRepository.deleteAll();
- return true;
- }
-
- @Transactional
- public void deleteJDMIInstances() {
- instanceRepository.deleteAll();
- }
-
- @Transactional
- public Instance updateInstance(Long id) {
Instance instance = instanceRepository.findById(id);
- return instance;
+ if (!containerExists(instance.name))
+ return instanceRepository.deleteById(id);
+ return false;
+ }
+
+ public boolean containerExists(String containerName) {
+ try {
+ dockerClient.inspectContainerCmd(containerName).exec();
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ public Set getUsedPorts() {
+ Set retour = new HashSet<>();
+ List allInstances = getAllInstances();
+ for (Instance instance : allInstances) {
+ retour.add(instance.port);
+ }
+
+ return retour;
+ }
+
+ public Set getFreePort(int nbPortsNeeded) {
+ Set used = getUsedPorts();
+ Set retour = new HashSet<>();
+
+ int port = 40000;
+
+ // max 1000 ports used at a same time
+ while (retour.size() < nbPortsNeeded && port < 41000) {
+ if (!used.contains(port)) {
+ retour.add(port);
+ }
+ port++;
+ }
+
+ return retour;
}
}
diff --git a/src/main/java/fr/la_banquise/backend/services/JiService.java b/src/main/java/fr/la_banquise/backend/services/JiService.java
new file mode 100644
index 0000000..536e85e
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/services/JiService.java
@@ -0,0 +1,102 @@
+package fr.la_banquise.backend.services;
+
+import fr.la_banquise.backend.data.model.Instance;
+import fr.la_banquise.backend.data.model.Ji;
+import fr.la_banquise.backend.data.model.Site;
+import fr.la_banquise.backend.data.model.User;
+import fr.la_banquise.backend.data.repository.JiRepository;
+import fr.la_banquise.backend.data.repository.UserRepository;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.transaction.Transactional;
+import jakarta.ws.rs.core.SecurityContext;
+import java.util.List;
+
+@ApplicationScoped
+public class JiService {
+
+ @Inject JiRepository jiRepository;
+ @Inject UserRepository userRepository;
+ @Inject SiteService siteService;
+ @Inject InstanceService instanceService;
+ @Inject SecurityContext security;
+
+ @Transactional
+ public Ji createJi(String name, String description, String address,
+ String site_name) {
+ Site site = siteService.getSiteByName(site_name);
+ User currentUser =
+ userRepository.findByName(security.getUserPrincipal().getName());
+ Ji ji = new Ji(name, description, List.of(currentUser), "date", site);
+ jiRepository.persist(ji);
+ siteService.addJi(site, ji);
+ return ji;
+ }
+
+ public List getAllJiAdmin() { return jiRepository.listAll(); }
+
+ public List getAllJiRespo(String username) {
+ User user = userRepository.findByName(username);
+ return user.jiRespo;
+ }
+
+ public Ji getJiByName(String name) {
+ return jiRepository.find("name", name).firstResult();
+ }
+
+ public Ji getJiById(Long id) { return jiRepository.findById(id); }
+
+ @Transactional
+ public void deleteJi(Long id) {
+ Ji ji = getJiById(id);
+ siteService.removeJi(ji.site, ji);
+ jiRepository.deleteById(id);
+ }
+
+ @Transactional
+ public void deleteJi(String name) {
+ Ji ji = getJiByName(name);
+ siteService.removeJi(ji.site, ji);
+ jiRepository.delete(ji);
+ }
+
+ @Transactional
+ public Instance createInstance(Long id, String username) {
+ Ji ji = jiRepository.findById(id);
+ Instance instance = instanceService.createInstance(username, ji);
+ ji.instances.add(instance);
+ return instance;
+ }
+
+ @Transactional
+ public String createContainer(Long id, String username) {
+ Ji ji = jiRepository.findById(id);
+ String retour = "";
+ for (Instance instance : ji.instances) {
+
+ if (instance.name.equals(username + "-" + id)) {
+ retour = instanceService.createContainer(instance.id);
+ break;
+ }
+ }
+ if (retour == "")
+ throw new Error("instance or container not found");
+
+ return retour;
+ }
+
+ public String getStatusContainer(Long id, String username) {
+ Ji ji = jiRepository.findById(id);
+ String retour = "";
+ for (Instance instance : ji.instances) {
+ if (instance.name.equals(username + "-" + id)) {
+ retour =
+ instanceService.getStatusContainer(instance.id).toString();
+ break;
+ }
+ }
+ if (retour == "")
+ throw new Error("instance or container not found");
+ return retour;
+ }
+}
diff --git a/src/main/java/fr/la_banquise/backend/services/SiteService.java b/src/main/java/fr/la_banquise/backend/services/SiteService.java
new file mode 100644
index 0000000..816d277
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/services/SiteService.java
@@ -0,0 +1,65 @@
+package fr.la_banquise.backend.services;
+
+import fr.la_banquise.backend.data.model.Ji;
+import fr.la_banquise.backend.data.model.Site;
+import fr.la_banquise.backend.data.repository.SiteRepository;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.transaction.Transactional;
+import java.util.List;
+
+@ApplicationScoped
+public class SiteService {
+
+ @Inject SiteRepository siteRepository;
+
+ @Transactional
+ public Site createSite(String name, String description, String address) {
+ Site site = new Site(name, description, address);
+ siteRepository.persist(site);
+ return site;
+ }
+
+ /*@Transactional
+ public List saveAllSites(List sites) {
+ sites.forEach(site -> siteRepository.persist(site));
+ return sites;
+ }*/
+
+ public List getAllSites() { return siteRepository.listAll(); }
+
+ public Site getSiteByName(String name) {
+ return siteRepository.find("name", name).firstResult();
+ }
+
+ public Site getSiteById(Long id) { return siteRepository.findById(id); }
+
+ @Transactional
+ public void addJi(Site site, Ji ji) {
+ site.jiInSite.add(ji);
+ }
+
+ @Transactional
+ public void removeJi(Site site, Ji ji) {
+ site.jiInSite.remove(ji);
+ }
+
+ @Transactional
+ public boolean deleteSiteById(Long id) {
+ if (getSiteById(id).jiInSite.isEmpty()) {
+ siteRepository.deleteById(id);
+ return true;
+ }
+ return false;
+ }
+
+ @Transactional
+ public boolean deleteSiteByName(String name) {
+ Site site = getSiteByName(name);
+ if (site.jiInSite.isEmpty()) {
+ siteRepository.delete(site);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/fr/la_banquise/backend/services/SujetService.java b/src/main/java/fr/la_banquise/backend/services/SujetService.java
new file mode 100644
index 0000000..42e7f1f
--- /dev/null
+++ b/src/main/java/fr/la_banquise/backend/services/SujetService.java
@@ -0,0 +1,98 @@
+package fr.la_banquise.backend.services;
+
+import fr.la_banquise.backend.data.model.Sujet;
+import fr.la_banquise.backend.data.model.User;
+import fr.la_banquise.backend.data.repository.InstanceRepository;
+import fr.la_banquise.backend.data.repository.SujetRepository;
+import fr.la_banquise.backend.data.repository.UserRepository;
+import fr.la_banquise.backend.rest.request.SujetRequest;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.transaction.Transactional;
+import jakarta.ws.rs.core.SecurityContext;
+import java.util.List;
+
+/**
+ * TpService
+ */
+@ApplicationScoped
+public class SujetService {
+
+ @Inject SecurityContext security;
+
+ @Inject SujetRepository sujetRepository;
+
+ @Inject UserRepository userRepository;
+
+ @Inject InstanceRepository instanceRepository;
+
+ public List getAllSujetsAdmin() { return sujetRepository.listAll(); }
+
+ public List getAllSujetsRespo(String username) {
+ User user = userRepository.findByName(username);
+ return user.sujetRespo;
+ }
+
+ /*public PracticalResponse getTp(Long id, String username) {
+ User user = userRepository.findByName(username);
+ Sujet sujet = sujetRepository.findById(id);
+ Instance instance =
+ instanceRepository.find("user = ?1 AND tp = ?2", user, sujet)
+ .firstResult();
+ PracticalResponse res = new PracticalResponse(
+ sujet.name, sujet.description, sujet.pdfLink, sujet.respos,
+ instance.name, instance.pwd, instance.ssh, instance.port);
+ return res;
+ }
+
+ /*public PracticalResponse getTpAdmin(Long id) {
+ Sujet sujet = sujetRepository.findById(id);
+ return new PracticalResponse(sujet.name, sujet.description,
+ sujet.pdfLink, sujet.respos, "", "", "",
+ 0L);
+ }*/
+
+ @Transactional
+ public Sujet createSujet(SujetRequest requestSujet) {
+ User currentUser =
+ userRepository.findByName(security.getUserPrincipal().getName());
+ Sujet sujet = new Sujet(requestSujet.title, requestSujet.description,
+ requestSujet.pdf, List.of(currentUser));
+ sujetRepository.persist(sujet);
+ return sujet;
+ }
+
+ @Transactional
+ public void deleteSujet(Long id) {
+ sujetRepository.deleteById(id);
+ }
+
+ @Transactional
+ public boolean addRespo(String nameSujet, String nameUser) {
+ User user = userRepository.find("name", nameUser).firstResult();
+ Sujet sujet = sujetRepository.find("name", nameSujet).firstResult();
+ if (!sujet.respos.contains(user)) {
+ sujet.respos.add(user);
+ return true;
+ }
+ return false;
+ }
+
+ @Transactional
+ public boolean rmRespo(String nameSujet, String nameUser) {
+ User user = userRepository.find("name", nameUser).firstResult();
+ Sujet sujet = sujetRepository.find("name", nameSujet).firstResult();
+ if (sujet.respos.contains(user)) {
+ sujet.respos.remove(user);
+ return true;
+ }
+ return false;
+ }
+ /*
+ * TODO: Seuls les respos du sujet et root doivent pouvoir avoir acces
+ * @Transactional
+ public Sujet updateSujet(Long id) {
+ Sujet sujet = sujetRepository.findById(id);
+ return sujet;
+ }*/
+}
diff --git a/src/main/java/fr/la_banquise/backend/services/TpService.java b/src/main/java/fr/la_banquise/backend/services/TpService.java
deleted file mode 100644
index decb756..0000000
--- a/src/main/java/fr/la_banquise/backend/services/TpService.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package fr.la_banquise.backend.services;
-
-import java.text.Collator;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import fr.la_banquise.backend.data.model.Instance;
-import fr.la_banquise.backend.data.model.Tp;
-import fr.la_banquise.backend.data.model.User;
-import fr.la_banquise.backend.data.repository.InstanceRepository;
-import fr.la_banquise.backend.data.repository.TpRepository;
-import fr.la_banquise.backend.data.repository.UserRepository;
-import fr.la_banquise.backend.rest.request.TpRequest;
-import fr.la_banquise.backend.rest.response.PracticalResponse;
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Inject;
-import jakarta.transaction.Transactional;
-import jakarta.ws.rs.core.SecurityContext;
-
-/**
- * TpService
- */
-@ApplicationScoped
-public class TpService {
-
- @Inject
- SecurityContext security;
-
- @Inject
- TpRepository tpRepository;
-
- @Inject
- UserRepository userRepository;
-
- @Inject
- InstanceRepository instanceRepository;
-
- public List getAllTpsAdmin() {
- return tpRepository.listAll();
- }
-
- public List getAllTps(String username) {
- User user = userRepository.findByName(username);
- List instances = instanceRepository.find("user = ?1 AND tp IS NOT NULL", user).list();
- return tpRepository.find("id in ?1", instances.stream().map(i -> i.tp.id).collect(Collectors.toList())).list();
- }
-
- public PracticalResponse getTp(Long id, String username) {
- User user = userRepository.findByName(username);
- Tp tp = tpRepository.findById(id);
- Instance instance = instanceRepository.find("user = ?1 AND tp = ?2", user, tp).firstResult();
- PracticalResponse res = new PracticalResponse(tp.name, tp.description, tp.pdfLink, tp.respo, tp.date,
- instance.name,
- instance.pwd, instance.ssh, instance.port);
- return res;
- }
-
- public PracticalResponse getTpAdmin(Long id) {
- Tp tp = tpRepository.findById(id);
- return new PracticalResponse(tp.name, tp.description, tp.pdfLink, tp.respo, tp.date,
- "",
- "", "", 0L);
- }
-
- @Transactional
- public Tp createTp(TpRequest requestTp) {
- Tp tp = new Tp(requestTp.title, requestTp.description, requestTp.pdf, security.getUserPrincipal().getName(),
- requestTp.date);
- tpRepository.persist(tp);
- return tp;
- }
-
- @Transactional
- public void deleteTp(Long id) {
- tpRepository.deleteById(id);
- }
-
- @Transactional
- public Tp updateTp(Long id) {
- Tp tp = tpRepository.findById(id);
- return tp;
- }
-}
diff --git a/src/main/java/fr/la_banquise/backend/services/UserService.java b/src/main/java/fr/la_banquise/backend/services/UserService.java
index a71e013..c22ae1b 100644
--- a/src/main/java/fr/la_banquise/backend/services/UserService.java
+++ b/src/main/java/fr/la_banquise/backend/services/UserService.java
@@ -1,19 +1,21 @@
package fr.la_banquise.backend.services;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.hibernate.annotations.TypeRegistration;
-
-import fr.la_banquise.backend.data.model.Instance;
+import fr.la_banquise.backend.data.model.RolesAsso;
import fr.la_banquise.backend.data.model.User;
+import fr.la_banquise.backend.data.repository.JiRepository;
import fr.la_banquise.backend.data.repository.UserRepository;
-import fr.la_banquise.backend.rest.request.BulkUserRequest;
+import fr.la_banquise.backend.rest.request.BulkUserDelRequest;
+import fr.la_banquise.backend.rest.request.BulkUserPostRequest;
+import fr.la_banquise.backend.rest.request.UserDelRequest;
import fr.la_banquise.backend.rest.request.UserRequest;
+import fr.la_banquise.backend.rest.response.BulkUserDelResponse;
+import fr.la_banquise.backend.rest.response.BulkUserPostResponse;
import io.quarkus.elytron.security.common.BcryptUtil;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
+import java.util.ArrayList;
+import java.util.List;
/**
* UserService
@@ -21,23 +23,19 @@ import jakarta.transaction.Transactional;
@ApplicationScoped
public class UserService {
- @Inject
- UserRepository userRepository;
+ @Inject UserRepository userRepository;
+ @Inject InstanceService instanceService;
+ @Inject JiRepository jiRepository;
- @Inject
- InstanceService instanceService;
+ public List getAllUsers() { return userRepository.listAll(); }
- public List getAllUsers() {
- return userRepository.listAll();
- }
-
- public User getUser(Long id) {
- return userRepository.findById(id);
- }
+ public User getUser(Long id) { return userRepository.findById(id); }
@Transactional
public User createUser(UserRequest request) {
- User user = new User(request.name, BcryptUtil.bcryptHash(request.password), "pingouin", new ArrayList<>());
+ User user =
+ new User(request.name, BcryptUtil.bcryptHash(request.password),
+ RolesAsso.NONE);
userRepository.persist(user);
return user;
}
@@ -47,7 +45,7 @@ public class UserService {
userRepository.deleteById(id);
}
- @Transactional
+ @Transactional // wtf ? this is get user no ? EDIT : this is x)
public User updateUser(Long id) {
User user = userRepository.findById(id);
return user;
@@ -61,24 +59,51 @@ public class UserService {
}
@Transactional
- public void deleteJDMI() {
- for (Instance instance : instanceService.getAllInstances()) {
- instanceService.deleteInstance(instance.id);
- userRepository.deleteById(instance.user.id);
+ public BulkUserDelResponse deleteUsers(BulkUserDelRequest request) {
+ BulkUserDelResponse response = new BulkUserDelResponse();
+ User userToDel;
+
+ for (UserDelRequest requestName : request.usernames) {
+ try {
+ userToDel =
+ userRepository.find("name", requestName.name).firstResult();
+ userRepository.delete(userToDel);
+ response.success_names.add(requestName.name);
+ } catch (Exception e) {
+ response.failed_names.add(requestName.name);
+ response.failed_reasons.add(e.toString());
+ }
}
+
+ return response;
}
@Transactional
- public List createJdmiUser(BulkUserRequest usersRequest) {
- List users = new ArrayList<>();
- for (UserRequest user : usersRequest.users) {
- User newUser = createUser(user);
- users.add(newUser);
- instanceService.createInstance(user.instance_name, user.instance_ssh, user.instance_pwd, user.instance_port,
- user.name,
- usersRequest.tpId);
- }
- return new ArrayList();
- }
+ public BulkUserPostResponse createUsers(BulkUserPostRequest usersRequest) {
+ BulkUserPostResponse response = new BulkUserPostResponse();
+ if (jiRepository.findById(usersRequest.jiId) != null) {
+ for (UserRequest user : usersRequest.users) {
+ try {
+ createUser(user);
+ response.success_names.add(user.name);
+ } catch (Exception e) {
+ response.already_created.add(user.name);
+ }
+ }
+ }
+
+ return response;
+ }
+
+
+ public RolesAsso fromString(String role_str) {
+ return switch (role_str) {
+ case "ROOT" -> RolesAsso.ROOT;
+ case "MODO" -> RolesAsso.MODO;
+ case "PINGOUIN" -> RolesAsso.PINGOUIN;
+ case "JI" -> RolesAsso.JI;
+ default -> throw new Error("Wrong role str");
+ };
+ }
}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index e95de2b..46f7133 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -26,13 +26,18 @@ quarkus.security.ldap.identity-mapping.attribute-mappings."0".filter-base-dn=ou=
# database
quarkus.datasource.db-kind = postgresql
-quarkus.datasource.username = postgres
-quarkus.datasource.password = secret
-quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:5432/quarkus
+quarkus.datasource.username = banq
+quarkus.datasource.password = test
+#quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:5432/quarkus
# drop and create the database at startup (use `update` to only update the schema)drop-and-create
-quarkus.hibernate-orm.database.generation=update
-# quarkus.hibernate-orm.database.generation=drop-and-create
+#quarkus.hibernate-orm.database.generation=update
+quarkus.hibernate-orm.database.generation=drop-and-create
quarkus.quinoa.dev-server.port=5173
quarkus.quinoa.enable-spa-routing=true
+
+quarkus.docker.docker-host=unix:///run/user/1001/docker.sock
+#quarkus.security.auth.enabled-in-dev-mode=false
+
+quarkus.hibernate-orm.sql-load-script=import-dev.sql
diff --git a/src/main/resources/import-dev.sql b/src/main/resources/import-dev.sql
new file mode 100644
index 0000000..dc81df7
--- /dev/null
+++ b/src/main/resources/import-dev.sql
@@ -0,0 +1,6 @@
+-- Ce fichier est exécuté automatiquement en mode dev
+INSERT INTO penguin (name, password) VALUES ('root', '$2a$10$lzKAv4aj6s0jtneg0Ikx/eEBb6p.6N6yo7ZF.myqYxEA9MWbMwvNu');
+INSERT INTO user_roles (User_id, role) VALUES (1, 'ROOT');
+INSERT INTO site (name, description, address) VALUES ('test', 'test', 'test');
+INSERT INTO ji (name, description, date, site_id) VALUES ('ji', 'test', 'date', 1);
+INSERT INTO ji_respos (ji_id, User_id) VALUES (1, 1);