diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..0047e74 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,75 @@ +kind: pipeline +type: docker +name: default + +trigger: + event: + - push + +steps: + - name: build + image: mcr.microsoft.com/dotnet/sdk:8.0 + commands: + - dotnet restore API_dotnet.sln + - dotnet build API_dotnet.sln -c Release --no-restore + - dotnet publish API_dotnet.sln -c Release --no-restore -o $CI_PROJECT_DIR/build/release + + - name: tests + image: mcr.microsoft.com/dotnet/sdk:8.0 + commands: + - dotnet restore API_dotnet.sln + - dotnet test API_dotnet.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: Optifit_API_ef + commands: + - dotnet restore API_dotnet.sln + - dotnet sonarscanner begin /k:$${project_key} /d:sonar.host.url=$${sonar_host} /d:sonar.coverageReportPaths="coveragereport/SonarQube.xml" /d:sonar.login=$${sonar_token} + - dotnet build API_dotnet.sln -c Release --no-restore + - dotnet test API_dotnet.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 API_dotnet.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/optifit_ef_api + username: + from_secret: SECRET_REGISTRY_USERNAME + password: + from_secret: SECRET_REGISTRY_PASSWORD + when: + branch: + - main + - rebase + - pipeline + + - name: deploy-container + image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest + environment: + IMAGENAME: hub.codefirst.iut.uca.fr/louis.laborie/optifit_ef_api:latest + CONTAINERNAME: optifit-ef-api + COMMAND: create + OVERWRITE: true + CODEFIRST_CLIENTDRONE_ENV_ASPNETCORE_HTTP_PORTS: 80 + ADMINS: louislaborie,tonyfages,anthonyrichard + depends_on: + - docker-build-and-push \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6643758 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +WORKDIR /app + +EXPOSE 80 +EXPOSE 443 +EXPOSE 8080 +EXPOSE 8081 + +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["Infrastructure/Infrastructure.csproj", "Infrastructure/"] +COPY ["Server/Server.csproj", "Server/"] +COPY ["Shared/Shared.csproj", "Shared/"] +RUN dotnet restore "Server/Server.csproj" +COPY . . +WORKDIR "/src/Server" +RUN dotnet build "Server.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "Server.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + + + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Server.dll"] \ No newline at end of file diff --git a/Server/Controller/v1/UsersController.cs b/Server/Controller/v1/UsersController.cs index 4209c78..f62e714 100644 --- a/Server/Controller/v1/UsersController.cs +++ b/Server/Controller/v1/UsersController.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc; using Server.Dto.Request; using Server.Dto.Response; using Asp.Versioning; +using Microsoft.AspNetCore.Authorization; using Server.IServices; namespace Server.Controller.v1; @@ -39,4 +40,39 @@ public class UsersController : ControllerBase var alumni = _dataServices.GetUserById(id); return alumni.Result == null ? NotFound() : Ok(alumni); } + + [HttpPost] + [ProducesResponseType(typeof(ResponseUserDto), StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [AllowAnonymous] + public async Task CreateUser([FromBody] RequestUserDto request) + { + if (!ModelState.IsValid) return BadRequest(ModelState); + + var createdUser = await _dataServices.CreateUser(request); + return CreatedAtAction(nameof(GetAlumniById), new { id = createdUser.Id }, createdUser); + } + + [HttpPut("{id}")] + [ProducesResponseType(typeof(ResponseUserDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [AllowAnonymous] + public async Task UpdateUser(string id, [FromBody] RequestUserDto request) + { + if (!ModelState.IsValid) return BadRequest(ModelState); + + var updatedProgram = await _dataServices.UpdateUser(id, request); + return updatedProgram == null ? NotFound() : Ok(updatedProgram); + } + + [HttpDelete("{id}")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [AllowAnonymous] + public async Task DeleteUser(string id) + { + var deleted = await _dataServices.DeleteUser(id); + return deleted ? NoContent() : NotFound(); + } } \ No newline at end of file diff --git a/Server/Dockerfile b/Server/Dockerfile index 18264a1..da6efa5 100644 --- a/Server/Dockerfile +++ b/Server/Dockerfile @@ -24,4 +24,4 @@ RUN dotnet publish "Server.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:Us FROM base AS final WORKDIR /app COPY --from=publish /app/publish . -ENTRYPOINT ["dotnet", "Server.dll"] +ENTRYPOINT ["dotnet", "Server.dll"] \ No newline at end of file diff --git a/Server/IServices/IUsersService.cs b/Server/IServices/IUsersService.cs index c451027..831e88f 100644 --- a/Server/IServices/IUsersService.cs +++ b/Server/IServices/IUsersService.cs @@ -9,4 +9,8 @@ public interface IUsersService { Task GetUserById(string id); Task> GetUsers(int page, int size, bool ascending = true); + Task CreateUser(RequestUserDto request); + Task UpdateUser(string id, RequestUserDto request); + Task DeleteUser(string id); + } \ No newline at end of file diff --git a/Server/Program.cs b/Server/Program.cs index 9640653..1dee5c0 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -67,9 +67,9 @@ if (app.Environment.IsDevelopment()) c.SwaggerEndpoint("/swagger/v1/swagger.json", "Optifit API v1"); c.RoutePrefix = string.Empty; // Serve Swagger UI at the app's root }); + app.UseHttpsRedirection(); } -app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run(); \ No newline at end of file diff --git a/Server/Services/UsersService.cs b/Server/Services/UsersService.cs index 84e3105..60d6c66 100644 --- a/Server/Services/UsersService.cs +++ b/Server/Services/UsersService.cs @@ -3,6 +3,9 @@ using Infrastructure.Repositories; using Server.Dto.Response; using Server.IServices; using AutoMapper; +using Azure; +using Infrastructure.Entities; +using Server.Dto.Request; using Shared; namespace Server.Services; @@ -31,8 +34,39 @@ public class UsersService : IUsersService return userDto; } - public Task> GetUsers(int page, int size, bool ascending = true) + public async Task> GetUsers(int page, int size, bool ascending = true) { - throw new NotImplementedException(); + var users = await _userRepository.GetPaginatedListAsync(page - 1, size, null, null); + var result = _mapper.Map>(users); + return result; + } + + public async Task CreateUser(RequestUserDto request) + { + var user = _mapper.Map(request); + await _userRepository.InsertAsync(user); + await _context.SaveChangesAsync(); + return _mapper.Map(user); + } + + public async Task UpdateUser(string id,RequestUserDto request) + { + var user = await _userRepository.GetByIdAsync(id); + if (user == null) return null; + + _mapper.Map(request, user); + _userRepository.Update(user); + await _context.SaveChangesAsync(); + return _mapper.Map(user); + } + + public async Task DeleteUser(string id) + { + var user = await _userRepository.GetByIdAsync(id); + if (user == null) return false; + + _userRepository.Delete(id); + await _context.SaveChangesAsync(); + return true; } } \ No newline at end of file diff --git a/Shared/ECategory.cs b/Shared/ECategory.cs new file mode 100644 index 0000000..11f823a --- /dev/null +++ b/Shared/ECategory.cs @@ -0,0 +1,8 @@ +namespace Shared; + +public enum ECategory +{ + WARM_UP, + TRAINING, + STRETCHING +} \ No newline at end of file diff --git a/Shared/ETarget.cs b/Shared/ETarget.cs new file mode 100644 index 0000000..8e03c04 --- /dev/null +++ b/Shared/ETarget.cs @@ -0,0 +1,9 @@ +namespace Shared; + +public enum ETarget +{ + LEG, + ARM, + CARDIO, + HAMSTRING +} \ No newline at end of file