WIP: adding basic sites and ji handling #2

Draft
arthur.wambst wants to merge 59 commits from arthur.wambst/tests into master
51 changed files with 2721 additions and 421 deletions

1
.gitmodules vendored
View File

@ -1,3 +1,4 @@
[submodule "src/main/webui"]
path = src/main/webui
url = git@git.la-banquise.fr:banquise/intra-front.git
branch = dev

11
dockerfile/Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM linuxserver/openssh-server
RUN apk update
RUN apk upgrade
RUN apk add vim python3 py3-pip apache2 git
RUN pip install discord-py --break-system-packages
RUN mkdir -p /run/apache2
CMD exec /bin/sh -c "trap : TERM INT; sleep 9999999999d & wait"

View File

@ -79,6 +79,11 @@
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkiverse.docker</groupId>
<artifactId>quarkus-docker-client</artifactId>
<version>0.0.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

View File

@ -1,30 +1,32 @@
{ pkgs ? import <nixpkgs> {} }:
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
'';
}

View File

@ -0,0 +1,435 @@
package fr.la_banquise.backend;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection(targets = {
com.github.dockerjava.api.async.ResultCallbackTemplate.class,
com.github.dockerjava.api.model.UpdateFailureAction.class,
com.github.dockerjava.api.model.SwarmNode.class,
com.github.dockerjava.api.model.DriverStatus.class,
com.github.dockerjava.api.model.BindPropagation.class,
com.github.dockerjava.api.model.ResponseItem.ErrorDetail.class,
com.github.dockerjava.api.model.SwarmNodeRole.class,
com.github.dockerjava.api.model.PushResponseItem.class,
com.github.dockerjava.api.model.Ports.class,
com.github.dockerjava.api.model.Version.class,
com.github.dockerjava.api.model.Event.class,
com.github.dockerjava.api.model.ServiceReplicatedModeOptions.class,
com.github.dockerjava.api.model.Config.class,
com.github.dockerjava.api.model.ContainerSpec.class,
com.github.dockerjava.api.model.Volumes.class,
com.github.dockerjava.api.model.ExposedPort.class,
com.github.dockerjava.api.model.SwarmNodeManagerStatus.class,
com.github.dockerjava.api.model.BindOptions.class,
com.github.dockerjava.api.model.NetworkAttachmentConfig.class,
com.github.dockerjava.api.model.SwarmNodePlatform.class,
com.github.dockerjava.api.model.LoadResponseItem.class,
com.github.dockerjava.api.model.BuildResponseItem.class,
com.github.dockerjava.api.model.ServiceGlobalModeOptions.class,
com.github.dockerjava.api.model.SecretSpec.class,
com.github.dockerjava.api.model.SwarmNodeState.class,
com.github.dockerjava.api.model.BlkioStatsConfig.class,
com.github.dockerjava.api.model.Endpoint.class,
com.github.dockerjava.api.model.ContainerSpecPrivilegesSELinuxContext.class,
com.github.dockerjava.api.model.ResourceVersion.class,
com.github.dockerjava.api.model.EndpointResolutionMode.class,
com.github.dockerjava.api.model.PortConfig.class,
com.github.dockerjava.api.model.VolumeBinds.class,
com.github.dockerjava.api.model.ServiceUpdateState.class,
com.github.dockerjava.api.model.DiscreteResourceSpec.class,
com.github.dockerjava.api.model.UpdateConfig.class,
com.github.dockerjava.api.model.PeerNode.class,
com.github.dockerjava.api.model.ErrorDetail.class,
com.github.dockerjava.api.model.ServiceSpec.class,
com.github.dockerjava.api.model.Mount.class,
com.github.dockerjava.api.model.ServicePlacement.class,
com.github.dockerjava.api.model.UpdateOrder.class,
com.github.dockerjava.api.model.WaitResponse.class,
com.github.dockerjava.api.model.Binds.class,
com.github.dockerjava.api.model.BlkioRateDevice.class,
com.github.dockerjava.api.model.VersionPlatform.class,
com.github.dockerjava.api.model.SwarmDispatcherConfig.class,
com.github.dockerjava.api.model.LxcConf.class,
com.github.dockerjava.api.model.DeviceRequest.class,
com.github.dockerjava.api.model.Network.Ipam.class,
com.github.dockerjava.api.model.LocalNodeState.class,
com.github.dockerjava.api.model.DockerObjectAccessor.class,
com.github.dockerjava.api.model.ServiceRestartCondition.class,
com.github.dockerjava.api.model.SwarmNodePluginDescription.class,
com.github.dockerjava.api.model.ContainerSpecPrivileges.class,
com.github.dockerjava.api.model.SwarmNodeEngineDescription.class,
com.github.dockerjava.api.model.TaskSpec.class,
com.github.dockerjava.api.model.PropagationMode.class,
com.github.dockerjava.api.model.ResponseItem.ProgressDetail.class,
com.github.dockerjava.api.model.ResponseItem.AuxDetail.class,
com.github.dockerjava.api.model.Image.class,
com.github.dockerjava.api.model.EventType.class,
com.github.dockerjava.api.model.Network.Ipam.Config.class,
com.github.dockerjava.api.model.ContainerNetworkSettings.class,
com.github.dockerjava.api.model.Reachability.class,
com.github.dockerjava.api.model.VolumeOptions.class,
com.github.dockerjava.api.model.HealthCheck.class,
com.github.dockerjava.api.model.PortConfig.PublishMode.class,
com.github.dockerjava.api.model.EndpointSpec.class,
com.github.dockerjava.api.model.HostConfig.class,
com.github.dockerjava.api.command.SaveImagesCmd.Exec.class,
com.github.dockerjava.api.command.ListVolumesCmd.Exec.class,
com.github.dockerjava.api.command.LeaveSwarmCmd.Exec.class,
com.github.dockerjava.api.command.SaveImageCmd.class,
com.github.dockerjava.api.command.RemoveServiceCmd.class,
com.github.dockerjava.api.command.ResizeExecCmd.class,
com.github.dockerjava.api.command.DockerCmdExecFactory.class,
com.github.dockerjava.api.command.DockerCmdAsyncExec.class,
com.github.dockerjava.api.command.SaveImageCmd.Exec.class,
com.github.dockerjava.api.command.InspectContainerResponse.Mount.class,
com.github.dockerjava.api.command.ListSecretsCmd.Exec.class,
com.github.dockerjava.api.command.InspectExecResponse.class,
com.github.dockerjava.api.command.InspectVolumeResponse.class,
com.github.dockerjava.api.command.BuildImageCmd.class,
com.github.dockerjava.api.command.CreateConfigCmd.Exec.class,
com.github.dockerjava.api.command.CreateConfigResponse.class,
com.github.dockerjava.api.command.InspectSwarmNodeCmd.Exec.class,
com.github.dockerjava.api.command.BuildImageCmd.Exec.class,
com.github.dockerjava.api.command.InspectExecCmd.Exec.class,
com.github.dockerjava.api.command.InspectImageCmd.Exec.class,
com.github.dockerjava.api.command.RemoveVolumeCmd.Exec.class,
com.github.dockerjava.api.command.InitializeSwarmCmd.class,
com.github.dockerjava.api.command.CreateNetworkCmd.class,
com.github.dockerjava.api.command.InspectTaskCmd.Exec.class,
com.github.dockerjava.api.command.InspectImageCmd.class,
com.github.dockerjava.api.command.ExecStartCmd.class,
com.github.dockerjava.api.command.TagImageCmd.Exec.class,
com.github.dockerjava.api.command.ExecCreateCmd.Exec.class,
com.github.dockerjava.api.command.CopyArchiveFromContainerCmd.Exec.class,
com.github.dockerjava.api.command.ListNetworksCmd.class,
com.github.dockerjava.api.command.PauseContainerCmd.class,
com.github.dockerjava.api.command.ExecStartCmd.Exec.class,
com.github.dockerjava.api.command.PullImageResultCallback.class,
com.github.dockerjava.api.command.ContainerDiffCmd.Exec.class,
com.github.dockerjava.api.command.InspectSwarmCmd.class,
com.github.dockerjava.api.command.CopyFileFromContainerCmd.Exec.class,
com.github.dockerjava.api.command.RemoveNetworkCmd.Exec.class,
com.github.dockerjava.api.command.PruneCmd.Exec.class,
com.github.dockerjava.api.command.RestartContainerCmd.class,
com.github.dockerjava.api.command.CreateConfigCmd.class,
com.github.dockerjava.api.command.RemoveConfigCmd.class,
com.github.dockerjava.api.command.CreateSecretCmd.class,
com.github.dockerjava.api.command.LoadImageCallback.class,
com.github.dockerjava.api.command.UpdateServiceCmd.Exec.class,
com.github.dockerjava.api.command.CommitCmd.class,
com.github.dockerjava.api.command.InitializeSwarmCmd.Exec.class,
com.github.dockerjava.api.command.ListVolumesResponse.class,
com.github.dockerjava.api.command.TopContainerResponse.class,
com.github.dockerjava.api.command.ResizeContainerCmd.Exec.class,
com.github.dockerjava.api.command.CopyArchiveToContainerCmd.class,
com.github.dockerjava.api.command.ConnectToNetworkCmd.class,
com.github.dockerjava.api.command.ExecCreateCmd.class,
com.github.dockerjava.api.command.InspectVolumeCmd.Exec.class,
com.github.dockerjava.api.command.ListContainersCmd.Exec.class,
com.github.dockerjava.api.command.HealthStateLog.class,
com.github.dockerjava.api.command.RemoveNetworkCmd.class,
com.github.dockerjava.api.command.UnpauseContainerCmd.Exec.class,
com.github.dockerjava.api.command.ListNetworksCmd.Exec.class,
com.github.dockerjava.api.exception.InternalServerErrorException.class,
com.github.dockerjava.api.async.ResultCallback.Adapter.class,
com.github.dockerjava.api.model.EventActor.class,
com.github.dockerjava.api.model.SwarmJoinTokens.class,
com.github.dockerjava.api.model.VolumesFrom.class,
com.github.dockerjava.api.model.ExposedPorts.class,
com.github.dockerjava.api.model.SwarmRaftConfig.class,
com.github.dockerjava.api.model.BlkioStatEntry.class,
com.github.dockerjava.api.model.ExternalCA.class,
com.github.dockerjava.api.model.Task.class,
com.github.dockerjava.api.model.ResourceRequirements.class,
com.github.dockerjava.api.model.SwarmVersion.class,
com.github.dockerjava.api.model.PullResponseItem.class,
com.github.dockerjava.api.model.InfoRegistryConfig.IndexConfig.class,
com.github.dockerjava.api.model.SearchItem.class,
com.github.dockerjava.api.model.ResponseItem.class,
com.github.dockerjava.api.model.Volume.class,
com.github.dockerjava.api.model.PortBinding.class,
com.github.dockerjava.api.model.ContainerPort.class,
com.github.dockerjava.api.model.PruneType.class,
com.github.dockerjava.api.model.Driver.class,
com.github.dockerjava.api.model.ErrorResponse.class,
com.github.dockerjava.api.model.Node.class,
com.github.dockerjava.api.model.TmpfsOptions.class,
com.github.dockerjava.api.model.EndpointVirtualIP.class,
com.github.dockerjava.api.model.Container.class,
com.github.dockerjava.api.model.AccessMode.class,
com.github.dockerjava.api.model.Device.class,
com.github.dockerjava.api.model.SwarmNodeResources.class,
com.github.dockerjava.api.model.Swarm.class,
com.github.dockerjava.api.model.MemoryStatsConfig.class,
com.github.dockerjava.api.model.TaskState.class,
com.github.dockerjava.api.model.SwarmNodeSpec.class,
com.github.dockerjava.api.model.RestartPolicy.class,
com.github.dockerjava.api.model.TaskDefaults.class,
com.github.dockerjava.api.model.AuthResponse.class,
com.github.dockerjava.api.model.BlkioWeightDevice.class,
com.github.dockerjava.api.model.PidsStatsConfig.class,
com.github.dockerjava.api.model.StatsConfig.class,
com.github.dockerjava.api.model.SwarmCAConfig.class,
com.github.dockerjava.api.model.SwarmSpec.class,
com.github.dockerjava.api.model.StreamType.class,
com.github.dockerjava.api.model.ThrottlingDataConfig.class,
com.github.dockerjava.api.model.Identifier.class,
com.github.dockerjava.api.model.ServiceUpdateStatus.class,
com.github.dockerjava.api.model.ContainerHostConfig.class,
com.github.dockerjava.api.model.GenericResource.class,
com.github.dockerjava.api.model.ContainerNetwork.class,
com.github.dockerjava.api.model.InternetProtocol.class,
com.github.dockerjava.api.model.ContainerSpecPrivilegesCredential.class,
com.github.dockerjava.api.model.DockerObject.class,
com.github.dockerjava.api.model.Bind.class,
com.github.dockerjava.api.model.Statistics.class,
com.github.dockerjava.api.model.ContainerSpecConfig.class,
com.github.dockerjava.api.model.CpuUsageConfig.class,
com.github.dockerjava.api.model.StatisticNetworksConfig.class,
com.github.dockerjava.api.model.ContainerConfig.class,
com.github.dockerjava.api.model.RuntimeInfo.class,
com.github.dockerjava.api.model.Ulimit.class,
com.github.dockerjava.api.model.Isolation.class,
com.github.dockerjava.api.model.ContainerSpecSecret.class,
com.github.dockerjava.api.model.ContainerNetwork.Ipam.class,
com.github.dockerjava.api.model.PruneResponse.class,
com.github.dockerjava.api.model.Network.class,
com.github.dockerjava.api.model.NetworkSettings.class,
com.github.dockerjava.api.model.ServiceRestartPolicy.class,
com.github.dockerjava.api.model.Secret.class,
com.github.dockerjava.api.model.Repository.class,
com.github.dockerjava.api.model.TaskStatus.class,
com.github.dockerjava.api.model.Frame.class,
com.github.dockerjava.api.model.Links.class,
com.github.dockerjava.api.model.InfoRegistryConfig.class,
com.github.dockerjava.api.model.ContainerMount.class,
com.github.dockerjava.api.model.ServiceMode.class,
com.github.dockerjava.api.command.RemoveSwarmNodeCmd.Exec.class,
com.github.dockerjava.api.command.KillContainerCmd.Exec.class,
com.github.dockerjava.api.command.CreateNetworkCmd.Exec.class,
com.github.dockerjava.api.command.GraphDriver.class,
com.github.dockerjava.api.command.VersionCmd.class,
com.github.dockerjava.api.command.InspectContainerResponse.Node.class,
com.github.dockerjava.api.command.VersionCmd.Exec.class,
com.github.dockerjava.api.command.AsyncDockerCmd.class,
com.github.dockerjava.api.command.ConnectToNetworkCmd.Exec.class,
com.github.dockerjava.api.command.PushImageCmd.Exec.class,
com.github.dockerjava.api.command.AuthCmd.Exec.class,
com.github.dockerjava.api.command.SearchImagesCmd.Exec.class,
com.github.dockerjava.api.command.RemoveServiceCmd.Exec.class,
com.github.dockerjava.api.command.RemoveImageCmd.class,
com.github.dockerjava.api.command.ListServicesCmd.class,
com.github.dockerjava.api.command.WaitContainerResultCallback.class,
com.github.dockerjava.api.command.StopContainerCmd.class,
com.github.dockerjava.api.command.InspectSwarmCmd.Exec.class,
com.github.dockerjava.api.command.ListImagesCmd.class,
com.github.dockerjava.api.command.PushImageCmd.class,
com.github.dockerjava.api.command.CreateVolumeCmd.class,
com.github.dockerjava.api.command.TopContainerCmd.Exec.class,
com.github.dockerjava.api.command.DockerCmd.class,
com.github.dockerjava.api.command.ListImagesCmd.Exec.class,
com.github.dockerjava.api.command.ContainerDiffCmd.class,
com.github.dockerjava.api.command.CreateServiceCmd.Exec.class,
com.github.dockerjava.api.command.SaveImagesCmd.class,
com.github.dockerjava.api.command.InspectExecCmd.class,
com.github.dockerjava.api.command.LeaveSwarmCmd.class,
com.github.dockerjava.api.command.PushImageCmd.Exec.class,
com.github.dockerjava.api.command.LoadImageAsyncCmd.Exec.class,
com.github.dockerjava.api.command.LoadImageCmd.Exec.class,
com.github.dockerjava.api.command.SearchImagesCmd.class,
com.github.dockerjava.api.command.InspectContainerCmd.Exec.class,
com.github.dockerjava.api.command.ListContainersCmd.class,
com.github.dockerjava.api.command.PingCmd.class,
com.github.dockerjava.api.command.KillContainerCmd.class,
com.github.dockerjava.api.command.ListTasksCmd.class,
com.github.dockerjava.api.command.DisconnectFromNetworkCmd.class,
com.github.dockerjava.api.command.LogSwarmObjectCmd.class,
com.github.dockerjava.api.command.InspectTaskCmd.class,
com.github.dockerjava.api.command.CopyArchiveFromContainerCmd.class,
com.github.dockerjava.api.command.InspectConfigCmd.Exec.class,
com.github.dockerjava.api.command.ListVolumesCmd.class,
com.github.dockerjava.api.command.InfoCmd.Exec.class,
com.github.dockerjava.api.command.PullImageCmd.Exec.class,
com.github.dockerjava.api.command.CreateContainerResponse.class,
com.github.dockerjava.api.command.CreateVolumeCmd.Exec.class,
com.github.dockerjava.api.command.WaitContainerCmd.Exec.class,
com.github.dockerjava.api.command.GraphData.class,
com.github.dockerjava.api.command.AttachContainerCmd.Exec.class,
com.github.dockerjava.api.command.RestartContainerCmd.Exec.class,
com.github.dockerjava.api.command.EventsCmd.Exec.class,
com.github.dockerjava.api.command.CreateSecretResponse.class,
com.github.dockerjava.api.DockerClient.class,
com.github.dockerjava.api.exception.NotAcceptableException.class,
com.github.dockerjava.api.async.ResultCallback.class,
com.github.dockerjava.api.model.ContainerSpecFile.class,
com.github.dockerjava.api.model.SwarmNodeDescription.class,
com.github.dockerjava.api.model.SwarmOrchestration.class,
com.github.dockerjava.api.model.Capability.class,
com.github.dockerjava.api.model.MountType.class,
com.github.dockerjava.api.model.SELContext.class,
com.github.dockerjava.api.model.Link.class,
com.github.dockerjava.api.model.NamedResourceSpec.class,
com.github.dockerjava.api.model.ContainerDNSConfig.class,
com.github.dockerjava.api.model.VersionComponent.class,
com.github.dockerjava.api.model.LogConfig.class,
com.github.dockerjava.api.model.CpuStatsConfig.class,
com.github.dockerjava.api.model.ServiceModeConfig.class,
com.github.dockerjava.api.model.ChangeLog.class,
com.github.dockerjava.api.model.ResourceSpecs.class,
com.github.dockerjava.api.model.SwarmInfo.class,
com.github.dockerjava.api.model.VolumeBind.class,
com.github.dockerjava.api.model.Network.ContainerNetworkConfig.class,
com.github.dockerjava.api.model.Ports.Binding.class,
com.github.dockerjava.api.model.VolumesRW.class,
com.github.dockerjava.api.model.UpdateContainerResponse.class,
com.github.dockerjava.api.model.ExternalCAProtocol.class,
com.github.dockerjava.api.command.ExecCreateCmdResponse.class,
com.github.dockerjava.api.command.AttachContainerCmd.class,
com.github.dockerjava.api.command.StopContainerCmd.Exec.class,
com.github.dockerjava.api.command.RemoveImageCmd.Exec.class,
com.github.dockerjava.api.command.PullImageCmd.class,
com.github.dockerjava.api.command.RemoveContainerCmd.Exec.class,
com.github.dockerjava.api.command.PingCmd.Exec.class,
com.github.dockerjava.api.command.JoinSwarmCmd.Exec.class,
com.github.dockerjava.api.command.CreateSecretCmd.Exec.class,
com.github.dockerjava.api.command.CreateImageCmd.Exec.class,
com.github.dockerjava.api.command.InfoCmd.class,
com.github.dockerjava.api.command.InspectVolumeCmd.class,
com.github.dockerjava.api.command.PruneCmd.class,
com.github.dockerjava.api.command.UpdateSwarmNodeCmd.class,
com.github.dockerjava.api.command.InspectContainerResponse.class,
com.github.dockerjava.api.command.LogSwarmObjectCmd.Exec.class,
com.github.dockerjava.api.command.StartContainerCmd.class,
com.github.dockerjava.api.command.UpdateContainerCmd.class,
com.github.dockerjava.api.command.ListConfigsCmd.Exec.class,
com.github.dockerjava.api.command.InspectContainerCmd.class,
com.github.dockerjava.api.command.CommitCmd.Exec.class,
com.github.dockerjava.api.command.CreateServiceCmd.class,
com.github.dockerjava.api.command.TopContainerCmd.class,
com.github.dockerjava.api.command.RemoveContainerCmd.class,
com.github.dockerjava.api.command.RemoveSecretCmd.class,
com.github.dockerjava.api.command.LogContainerCmd.Exec.class,
com.github.dockerjava.api.command.InspectExecResponse.Container.class,
com.github.dockerjava.api.command.RenameContainerCmd.class,
com.github.dockerjava.api.command.CreateVolumeResponse.class,
com.github.dockerjava.api.command.UpdateSwarmNodeCmd.Exec.class,
com.github.dockerjava.api.command.DockerCmdSyncExec.class,
com.github.dockerjava.api.command.DelegatingDockerCmdExecFactory.class,
com.github.dockerjava.api.command.InspectImageResponse.class,
com.github.dockerjava.api.command.StatsCmd.class,
com.github.dockerjava.api.command.UpdateContainerCmd.Exec.class,
com.github.dockerjava.api.command.RemoveConfigCmd.Exec.class,
com.github.dockerjava.api.command.UpdateServiceCmd.class,
com.github.dockerjava.api.exception.DockerException.class,
com.github.dockerjava.api.DockerClientDelegate.class,
com.github.dockerjava.api.model.TaskStatusContainerStatus.class,
com.github.dockerjava.api.model.SwarmNodeAvailability.class,
com.github.dockerjava.api.model.SwarmNodeVersion.class,
com.github.dockerjava.api.model.VolumeRW.class,
com.github.dockerjava.api.model.Service.class,
com.github.dockerjava.api.model.SwarmNodeStatus.class,
com.github.dockerjava.api.model.AuthConfig.class,
com.github.dockerjava.api.model.LogConfig.LoggingType.class,
com.github.dockerjava.api.model.ClusterInfo.class,
com.github.dockerjava.api.model.Info.class,
com.github.dockerjava.api.model.ObjectVersion.class,
com.github.dockerjava.api.model.AuthConfigurations.class,
com.github.dockerjava.api.model.ConfigSpec.class,
com.github.dockerjava.api.model.PortConfigProtocol.class,
com.github.dockerjava.api.command.RemoveVolumeCmd.class,
com.github.dockerjava.api.command.InspectSwarmNodeCmd.class,
com.github.dockerjava.api.command.LogContainerCmd.class,
com.github.dockerjava.api.command.InspectConfigCmd.class,
com.github.dockerjava.api.command.PauseContainerCmd.Exec.class,
com.github.dockerjava.api.command.ResizeExecCmd.Exec.class,
com.github.dockerjava.api.command.BuildImageResultCallback.class,
com.github.dockerjava.api.command.RenameContainerCmd.Exec.class,
com.github.dockerjava.api.command.InspectNetworkCmd.Exec.class,
com.github.dockerjava.api.command.CreateImageCmd.class,
com.github.dockerjava.api.command.ListServicesCmd.Exec.class,
com.github.dockerjava.api.command.RemoveSecretCmd.Exec.class,
com.github.dockerjava.api.command.AuthCmd.class,
com.github.dockerjava.api.command.DisconnectFromNetworkCmd.Exec.class,
com.github.dockerjava.api.command.CreateImageResponse.class,
com.github.dockerjava.api.command.RootFS.class,
com.github.dockerjava.api.command.StartContainerCmd.Exec.class,
com.github.dockerjava.api.command.InspectExecResponse.ProcessConfig.class,
com.github.dockerjava.api.command.WaitContainerCmd.class,
com.github.dockerjava.api.command.ListSecretsCmd.class,
com.github.dockerjava.api.command.CopyFileFromContainerCmd.class,
com.github.dockerjava.api.command.JoinSwarmCmd.class,
com.github.dockerjava.api.command.CreateContainerCmd.Exec.class,
com.github.dockerjava.api.command.CreateServiceResponse.class,
com.github.dockerjava.api.command.EventsCmd.class,
com.github.dockerjava.api.command.LoadImageAsyncCmd.class,
com.github.dockerjava.api.command.StatsCmd.Exec.class,
com.github.dockerjava.api.command.ListSwarmNodesCmd.class,
com.github.dockerjava.api.command.TagImageCmd.class,
com.github.dockerjava.api.command.ListTasksCmd.Exec.class,
com.github.dockerjava.api.command.ListConfigsCmd.class,
com.github.dockerjava.api.command.SyncDockerCmd.class,
com.github.dockerjava.api.command.InspectServiceCmd.Exec.class,
com.github.dockerjava.api.command.CreateNetworkResponse.class,
com.github.dockerjava.api.command.LoadImageCmd.class,
com.github.dockerjava.api.command.ResizeContainerCmd.class,
com.github.dockerjava.api.command.InspectContainerResponse.ContainerState.class,
com.github.dockerjava.api.command.UpdateSwarmCmd.class,
com.github.dockerjava.api.command.SaveImagesCmd.TaggedImage.class,
com.github.dockerjava.api.command.CopyArchiveToContainerCmd.Exec.class,
com.github.dockerjava.api.command.HealthState.class,
com.github.dockerjava.api.command.UpdateSwarmCmd.Exec.class,
com.github.dockerjava.api.command.InspectNetworkCmd.class,
com.github.dockerjava.api.command.UnpauseContainerCmd.class,
com.github.dockerjava.api.command.InspectServiceCmd.class,
com.github.dockerjava.api.command.ListSwarmNodesCmd.Exec.class,
com.github.dockerjava.api.command.RemoveSwarmNodeCmd.class,
com.github.dockerjava.api.command.CreateContainerCmd.class,
com.github.dockerjava.api.exception.BadRequestException.class,
com.github.dockerjava.api.exception.NotFoundException.class,
com.github.dockerjava.api.exception.UnauthorizedException.class,
com.github.dockerjava.api.exception.ConflictException.class,
com.github.dockerjava.api.exception.DockerClientException.class,
com.github.dockerjava.api.exception.NotModifiedException.class,
com.github.dockerjava.api.model.LogConfig.class,
com.github.dockerjava.api.model.Container.class,
com.github.dockerjava.api.model.Image.class,
com.github.dockerjava.api.model.Info.class,
com.github.dockerjava.api.command.InspectContainerResponse.class,
com.github.dockerjava.core.command.BuildImageCmdImpl.class,
com.github.dockerjava.core.command.CreateContainerCmdImpl.class,
com.github.dockerjava.core.command.RemoveContainerCmdImpl.class,
com.github.dockerjava.core.command.ListImagesCmdImpl.class,
com.github.dockerjava.core.command.SearchImagesCmdImpl.class,
com.github.dockerjava.core.command.PullImageCmdImpl.class,
com.github.dockerjava.core.command.TagImageCmdImpl.class,
com.github.dockerjava.core.command.RemoveImageCmdImpl.class,
com.github.dockerjava.core.command.PushImageCmdImpl.class,
com.github.dockerjava.core.command.CreateContainerCmdImpl.class,
com.github.dockerjava.core.command.ListContainersCmdImpl.class,
com.github.dockerjava.core.command.StartContainerCmdImpl.class,
com.github.dockerjava.core.command.StopContainerCmdImpl.class,
com.github.dockerjava.core.command.RestartContainerCmdImpl.class,
com.github.dockerjava.core.command.KillContainerCmdImpl.class,
com.github.dockerjava.core.command.PauseContainerCmdImpl.class,
com.github.dockerjava.core.command.UnpauseContainerCmdImpl.class,
com.github.dockerjava.core.command.BuildImageCmdImpl.class,
com.github.dockerjava.api.command.CreateContainerResponse.class,
com.github.dockerjava.api.model.BuildResponseItem.class,
com.github.dockerjava.api.model.Container.class,
com.github.dockerjava.api.model.ContainerConfig.class,
com.github.dockerjava.api.model.HostConfig.class,
com.github.dockerjava.api.model.Image.class,
com.github.dockerjava.api.model.Info.class,
com.github.dockerjava.api.model.ResponseItem.class,
com.github.dockerjava.api.model.Statistics.class,
com.github.dockerjava.api.model.Volume.class,
com.github.dockerjava.api.model.Network.class,
com.github.dockerjava.api.model.Frame.class,
com.github.dockerjava.api.command.InspectContainerResponse.class,
com.github.dockerjava.core.command.ExecCreateCmdImpl.class,
com.github.dockerjava.core.command.ExecStartCmdImpl.class,
com.github.dockerjava.core.command.ExecStartCmdImpl.class,
})
public class DockerJavaReflectionConfig {
}

View File

@ -0,0 +1,72 @@
/**package fr.la_banquise.backend.data.model;
Review

Il est commente, il aurait une importance plus tard ou on peut le supprimer ?

Il est commente, il aurait une importance plus tard ou on peut le supprimer ?
Review

Il sert pour le moment a m éviter d aller rechercher les fonctions de docker java api directement dans le repo vu que y a 0 doc, j l enleverai pour la version finale

Il sert pour le moment a m éviter d aller rechercher les fonctions de docker java api directement dans le repo vu que y a 0 doc, j l enleverai pour la version finale
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<Instance> 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;
};
}**/

View File

@ -1,7 +1,7 @@
package fr.la_banquise.backend.data.model;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
@ -10,6 +10,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 +18,35 @@ 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;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "user_id", nullable = false)
public User user;
public User owner;
@ManyToOne
@JoinColumn(name = "practical_id")
public Tp tp;
public String containerId;
public String password;
public Instance(String name, String ssh, String pwd, Long port, User user, Tp tp) {
public Instance(String name, int port, User user, String containerId,
String password) {
this.name = name;
this.ssh = ssh;
this.pwd = pwd;
this.port = port;
this.user = user;
this.tp = tp;
this.owner = user;
this.containerId = containerId;
this.password = password;
}
}

View File

@ -0,0 +1,66 @@
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.ArrayList;
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;
public String date;
@ManyToOne
@JoinColumn(name = "site_id") //@JsonIgnore
public Site site;
@JsonIgnore
@ManyToMany
@JoinTable(name = "ji_respos", // Table de liaison
joinColumns = @JoinColumn(name = "ji_id"),
inverseJoinColumns = @JoinColumn(name = "user_id"))
public List<User> respos;
@JsonIgnore
@ManyToMany
@JoinTable(name = "ji_participants", // Table de liaison
joinColumns = @JoinColumn(name = "ji_id"),
inverseJoinColumns = @JoinColumn(name = "user_id"))
public List<User> participants;
@OneToMany
@JoinColumn(name = "instance_id")
public List<Instance> instances;
public Ji(String name, String description, List<User> respos, String date,
Site site) {
this.name = name;
this.description = description;
this.respos = respos;
this.date = date;
this.site = site;
this.participants = new ArrayList<User>();
this.instances = new ArrayList<Instance>();
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,44 @@
package fr.la_banquise.backend.data.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
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 = "site") @JsonIgnore public List<Ji> listJi;
public Site(String name, String description, String address) {
this.name = name;
this.description = description;
this.address = address;
this.listJi = new ArrayList<Ji>();
}
}

View File

@ -0,0 +1,51 @@
package fr.la_banquise.backend.data.model;
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<User> respos;
public Sujet(String name, String description, String pdfLink,
List<User> respos) {
this.name = name;
this.description = description;
this.pdfLink = pdfLink;
this.respos = respos;
}
}

View File

@ -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;
}
}

View File

@ -1,21 +1,31 @@
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.Column;
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 +44,51 @@ 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;
@Column(unique = true, nullable = false) @Username public String name;
@Password public String password;
@Enumerated(EnumType.STRING)
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "user_roles")
public Set<RolesAsso> role;
public String email;
///////////////////////////////////////////////////////////////////////////
// Dans l'ordre d'affichage dans le dashboard :
@ManyToMany(mappedBy = "respos", cascade = CascadeType.ALL)
public List<Ji> jiRespo; // JI dont user est respo
@ManyToMany(mappedBy = "participants", cascade = CascadeType.ALL)
public List<Ji> jiParticipant; // JI ou user est participant
@ManyToMany(mappedBy = "respos", cascade = CascadeType.ALL)
public List<Sujet> sujetRespo; // Sujet ou user est respo
///////////////////////////////////////////////////////////////////////////
@OneToMany(mappedBy = "owner", cascade = CascadeType.ALL)
public List<Instance> instances; // mouai, pas a afficher
// Méthode pour Quarkus Security - conversion simple
@RolesValue
@Roles
public String role;
@JsonManagedReference
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
public List<Instance> instances;
public User(String name, String password, String role, List<Instance> instances) {
this.name = name;
this.password = password;
this.role = role;
this.instances = instances;
public Set<String> getRoles() {
return role.stream()
.filter(r -> r != RolesAsso.NONE)
.map(Enum::name)
.collect(Collectors.toSet());
}
public User(String name, String password, RolesAsso role, String mail) {
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<>();
this.email = mail;
}
}

View File

@ -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<Container> {
}*/

View File

@ -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<Ji> {
}

View File

@ -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<Site> {}

View File

@ -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<Tp> {
}
public class SujetRepository implements PanacheRepository<Sujet> {}

View File

@ -0,0 +1,102 @@
package fr.la_banquise.backend.rest;
import fr.la_banquise.backend.services.DockerService;
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.Map;
@Path("/docker")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class DockerResource {
@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
@RolesAllowed("ROOT")
@Path("/all")
public Response listContainers() {
try {
return Response.ok(dockerService.listAllContainers()).build();
} catch (Exception e) {
return Response.status(500)
.entity(Map.of("error", e.getMessage()))
.build();
}
}
@POST
@RolesAllowed("ROOT")
@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
@RolesAllowed("ROOT")
@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
@RolesAllowed("ROOT")
@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();
}
}
}

View File

@ -1,8 +1,11 @@
package fr.la_banquise.backend.rest;
import fr.la_banquise.backend.data.model.User;
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 fr.la_banquise.backend.services.UserService;
import io.quarkus.security.Authenticated;
import io.quarkus.security.identity.SecurityIdentity;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
@ -15,27 +18,28 @@ import jakarta.ws.rs.core.Response;
@Path("api")
public class Endpoints {
@Inject
SecurityIdentity identity;
@Inject SecurityIdentity identity;
@Inject
InstanceService instanceService;
@Inject InstanceService instanceService;
@Inject SujetService sujetService;
@Inject UserService userService;
@Inject
TpService tpService;
@GET
@Authenticated
@Path("dashboard")
public Response getDashboard() {
String username = identity.getPrincipal().getName();
User user = userService.getUser(username);
DashboardResponse dashboard = new DashboardResponse();
if (identity.getRoles().contains("root")) {
dashboard.tps = tpService.getAllTpsAdmin();
} else {
dashboard.roles = user.getRoles();
dashboard.name = username;
dashboard.jiRespo = user.jiRespo;
dashboard.jiParticipant = user.jiParticipant;
dashboard.sujetRespo = user.sujetRespo;
dashboard.tps = tpService.getAllTps(identity.getPrincipal().getName());
}
dashboard.instances = instanceService.getAllInstances(username);
return Response.ok(dashboard).build();
}
}

View File

@ -1,38 +1,147 @@
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 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;
/**
* 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;
@Inject UserService userService;
///////////////////////////////////////////////////////////////////////////
///
/// First, we create our Instance and basic functions
@POST
@RolesAllowed("ROOT")
@Path("/{id}/instance")
public Response createInstance(@PathParam("id") Long jiId,
@QueryParam("userId") Long userId) {
jiService.createInstance(jiId, userId);
return Response.ok().build();
}
@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();
}
@GET
@RolesAllowed("ROOT")
@Path("/{id}/all-instances")
public Response getAllInstancesJi(@PathParam("id") Long jiId) {
return Response.ok(jiService.getAllInstancesJi(jiId)).build();
}
@GET
@Authenticated
@Path("/{id}/instances")
public Response getMyInstancesJi(@PathParam("id") Long jiId) {
String name = identity.getPrincipal().getName();
Long userId = userService.getId(name);
return Response.ok(jiService.getInstance(jiId, userId)).build();
}
///////////////////////////////////////////////////////////////////////////
/// Now that the Instance is created, create their containers !
@POST
@RolesAllowed("ROOT")
@Path("/{id}/containers")
public Response createContainers(@PathParam("id") Long jiId) {
jiService.createContainers(jiId);
return Response.ok().build();
}
/// Finally, start/stop the containers
@POST
@RolesAllowed("ROOT")
@Path("/{id}/container/start")
public Response startContainers(@PathParam("id") Long jiId) {
jiService.startContainers(jiId);
return Response.ok().build();
}
@POST
public Response createInstance(InstanceRequest request) {
instanceService.createInstance(request.name, request.ssh, request.pwd, request.port, request.username, request.tpId);
@RolesAllowed("ROOT")
@Path("/{id}/container/stop")
public Response stopContainers(@PathParam("id") Long jiId) {
jiService.stopContainers(jiId);
return Response.ok().build();
}
@GET
@RolesAllowed("ROOT")
@Path("/{id}/containers")
public Response getStatusContainers(@PathParam("id") Long jiId) {
return Response.ok(jiService.getStatusContainers(jiId)).build();
}
@GET
@RolesAllowed("ROOT")
@Path("/{id}/container-admin")
public Response getStatusContainer(@PathParam("id") Long jiId,
@QueryParam("instId") Long instId) {
// TODO : add securtiy if needed ?
return Response.ok(jiService.getStatusContainerInst(jiId, instId)).build();
}
@GET
@RolesAllowed("ROOT")
@Path("/{id}/instance-owner")
public Response getOwnerInstance(@PathParam("id") Long jiId,
@QueryParam("instId") Long instId) {
// TODO : add securtiy if needed ?
return Response.ok(jiService.getOwnerInst(jiId, instId)).build();
}
@GET
@Authenticated
@Path("/{id}/container")
public Response getStatusMyContainer(@PathParam("id") Long jiId) {
String name = identity.getPrincipal().getName();
Long userId = userService.getId(name);
return Response.ok(jiService.getStatusContainer(jiId, userId)).build();
}
///////////////////////////////////////////////////////////////////////////
/// Last but not least, be able do delete every container and instance
@DELETE
@RolesAllowed("ROOT")
@Path("/{id}/container/{instanceId}")
public Response
delContainer(@PathParam("id") Long jiId,
@PathParam("instanceId") Long instanceId) {
jiService.deleteContainer(instanceId);
// TODO: add filter by JI (but optionnal imo)
return Response.ok().build();
}
}

View File

@ -0,0 +1,128 @@
package fr.la_banquise.backend.rest;
import fr.la_banquise.backend.data.model.Ji;
import fr.la_banquise.backend.data.model.User;
import fr.la_banquise.backend.services.JiService;
import fr.la_banquise.backend.services.UserService;
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 JiEndpoints {
@Inject SecurityIdentity identity;
@Inject JiService jiService;
@Inject UserService userService;
///////////////////////////////////////////////////////////////////////////
///
/// First, we create our JI and basic functions
@POST
@Path("/create")
@RolesAllowed("ROOT")
public Response createJi(@QueryParam("name") String name,
@QueryParam("date") String date,
@QueryParam("desc") String desc,
@QueryParam("site_id") Long siteId) {
try {
String username = identity.getPrincipal().getName();
User user = userService.getUser(username);
Long id = jiService.createJi(name, desc, date, siteId, user.id).id;
return Response.ok(Map.of("id", id)).build();
} catch (Exception e) {
return Response.status(500)
.entity(Map.of("error", e.getMessage()))
.build();
}
}
@GET
@Path("/listall")
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed("ROOT")
public Response listall() {
try {
List<Ji> ji = jiService.getAllJiAdmin();
return Response.ok(ji).build();
} catch (Exception e) {
return Response.status(500)
.entity(Map.of("error", e.getMessage()))
.build();
}
}
@GET
@Path("/{ID}")
@Produces(MediaType.APPLICATION_JSON)
public Response getJi(@PathParam("ID") Long id) {
try {
Ji ji = jiService.getJi(id);
return Response.ok(ji).build();
} catch (Exception e) {
return Response.status(500)
.entity(Map.of("error", e.getMessage()))
.build();
}
}
@GET
@Path("/{ID}/site-id")
@Produces(MediaType.APPLICATION_JSON)
public Response getJiSiteId(@PathParam("ID") Long id) {
try {
Ji ji = jiService.getJi(id);
return Response.ok(ji.site.id).build();
} catch (Exception e) {
return Response.status(500)
.entity(Map.of("error", e.getMessage()))
.build();
}
}
///////////////////////////////////////////////////////////////////////////
/// Now that the JI is created, we want to add users to it and assign them
/// instances, but DONT create their containers yet !
/// Then, when an admin decides it, we create the containers
/// Finally, start/stop the containers
/// => These endpoints are into InstanceEndpoint
///////////////////////////////////////////////////////////////////////////
/// Last but not least, be able do delete every container and instance
@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
deleteJi(@QueryParam("id") Long id) {
try {
jiService.deleteJi(id);
return Response.ok().build();
} catch (Exception e) {
return Response.status(500)
.entity(Map.of("error", e.getMessage()))
.build();
}
}
}

View File

@ -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<Site> 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 {
Long id = siteService.createSite(name, desc, address).id;
return Response.ok(Map.of("id", id)).build();
} catch (Exception e) {
return Response.status(500)
.entity(Map.of("error", e.getMessage()))
.build();
}
}
@GET
@Path("/{ID}")
@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
getSite(@PathParam("ID") Long id) {
try {
Site site = siteService.getSite(id);
return Response.ok(site).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
deleteSite(@QueryParam("ID") Long id) {
try {
boolean retour = siteService.deleteSite(id);
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();
}
}
}

View File

@ -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)
Review

Quand une des annotation est repetitive @Produces(MediaType.APPLICATION_JSON) par exemple tu peux le mettre au dessus de ta declaration de class et elle sera pour toutes les method a l'interieur de ta classe

Quand une des annotation est repetitive `@Produces(MediaType.APPLICATION_JSON)` par exemple tu peux le mettre au dessus de ta declaration de class et elle sera pour toutes les method a l'interieur de ta classe
Review

euu jsp si elle est vraiment necessaire en fait, j vois pas clairement c qu elle change

euu jsp si elle est vraiment necessaire en fait, j vois pas clairement c qu elle change
@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();
}
}
}

View File

@ -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();
}
}

View File

@ -1,9 +1,10 @@
package fr.la_banquise.backend.rest;
import fr.la_banquise.backend.rest.request.BulkUserRequest;
import fr.la_banquise.backend.data.model.User;
import fr.la_banquise.backend.rest.request.UserRequest;
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 +14,91 @@ 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.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 {
userService.updateRole(role, userId);
return Response.ok().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 {
userService.removeRole(role, userId);
return Response.ok().build();
} catch (Exception e) {
return Response.status(404)
.entity(Map.of("User or Role not found", e))
.build();
}
}
arthur.wambst marked this conversation as resolved
Review

pareil qu'au dessus

pareil qu'au dessus
Review

done

done
@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();
return Response.ok(userService.createUserRandom(user)).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();
}

View File

@ -0,0 +1,72 @@
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
Review

@RolesAllowed({ "ROOT", "JI" })

`@RolesAllowed({ "ROOT", "JI" })`
Review

nan ca doit etre que les respo de la JI en question donc flm pour le moment

nan ca doit etre que les respo de la JI en question donc flm pour le moment
// INFO: if response is empty => required associated jiId was not found in
// existing JIs
public Response createUsersBulk(BulkUserPostRequest request) {
BulkUserPostResponse response = userService.createUsers(request);
if (response.successMails.size() == request.users.size())
return Response.ok(response).build();
if (response.successMails.size() == 0)
return Response.status(500).entity(response).build();
return Response.status(202).entity(response).build();
}
@DELETE
@RolesAllowed("ROOT")
public Response deleteUserBulk(BulkUserDelRequest users) {
BulkUserDelResponse response = userService.deleteUsers(users);
if (response.successNames.size() == users.usernames.size())
return Response.ok().build();
Map<String, String> retour = new HashMap<String, String>();
for (int id = 0; id < response.failedNames.size(); id++) {
retour.put(response.failedNames.get(id),
response.failedReasons.get(id));
}
return Response.status(202).entity(retour).build();
}
}

View File

@ -0,0 +1,7 @@
package fr.la_banquise.backend.rest.request;
import java.util.List;
public class BulkUserDelRequest {
public List<UserDelRequest> usernames;
}

View File

@ -2,11 +2,7 @@ package fr.la_banquise.backend.rest.request;
import java.util.List;
/**
* UserRequest
*/
public class BulkUserRequest {
public class BulkUserPostRequest {
public List<UserRequest> users;
public String password;
public Long tpId;
public Long jiId;
}

View File

@ -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;
}

View File

@ -0,0 +1,10 @@
package fr.la_banquise.backend.rest.request;
/**
* SiteRequest
*/
public class SiteRequest {
public String name;
public String description;
public String address;
}

View File

@ -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;
}

View File

@ -0,0 +1,5 @@
package fr.la_banquise.backend.rest.request;
public class UserDelRequest {
public String name;
}

View File

@ -1,14 +1,6 @@
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;
}

View File

@ -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<String> successNames;
public List<String> failedNames;
public List<String> failedReasons;
public BulkUserDelResponse() {
this.successNames = new ArrayList<String>();
this.failedNames = new ArrayList<String>();
this.failedReasons = new ArrayList<String>();
}
}

View File

@ -0,0 +1,19 @@
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<String> successMails;
public List<String> successPasswd;
public List<String> alreadyCreated;
public BulkUserPostResponse() {
this.successMails = new ArrayList<String>();
this.successPasswd = new ArrayList<String>();
this.alreadyCreated = new ArrayList<String>();
}
}

View File

@ -1,17 +1,30 @@
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.Ji;
import fr.la_banquise.backend.data.model.Sujet;
import io.quarkus.runtime.annotations.RegisterForReflection;
import lombok.AllArgsConstructor;
import java.util.List;
import java.util.Set;
/**
* DashboardResponse
*/
@RegisterForReflection
public class DashboardResponse {
public List<Tp> tps;
public List<Instance> instances;
///////////////////////////////////////////////////////////////////////////
////// Dans l'ordre d'affichage dans le dashboard :
// Profil
public String name;
public Set<String> roles;
// A afficher dans des blocs differents
public List<Ji> jiRespo;
public List<Ji> jiParticipant;
public List<Sujet> sujetRespo;
///////////////////////////////////////////////////////////////////////////
}

View File

@ -0,0 +1,15 @@
package fr.la_banquise.backend.rest.response;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
public class DockerResponse {
public String name;
public String state;
public String image;
public List<String> publicPorts;
}

View File

@ -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<String> roles;
public LoggedUserResponse(String username, Set<String> roles) {
this.username = username;
this.roles = roles;
}
}

View File

@ -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<User> 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;
}*/
}

View File

@ -0,0 +1,15 @@
package fr.la_banquise.backend.rest.response;
import fr.la_banquise.backend.data.model.User;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public class UserPostResponse {
public User user;
public String passwd;
public UserPostResponse(User user, String passwd) {
this.user = user;
this.passwd = passwd;
}
}

View File

@ -0,0 +1,179 @@
/*package fr.la_banquise.backend.services;
Review

Besoin de ca ou pas si il est commente ?

Besoin de ca ou pas si il est commente ?
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<String, String> 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<Container> 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<Container> containers = dockerClient.listContainersCmd()
.withShowAll(true)
.exec();
json.append("[");
for (int i = 0; i < containers.size(); i++) {
Container container = containers.get(i);
// Ports
List<String> 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();
}
}*/

View File

@ -0,0 +1,265 @@
package fr.la_banquise.backend.services;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.BuildImageResultCallback;
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 fr.la_banquise.backend.rest.response.DockerResponse;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@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<String, String> 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 listAllContainers() {
* StringBuilder json = new StringBuilder();
* List<Container> 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<Container> containers = dockerClient.listContainersCmd()
* .withShowAll(true)
* .exec();
* json.append("[");
* for (int i = 0; i < containers.size(); i++) {
* Container container = containers.get(i);
* // Ports
* List<String> 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();
* }
*/
////////////////////
///
///////////////////////////////////////////////////////////////////////////
///
/// First, we create our container and basic functions
public String createContainer(String name, int port, String username,
String password) {
ExposedPort tcpSsh = ExposedPort.tcp(2222);
Ports portBindings = new Ports();
portBindings.bind(tcpSsh, Ports.Binding.bindPort(port));
HostConfig hostConfig =
HostConfig.newHostConfig().withPortBindings(portBindings);
Map<String, String> labels = new HashMap<>();
labels.put("test", "banquise");
labels.put("environment", "development");
labels.put("version", "1.0");
labels.put("created-by", "java-docker-api");
if (username.equals("root")) {
username = "root_user";
}
dockerClient.buildImageCmd()
.withDockerfile(new File("./dockerfile/Dockerfile"))
.withBaseDirectory(new File("./dockerfile"))
.withTags(Set.of("ji-python:latest"))
.exec(new BuildImageResultCallback())
.awaitImageId();
CreateContainerResponse container =
dockerClient.createContainerCmd("ji-python:latest")
.withName(name)
.withLabels(labels)
.withExposedPorts(tcpSsh)
.withHostConfig(hostConfig)
.withEnv(
"SUDO_ACCESS=true", "PASSWORD_ACCESS=true",
"USER_NAME=".concat(username), // TODO : User login
"USER_PASSWORD=".concat(password) // TODO : Random passwd
)
.exec();
return container.getId();
}
public boolean containerExists(String name) {
try {
dockerClient.inspectContainerCmd(name).exec();
return true;
} catch (Exception e) {
return false;
}
}
public List<DockerResponse> listAllContainers() {
List<Container> containers =
dockerClient.listContainersCmd().withShowAll(true).exec();
return containers.stream().map(this::toDockerResponse).toList();
}
private DockerResponse toDockerResponse(Container container) {
List<String> portsList = new ArrayList<>();
for (var port : container.getPorts()) {
portsList.add(String.format("%s:%s", port.getPrivatePort(),
port.getPublicPort()));
}
return new DockerResponse(container.getNames()[0].substring(1),
container.getStatus(), container.getImage(),
portsList);
}
public InspectContainerResponse.ContainerState
getStatusContainer(String name) {
InspectContainerResponse container =
dockerClient.inspectContainerCmd(name).exec();
return container.getState();
}
public void start(String containerId) {
dockerClient.startContainerCmd(containerId).exec();
}
public void stop(String containerId) {
dockerClient.stopContainerCmd(containerId).exec();
}
public boolean remove(String name) {
try {
dockerClient.removeContainerCmd(name).exec();
return true;
} catch (Exception e) {
return false;
}
}
}

View File

@ -1,16 +1,19 @@
package fr.la_banquise.backend.services;
import java.util.List;
import com.github.dockerjava.api.command.InspectContainerResponse;
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.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
/**
* InstanceService
@ -18,64 +21,135 @@ import jakarta.transaction.Transactional;
@ApplicationScoped
public class InstanceService {
@Inject
InstanceRepository instanceRepository;
@Inject InstanceRepository instanceRepository;
@Inject
UserRepository userRepository;
@Inject UserRepository userRepository;
@Inject
TpRepository tpRepository;
@Inject JiRepository jiRepository;
@Inject DockerService dockerService;
///////////////////////////////////////////////////////////////////////////
///
/// First, we create our Instance and basic functions
public String randomAlphanumericString() {
int leftLimit = 48; // numeral '0'
int rightLimit = 122; // letter 'z'
int targetStringLength = 20;
Random random = new Random();
String generatedString =
random.ints(leftLimit, rightLimit + 1)
.filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97))
.limit(targetStringLength)
.collect(StringBuilder::new, StringBuilder::appendCodePoint,
StringBuilder::append)
.toString();
return generatedString;
}
@Transactional
public Instance createInstance(Long userId, Ji ji) {
User user = userRepository.findById(userId);
String name = user.name + "-" + ji.id;
int port = getFreePort(1).iterator().next();
Instance instance = new Instance(name, port, user, "Not created",
randomAlphanumericString());
instanceRepository.persist(instance);
return instance;
}
public List<Instance> getAllInstances() {
return instanceRepository.findAll().list();
}
public List<Instance> getAllInstances(String username) {
User user = userRepository.findByName(username);
return instanceRepository.find("user", user).list();
public List<Instance> getInstancesByOwner(Long id) {
User user = userRepository.findById(id);
return instanceRepository.find("owner", user).list();
}
public Instance getInstance(Long id) {
return instanceRepository.findById(id);
}
@Transactional
public Instance createInstance(String name, String ssh, String pwd, Long port, String username, Long tpId) {
User user = userRepository.findByName(username);
Tp tp = tpRepository.findById(tpId);
Instance instance = new Instance(name, ssh, pwd, port, user, tp);
instanceRepository.persist(instance);
return instance;
///////////////////////////////////////////////////////////////////////////
/// Now that the Instance is created, create their containers (and handle
/// if it is already created) !
public void createContainer(Long instanceId) {
Instance instance = instanceRepository.findById(instanceId);
if (instance.containerId.equals("Not created"))
instance.containerId = dockerService.createContainer(
instance.name, instance.port, instance.owner.name,
instance.password);
}
@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;
}
@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) {
public InspectContainerResponse.ContainerState getStatusContainer(Long id) {
Instance instance = instanceRepository.findById(id);
return instance;
return dockerService.getStatusContainer(instance.name);
}
///////////////////////////////////////////////////////////////////////////
/// Finally, start/stop the containers
public void startContainer(Long instanceId) {
Instance instance = instanceRepository.findById(instanceId);
dockerService.start(instance.containerId);
}
public void stopContainer(Long instanceId) {
Instance instance = instanceRepository.findById(instanceId);
dockerService.stop(instance.containerId);
}
///////////////////////////////////////////////////////////////////////////
/// Last but not least, be able do delete every container and instance
public boolean deleteContainer(Long id) {
Instance instance = instanceRepository.findById(id);
instance.containerId = "Not created";
return dockerService.remove(instance.name);
}
@Transactional
public void deleteInstance(Long id) {
Instance instance = instanceRepository.findById(id);
if (dockerService.containerExists(instance.containerId))
dockerService.remove(instance.containerId);
instanceRepository.deleteById(id);
}
///////////////////////////////////////////////////////////////////////////
/// UTILS FOR PORTS NUMBERS HANDLING
public Set<Integer> getUsedPorts() {
Set<Integer> retour = new HashSet<>();
List<Instance> allInstances = getAllInstances();
for (Instance instance : allInstances) {
retour.add(instance.port);
}
return retour;
}
public Set<Integer> getFreePort(int nbPortsNeeded) {
Set<Integer> used = getUsedPorts();
Set<Integer> 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;
}
}

View File

@ -0,0 +1,204 @@
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 UserService userService;
@Inject InstanceService instanceService;
@Inject SecurityContext security;
///////////////////////////////////////////////////////////////////////////
///
/// First, we create our JI and basic functions
@Transactional
public Ji createJi(String name, String description, String date,
Long siteId, Long ownerId) {
Site site = siteService.getSite(siteId);
User user = userService.getUser(ownerId);
if (site == null || user == null)
throw new Error("no site or user");
Ji ji = new Ji(name, description, List.of(user), date, site);
jiRepository.persist(ji);
siteService.registerJi(site, ji);
createInstance(user.id, ji.id);
return ji;
}
public List<Ji> getAllJiAdmin() { return jiRepository.listAll(); }
public List<Ji> getAllJiRespo(String username) {
User user = userRepository.findByName(username);
return user.jiRespo;
}
public Ji getJi(Long id) { return jiRepository.findById(id); }
public Long getJiSiteId(Long id) {
return jiRepository.findById(id).site.id;
}
public List<Instance> getAllInstancesJi(Long jiId) {
return jiRepository.findById(jiId).instances;
}
///////////////////////////////////////////////////////////////////////////
/// Now that the JI is created, we want to add users to it and assign them
/// instances, but DONT create their containers yet !
@Transactional
public Instance createInstance(Long userId, Long jiId) {
Ji ji = jiRepository.findById(jiId);
Instance instance = instanceService.createInstance(userId, ji);
ji.instances.add(instance);
return instance;
}
@Transactional
public Instance getInstance(Long jiId, Long userId) {
Ji ji = jiRepository.findById(jiId);
for (Instance inst : ji.instances) {
if (inst.owner.id == userId) {
return inst;
}
}
throw new Error("Instance or user not found");
}
@Transactional
public void registerUser(Long userId, Long jiId) {
User user = userService.getUser(userId);
Ji ji = getJi(jiId);
ji.participants.add(user);
createInstance(userId, jiId);
}
///////////////////////////////////////////////////////////////////////////
/// Then, when an admin decides it, we create the containers
/*@Transactional
public void createContainer(Long jiId, Long userId) {
Ji ji = jiRepository.findById(jiId);
String username = userService.getUser(userId).name;
for (Instance instance : ji.instances) {
if (instance.name.equals(username + "-" + jiId)) {
instanceService.createContainer(instance.id);
break;
}
}
}*/
// On dit a toute les instances de creer leur container.
// Instance gere le cas ou le container existe deja.
@Transactional
public void createContainers(Long jiId) {
Ji ji = jiRepository.findById(jiId);
for (Instance instance : ji.instances) {
instanceService.createContainer(instance.id);
}
}
public String getStatusContainer(Long jiId, Long userId) {
Ji ji = jiRepository.findById(jiId);
String username = userService.getUser(userId).name;
String retour = "";
for (Instance instance : ji.instances) {
if (instance.name.equals(username + "-" + jiId)) {
if (instance.containerId.equals("Not created"))
return "Not created";
retour = instanceService.getStatusContainer(instance.id)
.toString()
.replaceAll(".*status=([^,]+).*", "$1");
break;
}
}
if (retour == "")
return "Not created";
return retour;
}
public String getStatusContainerInst(Long jiId, Long instId) {
Ji ji = jiRepository.findById(jiId);
Instance instance = instanceService.getInstance(instId);
String retour = "";
if (instance.containerId.equals("Not created"))
return "Not created";
retour = instanceService.getStatusContainer(instance.id)
.toString()
.replaceAll(".*status=([^,]+).*", "$1");
if (retour == "")
return "Not created";
return retour;
}
public String getOwnerInst(Long jiId, Long instId) {
Instance instance = instanceService.getInstance(instId);
return instance.owner.name;
}
public String getStatusContainers(Long jiId) {
Ji ji = jiRepository.findById(jiId);
String retour = "";
for (Instance instance : ji.instances) {
if (instance.containerId.equals("Not created"))
retour += "Not created";
else {
retour +=
instanceService.getStatusContainer(instance.id).toString();
}
}
return retour;
}
///////////////////////////////////////////////////////////////////////////
/// Finally, start/stop the containers
@Transactional
public void startContainers(Long jiId) {
Ji ji = jiRepository.findById(jiId);
for (Instance instance : ji.instances) {
instanceService.startContainer(instance.id);
}
}
@Transactional
public void stopContainers(Long jiId) {
Ji ji = jiRepository.findById(jiId);
for (Instance instance : ji.instances) {
instanceService.stopContainer(instance.id);
}
}
///////////////////////////////////////////////////////////////////////////
/// Last but not least, be able do delete every container and instance
@Transactional
public void deleteContainer(Long instanceId) {
instanceService.deleteContainer(instanceId);
}
@Transactional
public void deleteJi(Long jiId) {
Ji ji = getJi(jiId);
for (Instance instance : ji.instances) {
instanceService.deleteInstance(instance.id);
}
siteService.removeJi(ji.site, ji);
jiRepository.deleteById(jiId);
}
}

View File

@ -0,0 +1,45 @@
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;
}
public List<Site> getAllSites() { return siteRepository.listAll(); }
public Site getSite(Long id) { return siteRepository.findById(id); }
@Transactional
public void registerJi(Site site, Ji ji) {
site.listJi.add(ji);
}
@Transactional
public void removeJi(Site site, Ji ji) {
site.listJi.remove(ji);
}
@Transactional
public boolean deleteSite(Long id) {
if (getSite(id).listJi.isEmpty()) {
siteRepository.deleteById(id);
return true;
}
return false;
}
}

View File

@ -0,0 +1,100 @@
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;
Review

On utilise generalement les services des autres fonctionnalite plutot que leur repo, pour avoir une layer d'abstraction en moins. Par exemple, le SujetService peut acceder au SujetRepository mais devrait acceder aux methode du UserRepository a travers les methode de UserService

On utilise generalement les services des autres fonctionnalite plutot que leur repo, pour avoir une layer d'abstraction en moins. Par exemple, le SujetService peut acceder au SujetRepository mais devrait acceder aux methode du UserRepository a travers les methode de UserService
public List<Sujet> getAllSujetsAdmin() { return sujetRepository.listAll(); }
public List<Sujet> getAllSujetsRespo(String username) {
User user = userRepository.findByName(username);
return user.sujetRespo;
}
/*public PracticalResponse getTp(Long id, String username) {
Review

Le code commentee a une utilite ou peut etre supprime ?

Le code commentee a une utilite ou peut etre supprime ?
Review

faut faire les get pour en get qu un seul ou tous ceux dont l user est participant, et j pensais repartir de ca pour aps avoir a rechercher les commandes pour l user

faut faire les get pour en get qu un seul ou tous ceux dont l user est participant, et j pensais repartir de ca pour aps avoir a rechercher les commandes pour l user
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)) {
Review

Que se passe-t-il si le sujet/user n'existe pas ? Toujours controler l'input de l'utilisateur

Que se passe-t-il si le sujet/user n'existe pas ? Toujours controler l'input de l'utilisateur
Review

ca met une erreur degeue de la db, mais pour le moment j me suis absolument pas interesse a la gestion des erreurs

ca met une erreur degeue de la db, mais pour le moment j me suis absolument pas interesse a la gestion des erreurs
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)) {
arthur.wambst marked this conversation as resolved
Review

Meme problemes qu'au dessus

Meme problemes qu'au dessus
Review

done

done
sujet.respos.remove(user);
return true;
}
return false;
}
/*
* TODO: Seuls les respos du sujet et root doivent pouvoir avoir acces
Review

Je sais que c'est commente mais c'est fait au niveau des endpoints les checks d'acces

Je sais que c'est commente mais c'est fait au niveau des endpoints les checks d'acces
Review

aa okeee j changerai ca dans tout plus tard

aa okeee j changerai ca dans tout plus tard
* TODO: move ce todo et refactor poru que les check d acces soient dans
* rest et pas dans services
* @Transactional
public Sujet updateSujet(Long id) {
Sujet sujet = sujetRepository.findById(id);
return sujet;
}*/
}

View File

@ -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<Tp> getAllTpsAdmin() {
return tpRepository.listAll();
}
public List<Tp> getAllTps(String username) {
User user = userRepository.findByName(username);
List<Instance> 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;
}
}

View File

@ -1,19 +1,22 @@
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 fr.la_banquise.backend.rest.response.UserPostResponse;
import io.quarkus.elytron.security.common.BcryptUtil;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import java.util.List;
import java.util.Random;
/**
* UserService
@ -21,25 +24,46 @@ import jakarta.transaction.Transactional;
@ApplicationScoped
public class UserService {
@Inject
UserRepository userRepository;
@Inject UserRepository userRepository;
@Inject InstanceService instanceService;
@Inject JiService jiService;
@Inject JiRepository jiRepository;
@Inject
InstanceService instanceService;
public List<User> getAllUsers() { return userRepository.listAll(); }
public List<User> getAllUsers() {
return userRepository.listAll();
public User getUser(Long id) { return userRepository.findById(id); }
public User getUser(String name) { return userRepository.findByName(name); }
public Long getId(String name) {
return userRepository.findByName(name).id;
}
public User getUser(Long id) {
return userRepository.findById(id);
public boolean userExists(String name) {
try {
if (userRepository.findByName(name) != null)
return true;
return false;
} catch (Exception e) {
return false;
}
}
@Transactional
public User createUser(UserRequest request) {
User user = new User(request.name, BcryptUtil.bcryptHash(request.password), "pingouin", new ArrayList<>());
public UserPostResponse createUser(UserRequest request, String code) {
User user = new User(request.name,
BcryptUtil.bcryptHash(request.name.concat(code)),
RolesAsso.NONE, request.email);
userRepository.persist(user);
return user;
String passwd = request.name.concat(code);
UserPostResponse retour = new UserPostResponse(user, passwd);
return retour;
}
@Transactional
public UserPostResponse createUserRandom(UserRequest request) {
Random rand = new Random();
int random = rand.nextInt(8999) + 1000;
return createUser(request, String.valueOf(random));
}
@Transactional
@ -47,7 +71,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 +85,64 @@ 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.successNames.add(requestName.name);
} catch (Exception e) {
response.failedNames.add(requestName.name);
response.failedReasons.add(e.toString());
}
}
return response;
}
@Transactional
public List<User> createJdmiUser(BulkUserRequest usersRequest) {
List<User> 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);
public BulkUserPostResponse createUsers(BulkUserPostRequest usersRequest) {
BulkUserPostResponse response = new BulkUserPostResponse();
if (jiRepository.findById(usersRequest.jiId) != null) {
for (UserRequest user : usersRequest.users) {
if (!userExists(user.name)) {
UserPostResponse resp = createUserRandom(user);
response.successMails.add(resp.user.email);
response.successPasswd.add(resp.passwd);
jiService.registerUser(resp.user.id, usersRequest.jiId);
} else {
response.alreadyCreated.add(user.name);
}
}
}
return new ArrayList<User>();
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");
};
}
@Transactional
public void updateRole(String role, Long userId) {
User user = userRepository.findById(userId);
user.role.add(fromString(role));
}
@Transactional
public void removeRole(String role, Long userId) {
User user = userRepository.findById(userId);
user.role.remove(fromString(role));
}
}

View File

@ -25,14 +25,21 @@ quarkus.security.ldap.identity-mapping.attribute-mappings."0".filter-base-dn=ou=
%test.quarkus.security.ldap.dir-context.url=ldap://127.0.0.1:10389
# database
quarkus.datasource.db-kind = postgresql
quarkus.datasource.username = postgres
quarkus.datasource.password = secret
quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:5432/quarkus
%dev.quarkus.datasource.db-kind = postgresql
%dev.quarkus.datasource.username = banq
%dev.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=update
# quarkus.hibernate-orm.database.generation=drop-and-create
quarkus.quinoa.dev-server.port=5173
quarkus.quinoa.enable-spa-routing=true
quarkus.native.additional-build-args=--initialize-at-run-time=com.github.dockerjava.transport.NamedPipeSocket$Kernel32,--initialize-at-run-time=org.apache.hc.client5.http.impl.auth.NTLMEngineImpl
quarkus.docker.docker-host=unix:///var/run/docker.sock
#quarkus.security.auth.enabled-in-dev-mode=false
quarkus.hibernate-orm.sql-load-script=import-dev.sql

View File

@ -0,0 +1,6 @@
-- Ce fichier est exécuté automatiquement en mode dev
INSERT INTO penguin (name, password) VALUES ('root', '$2a$12$o8FSg6JaPwW4h9OnEDT0VOOlf2K/mVg.rhPyRbQzgKybqb9obYyGS');
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);

@ -1 +1 @@
Subproject commit 5ac4bc1c56d54190c9fec1db0881a97a768cd255
Subproject commit c7384837c34fd74326c64031cce3d05f577d6210