Compare commits

..

No commits in common. 'master' and 'serviceApiJean' have entirely different histories.

@ -1,79 +0,0 @@
kind: pipeline
type: docker
name: default
trigger:
event:
- push
steps:
- name: build
image: mcr.microsoft.com/dotnet/sdk:8.0
commands:
- cd VeraxShield
- dotnet restore VeraxShield.sln
- dotnet build VeraxShield.sln -c Release --no-restore
- dotnet publish VeraxShield.sln -c Release --no-restore -o $CI_PROJECT_DIR/build/release
- name: tests
image: mcr.microsoft.com/dotnet/sdk:8.0
commands:
- cd VeraxShield
- dotnet restore VeraxShield.sln
- dotnet test VeraxShield.sln --no-restore
depends_on: [build]
- name: code-inspection
image: hub.codefirst.iut.uca.fr/marc.chevaldonne/codefirst-dronesonarplugin-dotnet8
secrets: [ SECRET_SONAR_LOGIN ]
environment:
sonar_host: https://codefirst.iut.uca.fr/sonar/
sonar_token:
from_secret: SECRET_SONAR_LOGIN # Secret de Drone
project_key: VeraxShield
commands:
- cd VeraxShield/
- dotnet restore VeraxShield.sln
- dotnet sonarscanner begin /k:$${project_key} /d:sonar.host.url=$${sonar_host} /d:sonar.coverageReportPaths="coveragereport/SonarQube.xml" /d:sonar.coverage.exclusions="VeraxShield/wwwroot/**","VeraxShield/composants/**","VeraxShield/pages/**","VeraxShield/Properties/**","TestVeraxShield/**","VeraxShield/Program.cs","VeraxShield/services/UtilisateursDataService/UtilisateursDataServiceApi.cs","VeraxShield/services/UtilisateursDataService/UtilisateursDataServiceFactice.cs" /d:sonar.login=$${sonar_token}
- dotnet build VeraxShield.sln -c Release --no-restore
- dotnet test VeraxShield.sln --logger trx --no-restore /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura --collect "XPlat Code Coverage"
- reportgenerator -reports:"**/coverage.cobertura.xml" -reporttypes:SonarQube -targetdir:"coveragereport"
- dotnet publish VeraxShield.sln -c Release --no-restore -o $CI_PROJECT_DIR/build/release
- dotnet sonarscanner end /d:sonar.login=$${sonar_token}
when:
branch:
- master
event:
- push
- pull_request
depends_on: [build,tests]
- name: docker-build-and-push
image: plugins/docker
settings:
dockerfile: dockerfile
context: .
registry: hub.codefirst.iut.uca.fr
repo: hub.codefirst.iut.uca.fr/louis.laborie/sae_2a_blazor
username:
from_secret: SECRET_REGISTRY_USERNAME
password:
from_secret: SECRET_REGISTRY_PASSWORD
when:
branch:
- master
- rebase
- name: deploy-container
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment:
IMAGENAME: hub.codefirst.iut.uca.fr/louis.laborie/sae_2a_blazor:latest
CONTAINERNAME: verax-blazor
COMMAND: create
OVERWRITE: true
CODEFIRST_CLIENTDRONE_ENV_ASPNETCORE_HTTP_PORTS: 80
ADMINS: louislaborie,tonyfages,noasillard,jeanmarcillac,shanacascarra
depends_on:
- docker-build-and-push

2
.gitignore vendored

@ -6,8 +6,6 @@
bin/
obj/
# Common node modules locations
/node_modules
/wwwroot/node_modules

@ -1,47 +1,2 @@
<h1 align="center">VeraxShield</h1>
# Blazor_SAE
<p align="center">
<img src="https://img.shields.io/badge/C%23-239120.svg?style=for-the-badge&logo=c-sharp&logoColor=white" alt="C#"/>
<img src="https://img.shields.io/badge/Blazor-512BD4.svg?style=for-the-badge&logo=blazor&logoColor=white" alt="Blazor"/>
<img src="https://img.shields.io/badge/.NET-512BD4.svg?style=for-the-badge&logo=.net&logoColor=white" alt=".NET"/>
<img src="https://img.shields.io/badge/HTML5-E34F26.svg?style=for-the-badge&logo=html5&logoColor=white" alt="HTML5"/>
<img src="https://img.shields.io/badge/CSS3-1572B6.svg?style=for-the-badge&logo=css3&logoColor=white" alt="CSS3"/>
</p>
## Description
VeraxShield est une application web avancée développée avec Blazor, représentant la partie administration de notre projet plus large, [Verax](https://codefirst.iut.uca.fr/git/Verax/Verax). Conçue pour offrir une interface de gestion intuitive, VeraxShield permet aux administrateurs de gérer efficacement les différents aspects du système Verax.
### Fonctionnalités Clés
- **Gestion des Utilisateurs** : Permet aux administrateurs de créer, modifier et supprimer des comptes utilisateurs. Inclut la gestion des rôles et des permissions pour un contrôle d'accès granulaire.
- **Notifications et Suivis des Actions** : Envoie des notifications sur les différentes actions des modérateurs afin pour assurer une meilleure gestion du système.
### Objectif du Projet
L'objectif principal de VeraxShield est de fournir une plateforme centralisée pour la gestion et le contrôle administratif du système Verax, en rationalisant les processus administratifs et en offrant une vue d'ensemble claire des opérations.
## Installation et Configuration
1. Clonez le dépôt : `git clone (https://codefirst.iut.uca.fr/git/Verax/Blazor_SAE.git)`
2. Ouvrez le fichier `VeraxShield.sln` avec Visual Studio.
3. Restaurez les packages nécessaires.
4. Lancez le projet depuis Visual Studio.
<h2 align="center">Equipe de Développement</h2>
<p align="center" >
<a href="https://codefirst.iut.uca.fr/git/louis.laborie" style="margin-right: 20px;">
<img src="img/Louis.png" width="50" height="50" title="Louis Laborie" alt="Louis Laborie"/>
</a>
<a href="https://codefirst.iut.uca.fr/git/shana.cascarra" style="margin-right: 20px;">
<img src="img/Shana.png" width="50" height="50" title="Shana Cascarra" alt="Shana Cascarra"/>
</a>
<a href="https://codefirst.iut.uca.fr/git/jean.marcillac" style="margin-right: 20px;">
<img src="img/Jean.png" width="50" height="50" title="Jean Marcillac" alt="Jean Marcillac"/>
</a>
<a href="https://codefirst.iut.uca.fr/git/tony.fages" style="margin-right: 20px;">
<img src="img/Tony.png" width="50" height="50" title="Tony Fages" alt="Tony Fages"/>
</a>
<a href="https://codefirst.iut.uca.fr/git/noa.sillard" style="margin-right: 20px;">
<img src="img/Noa.png" width="50" height="50" title="Noa Sillard" alt="Noa Sillard"/>
</a>
<p>

@ -1,15 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/.idea.VeraxShield.iml
/contentModel.xml
/modules.xml
/projectSettingsUpdater.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# GitHub Copilot persisted chat sessions
/copilot/chatSessions

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders>
<Path>../../Blazor_SAE</Path>
</attachedFolders>
<explicitIncludes />
<explicitExcludes />
</component>
</project>

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

@ -1,105 +0,0 @@
using System.Security.Claims;
using Moq;
using VeraxShield.composants.formulaires.modeles;
using VeraxShield.modele.utilisateurs;
using VeraxShield.services.UtilisateursDataService;
namespace TestVeraxShield;
public class AuthentificationServiceTests
{
private readonly AuthentificationService _authService;
private readonly Mock<IUtilisateursDataService> _mockDataService = new Mock<IUtilisateursDataService>();
public AuthentificationServiceTests()
{
_authService = new AuthentificationService(_mockDataService.Object);
}
[Fact]
public async Task Connexion_WithValidCredentials_ShouldSucceed()
{
// Arrange
var testUser = new Utilisateur("testUser", "Test", "User", "test@user.com", BCrypt.Net.BCrypt.HashPassword("password"), "User", false);
_mockDataService.Setup(s => s.getAllUtilisateurs())
.ReturnsAsync(new List<Utilisateur> { testUser });
var requete = new RequeteConnexion
{
Pseudo = "testUser",
MotDePasse = "password"
};
// Act & Assert
await _authService.Connexion(requete);
}
[Fact]
public async Task Connexion_WithInvalidCredentials_ShouldThrowException()
{
// Arrange
_mockDataService.Setup(s => s.getAllUtilisateurs())
.ReturnsAsync(new List<Utilisateur>());
var requete = new RequeteConnexion
{
Pseudo = "nonExistentUser",
MotDePasse = "wrongPassword"
};
// Act & Assert
await Assert.ThrowsAsync<Exception>(() => _authService.Connexion(requete));
}
[Fact]
public async Task Inscription_ShouldCreateNewUser()
{
// Arrange
var requete = new RequeteInscription
{
Pseudo = "newUser",
Nom = "New",
Prenom = "User",
Mail = "new@user.com",
MotDePasse = "newPassword"
};
// Setup the mock to verify that AjouterUtilisateur is called with a Utilisateur that matches the inscription details
_mockDataService.Setup(s => s.AjouterUtilisateur(It.IsAny<Utilisateur>()))
.Returns(Task.CompletedTask)
.Callback<Utilisateur>(u =>
{
Assert.Equal(requete.Pseudo, u.Pseudo);
Assert.True(BCrypt.Net.BCrypt.Verify(requete.MotDePasse, u.Mdp));
});
// Act
await _authService.Inscription(requete);
}
[Fact]
public async Task GetUtilisateur_ReturnsCorrectUser_WithClaims()
{
// Arrange
var expectedPseudo = "testUser";
var expectedRole = "User";
var testUser = new Utilisateur("testUser", "Test", "User", "test@user.com", BCrypt.Net.BCrypt.HashPassword("password"), "User", false);
var mockDataService = new Mock<IUtilisateursDataService>();
mockDataService.Setup(s => s.getAllUtilisateurs())
.ReturnsAsync(new List<Utilisateur> { testUser });
var authService = new AuthentificationService(mockDataService.Object);
// Act
var utilisateurCourant = await authService.GetUtilisateur(expectedPseudo);
utilisateurCourant.Claims.Add(ClaimTypes.Email, "test@user.com");
// Assert
Assert.NotNull(utilisateurCourant);
Assert.True(utilisateurCourant.EstAuthentifie);
Assert.Equal(expectedPseudo, utilisateurCourant.Pseudo);
}
}

@ -1,85 +0,0 @@
using Moq;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
using VeraxShield.composants.formulaires.modeles;
using VeraxShield.modele.utilisateurs;
using VeraxShield.services.UtilisateursDataService;
using Xunit;
namespace VeraxShield.UnitTests
{
public class DonneurEtatTests
{
private readonly DonneurEtat _donneurEtat;
private readonly Mock<IAuthentificationService> _mockAuthService;
private readonly Mock<IUtilisateursDataService> _mockUserDataService;
public DonneurEtatTests()
{
_mockAuthService = new Mock<IAuthentificationService>();
_mockUserDataService = new Mock<IUtilisateursDataService>();
_donneurEtat = new DonneurEtat(_mockAuthService.Object, _mockUserDataService.Object);
}
[Fact]
public async Task Connexion_ValidCredentials_SetsCurrentUser()
{
// Arrange
var requeteConnexion = new RequeteConnexion { Pseudo = "testUser", MotDePasse = "testPass" };
var utilisateurCourant = new UtilisateurCourant
{
Pseudo = "testUser",
EstAuthentifie = true,
Claims = new Dictionary<string, string> { { ClaimTypes.Role, "User" } }
};
_mockAuthService.Setup(x => x.GetUtilisateur(requeteConnexion.Pseudo)).ReturnsAsync(utilisateurCourant);
_mockAuthService.Setup(x => x.Connexion(requeteConnexion)).Returns(Task.CompletedTask);
// Act
await _donneurEtat.Connexion(requeteConnexion);
// Assert
Assert.NotNull(_donneurEtat._utilisateurCourant);
Assert.True(_donneurEtat._utilisateurCourant.EstAuthentifie);
_mockAuthService.Verify(x => x.Connexion(requeteConnexion), Times.Once);
_mockAuthService.Verify(x => x.GetUtilisateur(requeteConnexion.Pseudo), Times.Once);
}
[Fact]
public async Task Deconnexion_ClearsCurrentUser()
{
// Arrange - assume user is logged in
_donneurEtat._utilisateurCourant = new UtilisateurCourant { EstAuthentifie = true };
// Act
await _donneurEtat.Deconnexion();
// Assert
Assert.Null(_donneurEtat._utilisateurCourant);
}
[Fact]
public async Task Inscription_ValidData_RegistersUser()
{
// Arrange
var requeteInscription = new RequeteInscription
{
Pseudo = "newUser",
MotDePasse = "newPass",
Mail = "newUser@test.com",
Nom = "New",
Prenom = "User"
};
_mockAuthService.Setup(x => x.Inscription(requeteInscription)).Returns(Task.CompletedTask);
// Act
await _donneurEtat.Inscription(requeteInscription);
// Assert - Since Inscription does not automatically log in the user, we check if the method was called.
_mockAuthService.Verify(x => x.Inscription(requeteInscription), Times.Once);
}
}
}

@ -1,45 +0,0 @@
using Moq;
using VeraxShield.modele.utilisateurs;
using VeraxShield.services.UtilisateursDataService;
namespace TestVeraxShield;
public class IAuthentificationServiceTests
{
private readonly Mock<IUtilisateursDataService> _mockDataService;
private readonly AuthentificationService _authService;
public IAuthentificationServiceTests()
{
_mockDataService = new Mock<IUtilisateursDataService>();
_authService = new AuthentificationService(_mockDataService.Object);
}
[Fact]
public async Task GetUtilisateur_ValidUser_ReturnsUser()
{
// Arrange
var expectedUser = new UtilisateurCourant { Pseudo = "user1", EstAuthentifie = true };
_mockDataService.Setup(x => x.getAllUtilisateurs()).ReturnsAsync(new List<Utilisateur>
{
new Utilisateur("user1", "Name", "Surname", "user1@example.com", "password", "User", false)
});
// Act
var result = await _authService.GetUtilisateur("user1");
// Assert
Assert.Equal(expectedUser.Pseudo, result.Pseudo);
Assert.True(result.EstAuthentifie);
}
[Fact]
public async Task GetUtilisateur_NonExistentUser_ThrowsException()
{
// Arrange
_mockDataService.Setup(x => x.getAllUtilisateurs()).ReturnsAsync(new List<Utilisateur>());
// Act & Assert
await Assert.ThrowsAsync<Exception>(() => _authService.GetUtilisateur("user2"));
}
}

@ -1,25 +0,0 @@
using Moq;
using VeraxShield.modele.utilisateurs;
using VeraxShield.services.UtilisateursDataService;
namespace TestVeraxShield;
public class IUtilisateursDataServiceTests
{
private readonly Mock<IUtilisateursDataService> _service = new Mock<IUtilisateursDataService>();
[Fact]
public async Task AjouterUtilisateur_AddsUserSuccessfully()
{
// Arrange
var user = new Utilisateur("testUser", "User", "Test", "dez", "password", "User", false);
_service.Setup(s => s.AjouterUtilisateur(It.IsAny<Utilisateur>()))
.Returns(Task.CompletedTask)
.Callback<Utilisateur>(u => Assert.Equal("testUser", u.Pseudo));
// Act
await _service.Object.AjouterUtilisateur(user);
// Assert is handled by the Callback
}
}

@ -1,47 +0,0 @@
namespace TestVeraxShield;
public class ModeleAppUtilisateurTests
{
[Fact]
public void Constructeur_DoitInitialiserProprietes()
{
// Arrange & Act
var utilisateur = new ModeleAppUtilisateur("pseudoTest", "NomTest", "PrenomTest", "email@test.com", "motdepasse", "RoleTest");
// Assert
Assert.Equal("pseudoTest", utilisateur.Pseudo);
Assert.Equal("NomTest", utilisateur.Nom);
Assert.Equal("PrenomTest", utilisateur.Prenom);
Assert.Equal("email@test.com", utilisateur.Mail);
Assert.Equal("motdepasse", utilisateur.MotDePasse);
Assert.Contains("RoleTest", utilisateur.Roles);
}
[Fact]
public void AjouterRole_DoItAjouterNouveauRole()
{
// Arrange
var utilisateur = new ModeleAppUtilisateur("pseudoTest", "NomTest", "PrenomTest", "email@test.com", "motdepasse", "RoleTest");
// Act
utilisateur.ajouterRole("NouveauRole");
// Assert
Assert.Contains("NouveauRole", utilisateur.Roles);
}
[Fact]
public void SupprimerRole_DoItSupprimerRoleExistant()
{
// Arrange
var utilisateur = new ModeleAppUtilisateur("pseudoTest", "NomTest", "PrenomTest", "email@test.com", "motdepasse", "RoleTest");
utilisateur.ajouterRole("NouveauRole");
// Act
utilisateur.supprimerRole("RoleTest");
// Assert
Assert.DoesNotContain("RoleTest", utilisateur.Roles);
}
}

@ -1,57 +0,0 @@
namespace TestVeraxShield;
public class ModeleCurrentUserTests
{
[Fact]
public void InitializesCorrectly()
{
var utilisateur = new UtilisateurCourant();
Assert.Null(utilisateur.Claims);
Assert.False(utilisateur.EstAuthentifie);
Assert.Null(utilisateur.Pseudo);
}
[Fact]
public void AddsAndUpdatesClaimsCorrectly()
{
var utilisateur = new UtilisateurCourant { Claims = new Dictionary<string, string>() };
utilisateur.Claims.Add("role", "user");
Assert.Equal("user", utilisateur.Claims["role"]);
utilisateur.Claims["role"] = "admin";
Assert.Equal("admin", utilisateur.Claims["role"]);
}
[Fact]
public void RemovesClaimsCorrectly()
{
var utilisateur = new UtilisateurCourant { Claims = new Dictionary<string, string>() };
utilisateur.Claims.Add("role", "user");
utilisateur.Claims.Remove("role");
Assert.False(utilisateur.Claims.ContainsKey("role"));
}
[Fact]
public void TogglesAuthenticationState()
{
var utilisateur = new UtilisateurCourant();
utilisateur.EstAuthentifie = true;
Assert.True(utilisateur.EstAuthentifie);
utilisateur.EstAuthentifie = false;
Assert.False(utilisateur.EstAuthentifie);
}
[Fact]
public void UpdatesPseudoCorrectly()
{
var utilisateur = new UtilisateurCourant();
utilisateur.Pseudo = "TestUser";
Assert.Equal("TestUser", utilisateur.Pseudo);
}
}

@ -1,66 +0,0 @@
using VeraxShield.modele.utilisateurs;
namespace TestVeraxShield;
public class ModeleUtilisateurTests
{
[Fact]
public void ConstructorAssignsPropertiesCorrectly()
{
// Arrange
string expectedPseudo = "TestPseudo";
string expectedNom = "TestNom";
string expectedPrenom = "TestPrenom";
string expectedRole = "TestRole";
string expectedMdp = "TestMdp";
string expectedMail = "test@mail.com";
bool expectedIsBan = true;
// Act
Utilisateur utilisateur = new Utilisateur(expectedPseudo, expectedNom, expectedPrenom, expectedRole, expectedMdp, expectedMail, expectedIsBan);
// Assert
Assert.Equal(expectedPseudo, utilisateur.Pseudo);
Assert.Equal(expectedNom, utilisateur.Nom);
Assert.Equal(expectedPrenom, utilisateur.Prenom);
Assert.Equal(expectedRole, utilisateur.Role);
Assert.Equal(expectedMdp, utilisateur.Mdp);
Assert.Equal(expectedMail, utilisateur.Mail);
Assert.Equal(expectedIsBan, utilisateur.IsBan);
}
[Theory]
[InlineData("NewPseudo", "NewNom", "NewPrenom", "NewRole", "NewMdp", "new@mail.com", false)]
[InlineData("AnotherPseudo", "AnotherNom", "AnotherPrenom", "AnotherRole", "AnotherMdp", "another@mail.com", true)]
public void PropertiesUpdateCorrectly(string pseudo, string nom, string prenom, string role, string mdp, string mail, bool isBan)
{
// Arrange
Utilisateur utilisateur = new Utilisateur(pseudo, nom, prenom, role, mdp, mail, isBan);
// Act - changing values to test setter
string updatedPseudo = pseudo + "Update";
string updatedNom = nom + "Update";
string updatedPrenom = prenom + "Update";
string updatedRole = role + "Update";
string updatedMdp = mdp + "Update";
string updatedMail = "updated@" + mail;
bool updatedIsBan = !isBan;
utilisateur.Pseudo = updatedPseudo;
utilisateur.Nom = updatedNom;
utilisateur.Prenom = updatedPrenom;
utilisateur.Role = updatedRole;
utilisateur.Mdp = updatedMdp;
utilisateur.Mail = updatedMail;
utilisateur.IsBan = updatedIsBan;
// Assert
Assert.Equal(updatedPseudo, utilisateur.Pseudo);
Assert.Equal(updatedNom, utilisateur.Nom);
Assert.Equal(updatedPrenom, utilisateur.Prenom);
Assert.Equal(updatedRole, utilisateur.Role);
Assert.Equal(updatedMdp, utilisateur.Mdp);
Assert.Equal(updatedMail, utilisateur.Mail);
Assert.Equal(updatedIsBan, utilisateur.IsBan);
}
}

@ -1,47 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="bunit.web" Version="1.27.17" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0"/>
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="RichardSzalay.MockHttp" Version="7.0.0" />
<PackageReference Include="xunit" Version="2.4.2"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\VeraxShield\VeraxShield.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Remove="factoriesTests\**" />
<Compile Remove="ModeleTests\**" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Remove="factoriesTests\**" />
<EmbeddedResource Remove="ModeleTests\**" />
</ItemGroup>
<ItemGroup>
<None Remove="factoriesTests\**" />
<None Remove="ModeleTests\**" />
</ItemGroup>
</Project>

@ -1,56 +0,0 @@
using Microsoft.AspNetCore.Components;
using Moq;
using Newtonsoft.Json;
using RichardSzalay.MockHttp;
using VeraxShield.modele.utilisateurs;
using VeraxShield.services.UtilisateursDataService;
namespace TestVeraxShield;
public class UtilisateursDataServiceApiTests
{
private readonly MockHttpMessageHandler _mockHttp;
private readonly HttpClient _clientHttp;
private readonly Mock<NavigationManager> _mockNavigationManager;
private readonly UtilisateursDataServiceApi _service;
public UtilisateursDataServiceApiTests()
{
_mockHttp = new MockHttpMessageHandler();
// Mock the response for the API call
_mockHttp.When("https://Verax.com/api/utilisateurs/recuperer")
.Respond("application/json", JsonConvert.SerializeObject(new List<Utilisateur>
{
new Utilisateur("testUser", "User", "Test", "dez", "password", "User", false)
}));
_clientHttp = _mockHttp.ToHttpClient();
_clientHttp.BaseAddress = new System.Uri("https://Verax.com");
_mockNavigationManager = new Mock<NavigationManager>();
_service = new UtilisateursDataServiceApi(_clientHttp, _mockNavigationManager.Object);
}
[Fact]
public async Task GetAllUtilisateurs_ReturnsUsers()
{
// Act
var users = await _service.getAllUtilisateurs();
// Assert
Assert.Single(users);
Assert.Equal("testUser", users[0].Pseudo);
}
[Fact]
public async Task GetUtilisateurFromPseudo_ReturnsUser()
{
// Act
var user = await _service.getUtilisateurFromPseudo("testUser");
// Assert
Assert.Equal("testUser", user.Pseudo);
}
}

@ -1,56 +0,0 @@
namespace TestVeraxShield.factoriesTests;
using Xunit;
using VeraxShield.factories;
using VeraxShield.composants.formulaires.modeles;
using VeraxShield.modele.utilisateurs;
public class UtilisateursFactoryTests
{
[Fact]
public void ConvertsToUtilisateur_WithNewPasswordHashing()
{
// Arrange
var modele = new FormulaireAjoutModele { Mdp = "newPassword", /* other properties */ };
// Act
var utilisateur = UtilisateursFactory.toUtilisateur(modele);
// Assert
Assert.NotEqual("newPassword", utilisateur.Mdp);
}
[Fact]
public void ConvertsToModele_FromUtilisateur()
{
// Arrange
var utilisateur = new Utilisateur("pseudo", "nom", "prenom", "role", "mdp", "mail", false);
// Act
var modele = UtilisateursFactory.toModele(utilisateur);
// Assert
}
[Fact]
public void ConvertsToModele_FromUtilisateurs()
{
// Arrange
var utilisateur = new Utilisateur("pseudo", "nom", "prenom", "role", "mdp", "mail", false);
// Act
var modele = UtilisateursFactory.toModele(utilisateur);
// Assert
Assert.Equal(utilisateur.Pseudo, modele.Pseudo);
Assert.Equal(utilisateur.Nom, modele.Nom);
Assert.Equal(utilisateur.Prenom, modele.Prenom);
Assert.Equal(utilisateur.Role, modele.Role);
Assert.Equal(utilisateur.Mail, modele.Mail);
Assert.Equal(utilisateur.IsBan, modele.IsBan);
}
}

@ -5,8 +5,6 @@ VisualStudioVersion = 17.8.34322.80
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VeraxShield", "VeraxShield\VeraxShield.csproj", "{40D16910-ADA7-496E-BA48-AA9D6FF1E502}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestVeraxShield", "TestVeraxShield\TestVeraxShield.csproj", "{7924C3CD-C50B-41D1-8A93-C4E0AF0F1B3C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -17,10 +15,6 @@ Global
{40D16910-ADA7-496E-BA48-AA9D6FF1E502}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40D16910-ADA7-496E-BA48-AA9D6FF1E502}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40D16910-ADA7-496E-BA48-AA9D6FF1E502}.Release|Any CPU.Build.0 = Release|Any CPU
{7924C3CD-C50B-41D1-8A93-C4E0AF0F1B3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7924C3CD-C50B-41D1-8A93-C4E0AF0F1B3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7924C3CD-C50B-41D1-8A93-C4E0AF0F1B3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7924C3CD-C50B-41D1-8A93-C4E0AF0F1B3C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

@ -12,3 +12,17 @@
@* <Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router> *@

@ -13,17 +13,18 @@ var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
// Ajout du client http par d<>faut :
builder.Services.AddHttpClient();
// Service factice :
// Ajout du service de gestion des utilisateurs :
// On le met scoped, car c'est comme <20>a qu'est le service du localStorage alors sinon <20>a marche pas...
builder.Services.AddScoped<IUtilisateursDataService, UtilisateursDataServiceFactice>();
// Utilisation de l'api :
//builder.Services.AddScoped<IUtilisateursDataService, UtilisateursDataServiceApi>();
// Ajout du service pour le Blazored LocalStorage :
builder.Services.AddBlazoredLocalStorage();
// Ajout de Blazorise :
builder.Services
.AddBlazorise(options =>
{
@ -32,6 +33,7 @@ builder.Services
.AddBootstrapProviders()
.AddFontAwesomeIcons();
// Ajout de services pour l'authenfication :
builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<DonneurEtat>();

@ -10,7 +10,7 @@ namespace VeraxShield.composants.affichages.utilisateurs
public partial class DatagridUtilisateurs
{
[Inject]
private IUtilisateursDataService UtilisateursDataService { get; set; }
private IUtilisateursDataService utilisateursDataService { get; set; }
public static List<Utilisateur> Utilisateurs { get; set; }
@ -20,35 +20,37 @@ namespace VeraxShield.composants.affichages.utilisateurs
[Inject]
private DonneurEtat DonneurEtat {get; set;}
public static Utilisateur? UtilisateurSelectionne { get; set; }
public static Utilisateur? UtilisateurSelectionne;
[Parameter]
public ModalSuppressionUtilisateur Modal {get; set;}
protected override async Task OnInitializedAsync()
{
//await this.utilisateursDataService.resetDataUtilisateurs();
DatagridUtilisateurs.UtilisateurSelectionne = null;
DatagridUtilisateurs.Utilisateurs = await this.UtilisateursDataService.getAllUtilisateurs();
DatagridUtilisateurs.Utilisateurs = await this.utilisateursDataService.getAllUtilisateurs();
await base.OnInitializedAsync();
}
private async Task HandleUtilisateurSupprime()
{
DatagridUtilisateurs.Utilisateurs = await this.UtilisateursDataService.getAllUtilisateurs();
StateHasChanged();
DatagridUtilisateurs.Utilisateurs = await this.utilisateursDataService.getAllUtilisateurs();
StateHasChanged(); // Actualiser la vue
}
public async Task fermetureModal(bool suppressionConfirmee) {
public async Task fermetureModal(bool val) {
if (suppressionConfirmee) {
if (val) {
await this.supprimerUtilisateur(DatagridUtilisateurs.UtilisateurSelectionne);
}
}
public async Task supprimerUtilisateur(Utilisateur u)
{
await this.UtilisateursDataService.SupprimerUtilisateur(u);
DatagridUtilisateurs.Utilisateurs = await this.UtilisateursDataService.getAllUtilisateurs();
await this.utilisateursDataService.SupprimerUtilisateur(u);
DatagridUtilisateurs.Utilisateurs = await this.utilisateursDataService.getAllUtilisateurs();
this.NavigationManager.NavigateTo("/utilisateurs/liste");
}
@ -68,19 +70,18 @@ namespace VeraxShield.composants.affichages.utilisateurs
}
}
public async Task onClickBoutonSuppression(String pseudo)
public async Task onClickBoutonSuppression(String Pseudo)
{
DatagridUtilisateurs.UtilisateurSelectionne= await this.UtilisateursDataService.getUtilisateurFromPseudo(pseudo);
DatagridUtilisateurs.UtilisateurSelectionne= await this.utilisateursDataService.getUtilisateurFromPseudo(Pseudo);
if (this.DonneurEtat._utilisateurCourant.Pseudo != DatagridUtilisateurs.UtilisateurSelectionne.Pseudo)
{
await this.afficherModal();
}
}
public async Task onClickBoutonModification(String pseudo)
public async Task onClickBoutonModification(String Pseudo)
{
DatagridUtilisateurs.UtilisateurSelectionne = await this.UtilisateursDataService.getUtilisateurFromPseudo(pseudo);
DatagridUtilisateurs.UtilisateurSelectionne = await this.utilisateursDataService.getUtilisateurFromPseudo(Pseudo);
this.modifierUtilisateur();
}

@ -24,13 +24,14 @@ namespace VeraxShield.composants.authentification
private IUtilisateursDataService UtilisateursDataService {get; set;}
public String Erreur {get; set; }
public bool showPassword {get; set;}
public bool showPasswordConf {get; set;}
public bool showPassword = false;
public bool showPasswordConf = false;
protected override async Task OnInitializedAsync()
{
this.showPassword = false;
this.showPasswordConf = false;
this.Requete = new RequeteInscription();
DatagridUtilisateurs.Utilisateurs = await this.UtilisateursDataService.getAllUtilisateurs();
await base.OnInitializedAsync();

@ -21,6 +21,7 @@ namespace VeraxShield.composants.formulaires
[Inject]
private IUtilisateursDataService utilisateursDataService { get; set; }
protected override async Task OnInitializedAsync()
{
this.Modele = new FormulaireAjoutModele();
@ -31,11 +32,6 @@ namespace VeraxShield.composants.formulaires
{
if (await this.Validations.ValidateAll())
{
if(this.Modele.Mdp == null)
{
this.Modele.Mdp = this.Modele.Pseudo;
}
Utilisateur nouvelUtilisateur = UtilisateursFactory.toUtilisateur(this.Modele);
await this.utilisateursDataService.AjouterUtilisateur(nouvelUtilisateur);
this.NavigationManager.NavigateTo("/utilisateurs/liste");

@ -86,9 +86,9 @@
<div class="field-container">
<Validation>
<Field Horizontal>
<FieldLabel ColumnSize="ColumnSize.Is2">Modifier Mot de passe</FieldLabel>
<FieldLabel ColumnSize="ColumnSize.Is2">Mot de passe</FieldLabel>
<FieldBody ColumnSize="ColumnSize.Is10">
<TextEdit Placeholder="Nouveau mot de passe (facultatif)" @bind-Text="@Modele.Mdp">
<TextEdit Placeholder="Entrez votre mot de passe" @bind-Text="@Modele.Mdp">
<Feedback>
<ValidationError />
</Feedback>

@ -26,6 +26,8 @@ namespace VeraxShield.composants.formulaires
protected override async Task OnParametersSetAsync()
{
//PseudoCorrectAttribute.Initialiser(await this.utilisateursDataService.getAllUtilisateurs());
if (this.Utilisateur != null)
{
Utilisateur temp = new Utilisateur(" ", " ", " ", " ", " ", " ", true);
@ -42,14 +44,8 @@ namespace VeraxShield.composants.formulaires
protected async Task modifierUtilisateur()
{
if (await this.Validations.ValidateAll())
{
if (this.Modele.Mdp == null)
{
this.Modele.Mdp = Utilisateur.Mdp;
}
Utilisateur temp = UtilisateursFactory.toUtilisateur(this.Modele);
if (this.Utilisateur.Pseudo != this.Modele.Pseudo)

@ -28,6 +28,7 @@ namespace VeraxShield.composants.formulaires.modeles
[EmailAddress(ErrorMessage = "Veuillez entrer une adresse email valide.")]
public String Mail { get; set; }
[Required]
[RegularExpression("^[a-zA-Z0-9]+$", ErrorMessage = "Le mot de passe doit contenir uniquement des caractères alphanumériques.")]
public String Mdp { get; set; }
@ -50,7 +51,12 @@ namespace VeraxShield.composants.formulaires.modeles
public FormulaireAjoutModele()
{
Mdp = null;
//Pseudo = "temporairementVide";
//Nom = "temporairementVide";
//Prenom = "temporairementVide";
//Mail = "temporairementVide";
//Mdp = "temporairementVide";
//IsBan = true;
}
}
}

@ -8,6 +8,7 @@ namespace VeraxShield.composants.formulaires.modeles.attributsValidationCustoms
{
public class PseudoCorrectAttribute : ValidationAttribute
{
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
{
bool pseudoExisteDeja = false;
@ -15,6 +16,7 @@ namespace VeraxShield.composants.formulaires.modeles.attributsValidationCustoms
foreach (Utilisateur u in DatagridUtilisateurs.Utilisateurs)
{
if ((u.Pseudo == pseudo))
{
if (DatagridUtilisateurs.UtilisateurSelectionne == null) {

@ -1,6 +1,4 @@
using Blazorise.DataGrid;
using VeraxShield.composants.affichages.utilisateurs;
using VeraxShield.composants.formulaires.modeles;
using VeraxShield.composants.formulaires.modeles;
using VeraxShield.modele.utilisateurs;
namespace VeraxShield.factories
@ -9,27 +7,16 @@ namespace VeraxShield.factories
{
public static Utilisateur toUtilisateur(FormulaireAjoutModele modele)
{
if (DatagridUtilisateurs.UtilisateurSelectionne != null )
{
if (DatagridUtilisateurs.UtilisateurSelectionne.Mdp != modele.Mdp)
{
var motDePasseClair = modele.Mdp;
modele.Mdp = BCrypt.Net.BCrypt.HashPassword(motDePasseClair);
}
}
else
{
var motDePasseClair = modele.Mdp;
modele.Mdp = BCrypt.Net.BCrypt.HashPassword(motDePasseClair);
}
Utilisateur temp = new Utilisateur(
modele.Pseudo,
modele.Nom,
modele.Prenom,
modele.Role,
// ici hash
modele.Mdp,
modele.Mail,
modele.IsBan);
@ -44,7 +31,7 @@ namespace VeraxShield.factories
temp.Prenom = u.Prenom;
// ici dehash
//temp.Mdp = u.Mdp;
temp.Mdp = u.Mdp;
temp.Role = u.Role;

@ -1,4 +1,4 @@
public class ModeleAppUtilisateur
public class AppUtilisateur
{
public string MotDePasse { get; set; }
public List<string> Roles { get; set; }
@ -8,7 +8,7 @@ public class ModeleAppUtilisateur
public string Mail { get; set; }
public ModeleAppUtilisateur(string pseudo,string nom, string prenom, string mail, string mdp, String premierRole)
public AppUtilisateur(string pseudo,string nom, string prenom, string mail, string mdp, String premierRole)
{
this.MotDePasse = mdp;
this.Pseudo = pseudo;

@ -1,6 +1,25 @@
@using VeraxShield.composants.affichages.navBar;
@page "/"
<!--
<h1>VeraxShield</h1>
<button type="button" class="btn btn-link ml-md-auto" @onclick="@SeConnecter">Connexion</button>
<button type="button" class="btn btn-link ml-md-auto" @onclick="@NavBar">NavBar</button>
<AuthorizeView>
<h1> Adiu : @context.User.Identity.Name!</h1>
<p>Podètz veire aquest contengut solament se sètz autentificat ! </p>
<NavLink href="/utilisateurs/liste"> -> Liste des utilisateurs</NavLink>
<button type="button" class="btn btn-link ml-md-auto" @onclick="@SeDeconnecter">Deconnexion</button>
</AuthorizeView>
-->
<head>
<link rel="stylesheet" href="css/index.css">
</head>

@ -9,7 +9,6 @@ namespace VeraxShield.pages
[Inject]
private NavigationManager NavigationManager {get; set;}
private async Task SeDeconnecter()
{
await DonneurEtat.Deconnexion();

@ -14,9 +14,24 @@ namespace VeraxShield.pages.utilisateurs
[Inject]
private IUtilisateursDataService utilisateursDataService {get; set;}
//private Utilisateur utilisateur {get; set;}
protected override async Task OnInitializedAsync()
{
Console.WriteLine("Passage dans le OnInitializedAsync...");
this.Utilisateur = await this.utilisateursDataService.getUtilisateurFromPseudo(this.Pseudo);
if (Utilisateur != null)
{
Console.WriteLine("Pseudo du mec : " + this.Utilisateur.Pseudo);
}
else
{
Console.WriteLine("L'utilisateur est null...");
}
Console.WriteLine("Fin du OnInitializedParent");
await base.OnInitializedAsync();
}
}

@ -38,16 +38,25 @@ namespace VeraxShield.services.UtilisateursDataService
if (lUtilisateurs.Count == 0)
{
lUtilisateurs = await this.getUtilisateursFromJson(this.EmplacementJson);
// Cette boucle permet de hach les mdp des user du json
foreach (var user in lUtilisateurs)
{
var motDePasseClair = user.Mdp;
// Hach du mot de passe
user.Mdp = BCrypt.Net.BCrypt.HashPassword(motDePasseClair);
System.Console.WriteLine(user);
}
System.Console.WriteLine(lUtilisateurs);
await this.saveUtilisateursLocalStorage(lUtilisateurs);
Console.WriteLine("--> Le contenu du local storage a été écrasé !");
}
return lUtilisateurs;
}
@ -109,7 +118,9 @@ namespace VeraxShield.services.UtilisateursDataService
private async Task<List<Utilisateur>> getUtilisateursFromLocalStorage()
{
List<Utilisateur> utilisateursFromLocalStorage = null;
var data = await _localStorage.GetItemAsync<Utilisateur[]>(EmplacementLocalStorage);
//utilisateursFromLocalStorage = data.ToList();
if (data == null)
{

@ -0,0 +1,7 @@
@inherits LayoutComponentBase
<div class="main">
<div class="content px-4">
@Body
</div>
</div>

@ -1,34 +0,0 @@
# Première étape : Créer l'image de base
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
# Deuxième étape : Construire l'application
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
# Copier les fichiers nécessaires pour la restauration des dépendances
COPY ["dockerfile", "."]
COPY ["VeraxShield/VeraxShield/VeraxShield.csproj", "VeraxShield/"]
RUN dotnet restore "VeraxShield/VeraxShield.csproj"
# Copier le reste des fichiers
COPY . .
WORKDIR "/src/VeraxShield/VeraxShield"
RUN dotnet build "VeraxShield.csproj" -c Release -o /app/build
# Troisième étape : Publier l'application
FROM build AS publish
RUN dotnet publish "VeraxShield.csproj" -c Release -o /app/publish
# Quatrième étape : Créer l'image finale
FROM base AS final
WORKDIR /app
# Copier les fichiers publiés dans l'image finale
COPY --from=publish /app/publish .
# Définir le point d'entrée de l'application
ENTRYPOINT ["dotnet", "VeraxShield.dll"]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Loading…
Cancel
Save