From 7b7efd5be88ecde74e9b09f34e75db4701855fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Konvi=C4=8Dka?= <konvicka.g630@gmail.com> Date: Sat, 6 Jan 2024 11:49:44 +0100 Subject: [PATCH] feat(#23): Add data validation --- ...compose.development.generated.override.yml | 21 ++++++++++ CodeToXMI.sln.DotSettings.user | 2 +- WebAPI/AuthenticateUserModel.cs | 7 ---- WebAPI/Controllers/ApiController.cs | 41 ++++++++++++++----- WebAPI/DTO/Attribute/Base64Attribute.cs | 25 +++++++++++ WebAPI/DTO/AuthenticateUserModel.cs | 14 +++++++ WebAPI/DTO/External/SourceCodeExt.cs | 11 +++++ WebAPI/DTO/RegisterUserModel.cs | 14 +++++++ WebAPI/DTO/RemoveCodeModel.cs | 12 ++++++ WebAPI/DTO/TokenDTO.cs | 12 ++++++ WebAPI/DTO/UploadCodeModel.cs | 13 ++++++ WebAPI/ListCodeModel.cs | 7 ---- WebAPI/RegisterUserModel.cs | 8 ---- WebAPI/RemoveCodeModel.cs | 7 ---- WebAPI/SourceCodeExt.cs | 7 ---- WebAPI/UploadCodeModel.cs | 7 ---- docker-compose.development.yaml | 12 ++++++ 17 files changed, 166 insertions(+), 54 deletions(-) create mode 100644 .idea/.idea.CodeToXMI/Docker/docker-compose.development.generated.override.yml delete mode 100644 WebAPI/AuthenticateUserModel.cs create mode 100644 WebAPI/DTO/Attribute/Base64Attribute.cs create mode 100644 WebAPI/DTO/AuthenticateUserModel.cs create mode 100644 WebAPI/DTO/External/SourceCodeExt.cs create mode 100644 WebAPI/DTO/RegisterUserModel.cs create mode 100644 WebAPI/DTO/RemoveCodeModel.cs create mode 100644 WebAPI/DTO/TokenDTO.cs create mode 100644 WebAPI/DTO/UploadCodeModel.cs delete mode 100644 WebAPI/ListCodeModel.cs delete mode 100644 WebAPI/RegisterUserModel.cs delete mode 100644 WebAPI/RemoveCodeModel.cs delete mode 100644 WebAPI/SourceCodeExt.cs delete mode 100644 WebAPI/UploadCodeModel.cs create mode 100644 docker-compose.development.yaml diff --git a/.idea/.idea.CodeToXMI/Docker/docker-compose.development.generated.override.yml b/.idea/.idea.CodeToXMI/Docker/docker-compose.development.generated.override.yml new file mode 100644 index 0000000..a1b94c4 --- /dev/null +++ b/.idea/.idea.CodeToXMI/Docker/docker-compose.development.generated.override.yml @@ -0,0 +1,21 @@ +# This is a generated file. Not intended for manual editing. +version: "3" +services: + codeToXMI_dev: + build: + context: "/Users/jakubkonvicka/RiderProjects/diplomathesis/WebAPI" + dockerfile: "Dockerfile" + target: "base" + command: [] + entrypoint: + - "dotnet" + - "/app/bin/Debug/net7.0/WebAPI.dll" + environment: + DOTNET_USE_POLLING_FILE_WATCHER: "true" + image: "webapi:dev" + ports: [] + volumes: + - "/Users/jakubkonvicka/.nuget/packages:/root/.nuget/packages" + - "/Users/jakubkonvicka/RiderProjects/diplomathesis/WebAPI:/app:rw" + - "/Users/jakubkonvicka/RiderProjects/diplomathesis:/src:rw" + working_dir: "/app" diff --git a/CodeToXMI.sln.DotSettings.user b/CodeToXMI.sln.DotSettings.user index 35ec7dd..b4ca132 100644 --- a/CodeToXMI.sln.DotSettings.user +++ b/CodeToXMI.sln.DotSettings.user @@ -1,7 +1,7 @@ <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue">/usr/local/share/dotnet/sdk/7.0.404/MSBuild.dll</s:String> <s:Int64 x:Key="/Default/Environment/Hierarchy/Build/BuildTool/MsbuildVersion/@EntryValue">1114112</s:Int64> - <s:String x:Key="/Default/Environment/Highlighting/HighlightingSourceSnapshotLocation/@EntryValue">/Users/jakubkonvicka/Library/Caches/JetBrains/Rider2023.2/resharper-host/temp/Rider/vAny/CoverageData/_CodeToXMI.401400098/Snapshot/snapshot.utdcvr</s:String> + <s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=7191ef50_002Dfb5e_002D4366_002D876f_002D7faeb1ecbf31/@EntryIndexedValue"><SessionState ContinuousTestingMode="0" IsActive="True" Name="BuildEmptyDiagram" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> <TestAncestor> <TestId>NUnit3x::0F37435B-F6C5-40D0-8250-192C843D1465::net7.0::UnitTest.ClassDiagramTests</TestId> diff --git a/WebAPI/AuthenticateUserModel.cs b/WebAPI/AuthenticateUserModel.cs deleted file mode 100644 index bd13ce3..0000000 --- a/WebAPI/AuthenticateUserModel.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace WebAPI; - -public class AuthenticateUserModel -{ - public string Username { get; set; } - public string Password { get; set; } -} \ No newline at end of file diff --git a/WebAPI/Controllers/ApiController.cs b/WebAPI/Controllers/ApiController.cs index 70406cc..7b7b67e 100644 --- a/WebAPI/Controllers/ApiController.cs +++ b/WebAPI/Controllers/ApiController.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.ComponentModel.DataAnnotations; using System.Text; using Antlr4.Runtime; using Antlr4.Runtime.Tree; @@ -8,10 +6,10 @@ using CodeParser.Cpp; using Database; using Database.Model; using DiagramBuilder.AbstractCreator; -using DiagramBuilder.Activity.Interface; using DiagramBuilder.ConcreteCreator; using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Logging; +using WebAPI.DTO; +using WebAPI.DTO.External; using WebAPI.Utils; namespace WebAPI.Controllers @@ -36,7 +34,17 @@ namespace WebAPI.Controllers //convert-to-activity-diagram [HttpGet("convert-to-activity-diagram", Name = "ConvertToActivityDiagram")] [Produces("application/xml")] - public IActionResult ConvertToActivityDiagram(string token, int sourceCodeId, string functionIdentifier) + public IActionResult ConvertToActivityDiagram( + [Required(ErrorMessage = "Token is required")] + [RegularExpression(@"^[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}$", ErrorMessage = "Invalid GUID format for Token")] + string token, + + [Required(ErrorMessage = "SourceCodeId is required")] + [Range(1, int.MaxValue, ErrorMessage = "Id must be greater than 0")] + int sourceCodeId, + + [Required(ErrorMessage = "FunctionIdentifier is required")] + string functionIdentifier) { if (TokenManager.VerifyAndRevalidateToken(token, tokenValidityMinutes)) { @@ -83,7 +91,13 @@ namespace WebAPI.Controllers //convert-to-class-diagram [HttpGet("convert-to-class-diagram", Name = "ConvertToClassDiagram")] [Produces("application/xml")] - public IActionResult ConvertToClassDiagram(string token, int sourceCodeId) + public IActionResult ConvertToClassDiagram([Required(ErrorMessage = "Token is required")] + [RegularExpression(@"^[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}$", ErrorMessage = "Invalid GUID format for Token")] + string token, + + [Required(ErrorMessage = "SourceCodeId is required")] + [Range(1, int.MaxValue, ErrorMessage = "Id must be greater than 0")] + int sourceCodeId) { if (TokenManager.VerifyAndRevalidateToken(token, tokenValidityMinutes)) { @@ -208,7 +222,13 @@ namespace WebAPI.Controllers } [HttpGet("code", Name = "ListCode")] - public IActionResult ListCode(string token, int id) + public IActionResult ListCode([Required(ErrorMessage = "Token is required")] + [RegularExpression(@"^[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}$", ErrorMessage = "Invalid GUID format for Token")] + string token, + + [Required(ErrorMessage = "Id is required")] + [Range(1, int.MaxValue, ErrorMessage = "Id must be greater than 0")] + int id) { if (TokenManager.VerifyAndRevalidateToken(token, tokenValidityMinutes)) { @@ -243,7 +263,8 @@ namespace WebAPI.Controllers } [HttpGet("code-all", Name = "ListAllCode")] - public IActionResult ListAllCode(string token) + public IActionResult ListAllCode([RegularExpression(@"^[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}$", ErrorMessage = "Invalid GUID format for Token")] + string token) { if (TokenManager.VerifyAndRevalidateToken(token, tokenValidityMinutes)) { @@ -317,7 +338,7 @@ namespace WebAPI.Controllers db.Users.Add(new User { - Name = model.UserName, + Name = model.Username, PasswordHash = passwordHash, Token = "NOT LOGGED IN YET", LastAccess = DateTime.MinValue diff --git a/WebAPI/DTO/Attribute/Base64Attribute.cs b/WebAPI/DTO/Attribute/Base64Attribute.cs new file mode 100644 index 0000000..78cbeee --- /dev/null +++ b/WebAPI/DTO/Attribute/Base64Attribute.cs @@ -0,0 +1,25 @@ +using System.ComponentModel.DataAnnotations; + +namespace WebAPI.DTO.Attribute; + +public class Base64Attribute : ValidationAttribute +{ + protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) + { + var errorMessage = $"{validationContext.DisplayName} must be a valid base64 string."; + if (value == null) + { + return ValidationResult.Success; + } + string stringValue = value.ToString(); + try + { + var fromBase64String = Convert.FromBase64String(stringValue); + return ValidationResult.Success; + } + catch (FormatException) + { + return new ValidationResult(errorMessage); + } + } +} \ No newline at end of file diff --git a/WebAPI/DTO/AuthenticateUserModel.cs b/WebAPI/DTO/AuthenticateUserModel.cs new file mode 100644 index 0000000..7ea5c08 --- /dev/null +++ b/WebAPI/DTO/AuthenticateUserModel.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; + +namespace WebAPI.DTO; + +public class AuthenticateUserModel +{ + [DisplayName("Username")] + [Required(ErrorMessage = "Username is required")] + public string Username { get; set; } + [DisplayName("Password")] + [Required(ErrorMessage = "Password is required")] + public string Password { get; set; } +} \ No newline at end of file diff --git a/WebAPI/DTO/External/SourceCodeExt.cs b/WebAPI/DTO/External/SourceCodeExt.cs new file mode 100644 index 0000000..e81f5cc --- /dev/null +++ b/WebAPI/DTO/External/SourceCodeExt.cs @@ -0,0 +1,11 @@ +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using WebAPI.DTO.Attribute; + +namespace WebAPI.DTO.External; + +public class SourceCodeExt +{ + public int Id { get; set; } + public string Code {get; set;} +} \ No newline at end of file diff --git a/WebAPI/DTO/RegisterUserModel.cs b/WebAPI/DTO/RegisterUserModel.cs new file mode 100644 index 0000000..24e2944 --- /dev/null +++ b/WebAPI/DTO/RegisterUserModel.cs @@ -0,0 +1,14 @@ +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; + +namespace WebAPI.DTO; + +public class RegisterUserModel : TokenDTO +{ + [DisplayName("Username")] + [Required(ErrorMessage = "Username is required")] + public string Username { get; set; } + [DisplayName("Password")] + [Required(ErrorMessage = "Password is required")] + public string Password { get; set; } +} \ No newline at end of file diff --git a/WebAPI/DTO/RemoveCodeModel.cs b/WebAPI/DTO/RemoveCodeModel.cs new file mode 100644 index 0000000..41c88a2 --- /dev/null +++ b/WebAPI/DTO/RemoveCodeModel.cs @@ -0,0 +1,12 @@ +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; + +namespace WebAPI.DTO; + +public class RemoveCodeModel : TokenDTO +{ + [DisplayName("Id")] + [Required(ErrorMessage = "Id is required")] + [Range(1, int.MaxValue, ErrorMessage = "Id must be greater than 0")] + public int Id { get; set; } +} \ No newline at end of file diff --git a/WebAPI/DTO/TokenDTO.cs b/WebAPI/DTO/TokenDTO.cs new file mode 100644 index 0000000..b210b2e --- /dev/null +++ b/WebAPI/DTO/TokenDTO.cs @@ -0,0 +1,12 @@ +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; + +namespace WebAPI.DTO; + +public abstract class TokenDTO +{ + [DisplayName("Token")] + [Required(ErrorMessage = "Token is required")] + [RegularExpression(@"^[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}$", ErrorMessage = "Invalid GUID format for Token")] + public string Token { get; set; } +} \ No newline at end of file diff --git a/WebAPI/DTO/UploadCodeModel.cs b/WebAPI/DTO/UploadCodeModel.cs new file mode 100644 index 0000000..a7982cc --- /dev/null +++ b/WebAPI/DTO/UploadCodeModel.cs @@ -0,0 +1,13 @@ +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using WebAPI.DTO.Attribute; + +namespace WebAPI.DTO; + +public class UploadCodeModel : TokenDTO +{ + [DisplayName("Code")] + [Required(ErrorMessage = "Code is required")] + [Base64(ErrorMessage = "Code must be a valid base64 string.")] + public string Code { get; set; } +} \ No newline at end of file diff --git a/WebAPI/ListCodeModel.cs b/WebAPI/ListCodeModel.cs deleted file mode 100644 index 4c4a309..0000000 --- a/WebAPI/ListCodeModel.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace WebAPI; - -public class ListCodeModel -{ - public string Token { get; set; } - public int[] Ids { get; set; } -} \ No newline at end of file diff --git a/WebAPI/RegisterUserModel.cs b/WebAPI/RegisterUserModel.cs deleted file mode 100644 index 5f1a221..0000000 --- a/WebAPI/RegisterUserModel.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace WebAPI; - -public class RegisterUserModel -{ - public string Token { get; set; } - public string UserName { get; set; } - public string Password { get; set; } -} \ No newline at end of file diff --git a/WebAPI/RemoveCodeModel.cs b/WebAPI/RemoveCodeModel.cs deleted file mode 100644 index f899f18..0000000 --- a/WebAPI/RemoveCodeModel.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace WebAPI; - -public class RemoveCodeModel -{ - public string Token { get; set; } - public int Id { get; set; } -} \ No newline at end of file diff --git a/WebAPI/SourceCodeExt.cs b/WebAPI/SourceCodeExt.cs deleted file mode 100644 index e616a23..0000000 --- a/WebAPI/SourceCodeExt.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace WebAPI; - -public class SourceCodeExt -{ - public int Id { get; set; } - public string Code {get; set;} -} \ No newline at end of file diff --git a/WebAPI/UploadCodeModel.cs b/WebAPI/UploadCodeModel.cs deleted file mode 100644 index 5b73670..0000000 --- a/WebAPI/UploadCodeModel.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace WebAPI; - -public class UploadCodeModel -{ - public string Token { get; set; } - public string Code { get; set; } -} \ No newline at end of file diff --git a/docker-compose.development.yaml b/docker-compose.development.yaml new file mode 100644 index 0000000..53e3428 --- /dev/null +++ b/docker-compose.development.yaml @@ -0,0 +1,12 @@ +version: '3' +services: + codeToXMI_dev: + container_name: CodeToXMI_API_dev + image: webapi:dev + build: + context: ./WebAPI/ + dockerfile: Dockerfile + ports: + - "7080:80" + environment: + - ASPNETCORE_ENVIRONMENT=Development \ No newline at end of file -- GitLab