From 49de8aa8d7467d00a60ca51dd19f494b6b210fc7 Mon Sep 17 00:00:00 2001 From: Tyler Wise Date: Sat, 19 Aug 2023 20:46:31 -0400 Subject: [PATCH] Doxy, -Wall -Werror, other cleanup and organization first round --- .../Attributes/ValidateModelStateAttribute.cs | 14 ++-- src/IO.Swagger/Controllers/AuthApi.cs | 35 ++++---- src/IO.Swagger/Controllers/CurrencyApi.cs | 47 ++++++----- src/IO.Swagger/Controllers/WalletApi.cs | 36 ++++---- src/IO.Swagger/Filters/BasePathFilter.cs | 5 +- .../GeneratePathParamsValidationFilter.cs | 14 ++-- src/IO.Swagger/IO.Swagger.csproj | 8 ++ ...130_Started transactions and currencies.cs | 4 +- .../{dto => RequestDto}/AuthLoginBody.cs | 22 ++--- .../{dto => RequestDto}/AuthRegisterBody.cs | 11 +-- .../CurrencyAddAssetBody.cs | 11 +-- .../{dto => RequestDto}/CurrencyCreateBody.cs | 19 ++--- .../CurrencyCreateCollectionBody.cs | 16 ++-- .../{dto => RequestDto}/CurrencyMintBody.cs | 32 ++------ .../WalletTransferDigitalBody.cs | 14 +--- .../WalletTransferPhysicalBody.cs | 41 +++++----- .../Models/ResponseDto/CurrencyDto.cs | 34 ++++++++ .../Models/ResponseDto/CurrencyInfoDto.cs | 31 +++++++ src/IO.Swagger/Models/ResponseDto/TokenDto.cs | 16 ++++ .../Models/ResponseDto/TransactionDto.cs | 54 ++++++++++++ src/IO.Swagger/Models/ResponseDto/UserDto.cs | 30 +++++++ .../Models/ResponseDto/WalletBalanceDto.cs | 23 ++++++ src/IO.Swagger/Models/db/Currency.cs | 44 +++++++++- src/IO.Swagger/Models/db/Transaction.cs | 69 ++++++++++++++-- src/IO.Swagger/Models/db/User.cs | 62 +++++++++++++- src/IO.Swagger/Models/dto/CurrencyDto.cs | 13 --- src/IO.Swagger/Models/dto/CurrencyInfoDto.cs | 9 -- src/IO.Swagger/Models/dto/TokenDto.cs | 7 -- src/IO.Swagger/Models/dto/TransactionDto.cs | 16 ---- src/IO.Swagger/Models/dto/UserDto.cs | 13 --- src/IO.Swagger/Models/dto/WalletBalanceDto.cs | 8 -- src/IO.Swagger/Program.cs | 2 +- .../Repositories/CurrencyRepository.cs | 25 ++++-- .../Repositories/ICurrencyRepository.cs | 23 +++++- .../Repositories/ITransactionRepository.cs | 36 +++++++- .../Repositories/IUserRepository.cs | 20 ++++- .../Repositories/TransactionRepository.cs | 25 ++++-- src/IO.Swagger/Repositories/UserRepository.cs | 29 ++++--- .../Security/BearerAuthenticationHandler.cs | 82 +++++++++---------- src/IO.Swagger/Services/BankDbContext.cs | 28 ++++++- src/IO.Swagger/Services/JwtService.cs | 22 +++-- src/IO.Swagger/Services/MapperProfile.cs | 9 +- src/IO.Swagger/Startup.cs | 23 +++--- 43 files changed, 728 insertions(+), 354 deletions(-) rename src/IO.Swagger/Models/{dto => RequestDto}/AuthLoginBody.cs (88%) rename src/IO.Swagger/Models/{dto => RequestDto}/AuthRegisterBody.cs (96%) rename src/IO.Swagger/Models/{dto => RequestDto}/CurrencyAddAssetBody.cs (96%) rename src/IO.Swagger/Models/{dto => RequestDto}/CurrencyCreateBody.cs (90%) rename src/IO.Swagger/Models/{dto => RequestDto}/CurrencyCreateCollectionBody.cs (93%) rename src/IO.Swagger/Models/{dto => RequestDto}/CurrencyMintBody.cs (79%) rename src/IO.Swagger/Models/{dto => RequestDto}/WalletTransferDigitalBody.cs (94%) rename src/IO.Swagger/Models/{dto => RequestDto}/WalletTransferPhysicalBody.cs (83%) create mode 100644 src/IO.Swagger/Models/ResponseDto/CurrencyDto.cs create mode 100644 src/IO.Swagger/Models/ResponseDto/CurrencyInfoDto.cs create mode 100644 src/IO.Swagger/Models/ResponseDto/TokenDto.cs create mode 100644 src/IO.Swagger/Models/ResponseDto/TransactionDto.cs create mode 100644 src/IO.Swagger/Models/ResponseDto/UserDto.cs create mode 100644 src/IO.Swagger/Models/ResponseDto/WalletBalanceDto.cs delete mode 100644 src/IO.Swagger/Models/dto/CurrencyDto.cs delete mode 100644 src/IO.Swagger/Models/dto/CurrencyInfoDto.cs delete mode 100644 src/IO.Swagger/Models/dto/TokenDto.cs delete mode 100644 src/IO.Swagger/Models/dto/TransactionDto.cs delete mode 100644 src/IO.Swagger/Models/dto/UserDto.cs delete mode 100644 src/IO.Swagger/Models/dto/WalletBalanceDto.cs diff --git a/src/IO.Swagger/Attributes/ValidateModelStateAttribute.cs b/src/IO.Swagger/Attributes/ValidateModelStateAttribute.cs index 07cfabe..9dca184 100644 --- a/src/IO.Swagger/Attributes/ValidateModelStateAttribute.cs +++ b/src/IO.Swagger/Attributes/ValidateModelStateAttribute.cs @@ -1,9 +1,9 @@ -using System.ComponentModel.DataAnnotations; -using System.Reflection; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.ModelBinding; +using System.ComponentModel.DataAnnotations; +using System.Reflection; namespace IO.Swagger.Attributes { @@ -19,14 +19,13 @@ namespace IO.Swagger.Attributes public override void OnActionExecuting(ActionExecutingContext context) { // Per https://blog.markvincze.com/how-to-validate-action-parameters-with-dataannotation-attributes/ - var descriptor = context.ActionDescriptor as ControllerActionDescriptor; - if (descriptor != null) + if (context.ActionDescriptor is ControllerActionDescriptor descriptor) { foreach (var parameter in descriptor.MethodInfo.GetParameters()) { object args = null; if (context.ActionArguments.ContainsKey(parameter.Name)) - { + { args = context.ActionArguments[parameter.Name]; } @@ -40,14 +39,13 @@ namespace IO.Swagger.Attributes } } - private void ValidateAttributes(ParameterInfo parameter, object args, ModelStateDictionary modelState) + private static void ValidateAttributes(ParameterInfo parameter, object args, ModelStateDictionary modelState) { foreach (var attributeData in parameter.CustomAttributes) { var attributeInstance = parameter.GetCustomAttribute(attributeData.AttributeType); - var validationAttribute = attributeInstance as ValidationAttribute; - if (validationAttribute != null) + if (attributeInstance is ValidationAttribute validationAttribute) { var isValid = validationAttribute.IsValid(args); if (!isValid) diff --git a/src/IO.Swagger/Controllers/AuthApi.cs b/src/IO.Swagger/Controllers/AuthApi.cs index 56262bc..1ba167b 100644 --- a/src/IO.Swagger/Controllers/AuthApi.cs +++ b/src/IO.Swagger/Controllers/AuthApi.cs @@ -7,24 +7,21 @@ * * Generated by: https://github.com/swagger-api/swagger-codegen.git */ -using System; -using System.Collections.Generic; +using AutoMapper; +using IO.Swagger.Attributes; +using IO.Swagger.Models.RequestDto; +using IO.Swagger.Models.ResponseDto; +using IO.Swagger.Repositories; +using IO.Swagger.Security; +using IO.Swagger.Services; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Annotations; -using Swashbuckle.AspNetCore.SwaggerGen; -using Newtonsoft.Json; -using System.ComponentModel.DataAnnotations; -using IO.Swagger.Attributes; -using IO.Swagger.Security; -using Microsoft.AspNetCore.Authorization; -using IO.Swagger.Models.dto; -using IO.Swagger.Repositories; -using System.Threading.Tasks; +using System; +using System.Collections.Generic; using System.Linq; -using IO.Swagger.Services; using System.Security.Claims; -using AutoMapper; -using Newtonsoft.Json.Linq; +using System.Threading.Tasks; namespace IO.Swagger.Controllers { @@ -85,12 +82,12 @@ namespace IO.Swagger.Controllers [SwaggerOperation("LoginUser")] [ProducesResponseType(typeof(TokenDto), 200)] [ProducesResponseType(typeof(IEnumerable), 400)] - public virtual async Task LoginUser([FromBody]AuthLoginBody body) + public virtual async Task LoginUser([FromBody] AuthLoginBody body) { if (!ModelState.IsValid) return BadRequest(ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage))); var user = await repository.LoginUser(body); - return user == null ? Unauthorized() : Ok(new TokenDto{ Token = jwt.GenerateJwt(user.Id) }); + return user == null ? Unauthorized() : Ok(new TokenDto { Token = jwt.GenerateJwt(user.Id) }); } /// @@ -107,13 +104,13 @@ namespace IO.Swagger.Controllers [SwaggerOperation("RegisterUser")] [ProducesResponseType(typeof(TokenDto), 200)] [ProducesResponseType(typeof(IEnumerable), 400)] - public async Task RegisterUser([FromBody]AuthRegisterBody body) + public async Task RegisterUser([FromBody] AuthRegisterBody body) { if (!ModelState.IsValid) return BadRequest(ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage))); - + var user = await repository.RegisterUser(body); - return user == null ? StatusCode(409) : Ok(new TokenDto{ Token = jwt.GenerateJwt(user.Id) }); + return user == null ? StatusCode(409) : Ok(new TokenDto { Token = jwt.GenerateJwt(user.Id) }); } } } diff --git a/src/IO.Swagger/Controllers/CurrencyApi.cs b/src/IO.Swagger/Controllers/CurrencyApi.cs index f1b97f1..b240be8 100644 --- a/src/IO.Swagger/Controllers/CurrencyApi.cs +++ b/src/IO.Swagger/Controllers/CurrencyApi.cs @@ -7,34 +7,43 @@ * * Generated by: https://github.com/swagger-api/swagger-codegen.git */ -using System; -using System.Collections.Generic; -using Microsoft.AspNetCore.Mvc; -using Swashbuckle.AspNetCore.Annotations; -using Swashbuckle.AspNetCore.SwaggerGen; -using Newtonsoft.Json; -using System.ComponentModel.DataAnnotations; +using AutoMapper; using IO.Swagger.Attributes; +using IO.Swagger.Models.RequestDto; +using IO.Swagger.Models.ResponseDto; +using IO.Swagger.Repositories; using IO.Swagger.Security; using Microsoft.AspNetCore.Authorization; -using IO.Swagger.Models.dto; +using Microsoft.AspNetCore.Mvc; +using Swashbuckle.AspNetCore.Annotations; +using System; +using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; -using IO.Swagger.Repositories; -using AutoMapper; namespace IO.Swagger.Controllers { /// /// /// + /// [ApiController] public class CurrencyApiController : ControllerBase { private readonly ICurrencyRepository repo; private readonly IMapper mapper; + /// + /// Initializes a new instance of the class. + /// + /// The repo. + /// The mapper. + /// + /// repo + /// or + /// mapper + /// public CurrencyApiController(ICurrencyRepository repo, IMapper mapper) { this.repo = repo ?? throw new ArgumentNullException(nameof(repo)); @@ -53,8 +62,8 @@ namespace IO.Swagger.Controllers [Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)] [ValidateModelState] [SwaggerOperation("AddDigitalAssetToCollection")] - public virtual IActionResult AddDigitalAssetToCollection([FromBody]CurrencyAddAssetBody body) - { + public virtual IActionResult AddDigitalAssetToCollection([FromBody] CurrencyAddAssetBody body) + { //TODO: Uncomment the next line to return response 201 or use other options such as return this.NotFound(), return this.BadRequest(..), ... // return StatusCode(201); @@ -79,8 +88,8 @@ namespace IO.Swagger.Controllers [Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)] [ValidateModelState] [SwaggerOperation("CreateAssetCollection")] - public virtual IActionResult CreateAssetCollection([FromBody]CurrencyCreateCollectionBody body) - { + public virtual IActionResult CreateAssetCollection([FromBody] CurrencyCreateCollectionBody body) + { //TODO: Uncomment the next line to return response 201 or use other options such as return this.NotFound(), return this.BadRequest(..), ... // return StatusCode(201); @@ -96,7 +105,7 @@ namespace IO.Swagger.Controllers /// /// Create a new currency type /// - /// + /// The currency to create /// Currency type created successfully /// Bad Request /// Unauthorized @@ -107,7 +116,7 @@ namespace IO.Swagger.Controllers [ValidateModelState] [SwaggerOperation("CreateCurrency")] [ProducesResponseType(typeof(IEnumerable), 400)] - public virtual async Task CreateCurrency([FromBody]CurrencyCreateBody body) + public virtual async Task CreateCurrency([FromBody] CurrencyCreateBody body) { var userIdString = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value; if (!int.TryParse(userIdString, out int userId)) @@ -123,7 +132,7 @@ namespace IO.Swagger.Controllers /// /// Mint additional units of a currency /// - /// + /// The information on the currency to mint /// Successful minting /// Bad Request /// Unauthorized @@ -134,7 +143,7 @@ namespace IO.Swagger.Controllers [ValidateModelState] [SwaggerOperation("MintCurrency")] [ProducesResponseType(typeof(IEnumerable), 400)] - public virtual async Task MintCurrency([FromBody]CurrencyMintBody body) + public virtual async Task MintCurrency([FromBody] CurrencyMintBody body) { var userIdString = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value; if (!int.TryParse(userIdString, out int userId)) @@ -151,7 +160,7 @@ namespace IO.Swagger.Controllers /// /// Returns all known currencies /// Unauthorized - [HttpPost] + [HttpGet] [Route("/v1/api/currency/getAll")] [Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)] [ValidateModelState] diff --git a/src/IO.Swagger/Controllers/WalletApi.cs b/src/IO.Swagger/Controllers/WalletApi.cs index 719e73b..b102712 100644 --- a/src/IO.Swagger/Controllers/WalletApi.cs +++ b/src/IO.Swagger/Controllers/WalletApi.cs @@ -7,27 +7,25 @@ * * Generated by: https://github.com/swagger-api/swagger-codegen.git */ -using System; -using System.Collections.Generic; -using Microsoft.AspNetCore.Mvc; -using Swashbuckle.AspNetCore.Annotations; -using Swashbuckle.AspNetCore.SwaggerGen; -using Newtonsoft.Json; -using System.ComponentModel.DataAnnotations; +using AutoMapper; using IO.Swagger.Attributes; +using IO.Swagger.Models.RequestDto; +using IO.Swagger.Models.ResponseDto; +using IO.Swagger.Repositories; using IO.Swagger.Security; using Microsoft.AspNetCore.Authorization; -using IO.Swagger.Models.dto; +using Microsoft.AspNetCore.Mvc; +using Swashbuckle.AspNetCore.Annotations; +using System; +using System.Collections.Generic; using System.Linq; using System.Security.Claims; -using IO.Swagger.Repositories; using System.Threading.Tasks; -using AutoMapper; namespace IO.Swagger.Controllers { /// - /// + /// The controller for accessing routes for wallet management /// [ApiController] public class WalletApiController : ControllerBase @@ -35,6 +33,16 @@ namespace IO.Swagger.Controllers private readonly ITransactionRepository transactionRepository; private readonly IMapper mapper; + /// + /// Initializes a new instance of the class. + /// + /// The transaction repository. + /// The mapper. + /// + /// transactionRepository + /// or + /// mapper + /// public WalletApiController(ITransactionRepository transactionRepository, IMapper mapper) { this.transactionRepository = transactionRepository ?? throw new ArgumentNullException(nameof(transactionRepository)); @@ -102,8 +110,8 @@ namespace IO.Swagger.Controllers [Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)] [ValidateModelState] [SwaggerOperation("TransferDigitalAsset")] - public virtual IActionResult TransferDigitalAsset([FromBody]WalletTransferDigitalBody body) - { + public virtual IActionResult TransferDigitalAsset([FromBody] WalletTransferDigitalBody body) + { //TODO: Uncomment the next line to return response 200 or use other options such as return this.NotFound(), return this.BadRequest(..), ... // return StatusCode(200); @@ -130,7 +138,7 @@ namespace IO.Swagger.Controllers [SwaggerOperation("TransferPhysicalCurrency")] [ProducesResponseType(typeof(IEnumerable), 400)] [ProducesResponseType(typeof(TransactionReturnCode), 409)] - public virtual async Task TransferPhysicalCurrency([FromBody]WalletTransferPhysicalBody body) + public virtual async Task TransferPhysicalCurrency([FromBody] WalletTransferPhysicalBody body) { var userIdString = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value; if (!int.TryParse(userIdString, out int userId)) diff --git a/src/IO.Swagger/Filters/BasePathFilter.cs b/src/IO.Swagger/Filters/BasePathFilter.cs index c9d95d6..a94d6a7 100644 --- a/src/IO.Swagger/Filters/BasePathFilter.cs +++ b/src/IO.Swagger/Filters/BasePathFilter.cs @@ -1,8 +1,7 @@ +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; using System.Linq; using System.Text.RegularExpressions; -using Swashbuckle.AspNetCore.Swagger; -using Swashbuckle.AspNetCore.SwaggerGen; -using Microsoft.OpenApi.Models; namespace IO.Swagger.Filters { diff --git a/src/IO.Swagger/Filters/GeneratePathParamsValidationFilter.cs b/src/IO.Swagger/Filters/GeneratePathParamsValidationFilter.cs index 1845e56..6154767 100644 --- a/src/IO.Swagger/Filters/GeneratePathParamsValidationFilter.cs +++ b/src/IO.Swagger/Filters/GeneratePathParamsValidationFilter.cs @@ -1,8 +1,8 @@ -using System.ComponentModel.DataAnnotations; -using System.Linq; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; +using System.ComponentModel.DataAnnotations; +using System.Linq; namespace IO.Swagger.Filters { @@ -42,7 +42,7 @@ namespace IO.Swagger.Filters string regex = (string)regexAttr.ConstructorArguments[0].Value; if (swaggerParam is OpenApiParameter) { - ((OpenApiParameter)swaggerParam).Schema.Pattern = regex; + swaggerParam.Schema.Pattern = regex; } } @@ -72,8 +72,8 @@ namespace IO.Swagger.Filters if (swaggerParam is OpenApiParameter) { - ((OpenApiParameter)swaggerParam).Schema.MinLength = minLenght; - ((OpenApiParameter)swaggerParam).Schema.MaxLength = maxLength; + swaggerParam.Schema.MinLength = minLenght; + swaggerParam.Schema.MaxLength = maxLength; } // Range [Range] @@ -85,8 +85,8 @@ namespace IO.Swagger.Filters if (swaggerParam is OpenApiParameter) { - ((OpenApiParameter)swaggerParam).Schema.Minimum = rangeMin; - ((OpenApiParameter)swaggerParam).Schema.Maximum = rangeMax; + swaggerParam.Schema.Minimum = rangeMin; + swaggerParam.Schema.Maximum = rangeMax; } } } diff --git a/src/IO.Swagger/IO.Swagger.csproj b/src/IO.Swagger/IO.Swagger.csproj index e956357..a5a8101 100644 --- a/src/IO.Swagger/IO.Swagger.csproj +++ b/src/IO.Swagger/IO.Swagger.csproj @@ -8,6 +8,14 @@ IO.Swagger IO.Swagger + + 9999 + True + + + 9999 + True + diff --git a/src/IO.Swagger/Migrations/20230819185130_Started transactions and currencies.cs b/src/IO.Swagger/Migrations/20230819185130_Started transactions and currencies.cs index 10656ab..c9b609d 100644 --- a/src/IO.Swagger/Migrations/20230819185130_Started transactions and currencies.cs +++ b/src/IO.Swagger/Migrations/20230819185130_Started transactions and currencies.cs @@ -1,5 +1,5 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations; +using System; #nullable disable diff --git a/src/IO.Swagger/Models/dto/AuthLoginBody.cs b/src/IO.Swagger/Models/RequestDto/AuthLoginBody.cs similarity index 88% rename from src/IO.Swagger/Models/dto/AuthLoginBody.cs rename to src/IO.Swagger/Models/RequestDto/AuthLoginBody.cs index b76d7e1..81dff65 100644 --- a/src/IO.Swagger/Models/dto/AuthLoginBody.cs +++ b/src/IO.Swagger/Models/RequestDto/AuthLoginBody.cs @@ -7,18 +7,12 @@ * * Generated by: https://github.com/swagger-api/swagger-codegen.git */ -using System; -using System.Linq; -using System.IO; -using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; using Newtonsoft.Json; +using System; +using System.Runtime.Serialization; +using System.Text; -namespace IO.Swagger.Models.dto +namespace IO.Swagger.Models.RequestDto { /// /// @@ -48,8 +42,8 @@ namespace IO.Swagger.Models.dto { var sb = new StringBuilder(); sb.Append("class AuthLoginBody {\n"); - sb.Append(" Email: ").Append(Email).Append("\n"); - sb.Append(" Password: ").Append(Password).Append("\n"); + sb.Append(" Email: ").Append(Email).Append('\n'); + sb.Append(" Password: ").Append(Password).Append('\n'); sb.Append("}\n"); return sb.ToString(); } @@ -70,7 +64,7 @@ namespace IO.Swagger.Models.dto /// Boolean public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) return false; + if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; return obj.GetType() == GetType() && Equals((AuthLoginBody)obj); } @@ -82,7 +76,7 @@ namespace IO.Swagger.Models.dto /// Boolean public bool Equals(AuthLoginBody other) { - if (ReferenceEquals(null, other)) return false; + if (other is null) return false; if (ReferenceEquals(this, other)) return true; return diff --git a/src/IO.Swagger/Models/dto/AuthRegisterBody.cs b/src/IO.Swagger/Models/RequestDto/AuthRegisterBody.cs similarity index 96% rename from src/IO.Swagger/Models/dto/AuthRegisterBody.cs rename to src/IO.Swagger/Models/RequestDto/AuthRegisterBody.cs index ef2c3eb..c1f0f20 100644 --- a/src/IO.Swagger/Models/dto/AuthRegisterBody.cs +++ b/src/IO.Swagger/Models/RequestDto/AuthRegisterBody.cs @@ -7,18 +7,13 @@ * * Generated by: https://github.com/swagger-api/swagger-codegen.git */ +using Newtonsoft.Json; using System; -using System.Linq; -using System.IO; -using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; -using Newtonsoft.Json; +using System.Text; -namespace IO.Swagger.Models.dto +namespace IO.Swagger.Models.RequestDto { /// /// diff --git a/src/IO.Swagger/Models/dto/CurrencyAddAssetBody.cs b/src/IO.Swagger/Models/RequestDto/CurrencyAddAssetBody.cs similarity index 96% rename from src/IO.Swagger/Models/dto/CurrencyAddAssetBody.cs rename to src/IO.Swagger/Models/RequestDto/CurrencyAddAssetBody.cs index ab21642..9e01b2a 100644 --- a/src/IO.Swagger/Models/dto/CurrencyAddAssetBody.cs +++ b/src/IO.Swagger/Models/RequestDto/CurrencyAddAssetBody.cs @@ -7,18 +7,13 @@ * * Generated by: https://github.com/swagger-api/swagger-codegen.git */ +using Newtonsoft.Json; using System; -using System.Linq; -using System.IO; -using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; -using Newtonsoft.Json; +using System.Text; -namespace IO.Swagger.Models.dto +namespace IO.Swagger.Models.RequestDto { /// /// diff --git a/src/IO.Swagger/Models/dto/CurrencyCreateBody.cs b/src/IO.Swagger/Models/RequestDto/CurrencyCreateBody.cs similarity index 90% rename from src/IO.Swagger/Models/dto/CurrencyCreateBody.cs rename to src/IO.Swagger/Models/RequestDto/CurrencyCreateBody.cs index 092c278..7327ec4 100644 --- a/src/IO.Swagger/Models/dto/CurrencyCreateBody.cs +++ b/src/IO.Swagger/Models/RequestDto/CurrencyCreateBody.cs @@ -7,18 +7,13 @@ * * Generated by: https://github.com/swagger-api/swagger-codegen.git */ +using Newtonsoft.Json; using System; -using System.Linq; -using System.IO; -using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; -using Newtonsoft.Json; +using System.Text; -namespace IO.Swagger.Models.dto +namespace IO.Swagger.Models.RequestDto { /// /// @@ -50,8 +45,8 @@ namespace IO.Swagger.Models.dto { var sb = new StringBuilder(); sb.Append("class CurrencyCreateBody {\n"); - sb.Append(" Name: ").Append(Name).Append("\n"); - sb.Append(" Symbol: ").Append(Symbol).Append("\n"); + sb.Append(" Name: ").Append(Name).Append('\n'); + sb.Append(" Symbol: ").Append(Symbol).Append('\n'); sb.Append("}\n"); return sb.ToString(); } @@ -72,7 +67,7 @@ namespace IO.Swagger.Models.dto /// Boolean public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) return false; + if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; return obj.GetType() == GetType() && Equals((CurrencyCreateBody)obj); } @@ -84,7 +79,7 @@ namespace IO.Swagger.Models.dto /// Boolean public bool Equals(CurrencyCreateBody other) { - if (ReferenceEquals(null, other)) return false; + if (other is null) return false; if (ReferenceEquals(this, other)) return true; return diff --git a/src/IO.Swagger/Models/dto/CurrencyCreateCollectionBody.cs b/src/IO.Swagger/Models/RequestDto/CurrencyCreateCollectionBody.cs similarity index 93% rename from src/IO.Swagger/Models/dto/CurrencyCreateCollectionBody.cs rename to src/IO.Swagger/Models/RequestDto/CurrencyCreateCollectionBody.cs index e0942c5..3571e6a 100644 --- a/src/IO.Swagger/Models/dto/CurrencyCreateCollectionBody.cs +++ b/src/IO.Swagger/Models/RequestDto/CurrencyCreateCollectionBody.cs @@ -7,18 +7,12 @@ * * Generated by: https://github.com/swagger-api/swagger-codegen.git */ -using System; -using System.Linq; -using System.IO; -using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; using Newtonsoft.Json; +using System; +using System.Runtime.Serialization; +using System.Text; -namespace IO.Swagger.Models.dto +namespace IO.Swagger.Models.RequestDto { /// /// @@ -78,7 +72,7 @@ namespace IO.Swagger.Models.dto if (ReferenceEquals(this, other)) return true; return - + CollectionName == other.CollectionName || CollectionName != null && CollectionName.Equals(other.CollectionName) diff --git a/src/IO.Swagger/Models/dto/CurrencyMintBody.cs b/src/IO.Swagger/Models/RequestDto/CurrencyMintBody.cs similarity index 79% rename from src/IO.Swagger/Models/dto/CurrencyMintBody.cs rename to src/IO.Swagger/Models/RequestDto/CurrencyMintBody.cs index 7f1c62f..18af445 100644 --- a/src/IO.Swagger/Models/dto/CurrencyMintBody.cs +++ b/src/IO.Swagger/Models/RequestDto/CurrencyMintBody.cs @@ -7,18 +7,13 @@ * * Generated by: https://github.com/swagger-api/swagger-codegen.git */ +using Newtonsoft.Json; using System; -using System.Linq; -using System.IO; -using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; -using Newtonsoft.Json; +using System.Text; -namespace IO.Swagger.Models.dto +namespace IO.Swagger.Models.RequestDto { /// /// @@ -50,8 +45,8 @@ namespace IO.Swagger.Models.dto { var sb = new StringBuilder(); sb.Append("class CurrencyMintBody {\n"); - sb.Append(" CurrencyId: ").Append(CurrencyId).Append("\n"); - sb.Append(" Amount: ").Append(Amount).Append("\n"); + sb.Append(" CurrencyId: ").Append(CurrencyId).Append('\n'); + sb.Append(" Amount: ").Append(Amount).Append('\n'); sb.Append("}\n"); return sb.ToString(); } @@ -72,7 +67,7 @@ namespace IO.Swagger.Models.dto /// Boolean public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) return false; + if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; return obj.GetType() == GetType() && Equals((CurrencyMintBody)obj); } @@ -84,18 +79,16 @@ namespace IO.Swagger.Models.dto /// Boolean public bool Equals(CurrencyMintBody other) { - if (ReferenceEquals(null, other)) return false; + if (other is null) return false; if (ReferenceEquals(this, other)) return true; return ( CurrencyId == other.CurrencyId || - CurrencyId != null && CurrencyId.Equals(other.CurrencyId) ) && ( Amount == other.Amount || - Amount != null && Amount.Equals(other.Amount) ); } @@ -106,16 +99,7 @@ namespace IO.Swagger.Models.dto /// Hash code public override int GetHashCode() { - unchecked // Overflow is fine, just wrap - { - var hashCode = 41; - // Suitable nullity checks etc, of course :) - if (CurrencyId != null) - hashCode = hashCode * 59 + CurrencyId.GetHashCode(); - if (Amount != null) - hashCode = hashCode * 59 + Amount.GetHashCode(); - return hashCode; - } + return HashCode.Combine(CurrencyId, Amount); } #region Operators diff --git a/src/IO.Swagger/Models/dto/WalletTransferDigitalBody.cs b/src/IO.Swagger/Models/RequestDto/WalletTransferDigitalBody.cs similarity index 94% rename from src/IO.Swagger/Models/dto/WalletTransferDigitalBody.cs rename to src/IO.Swagger/Models/RequestDto/WalletTransferDigitalBody.cs index 6e3b5db..0b419f0 100644 --- a/src/IO.Swagger/Models/dto/WalletTransferDigitalBody.cs +++ b/src/IO.Swagger/Models/RequestDto/WalletTransferDigitalBody.cs @@ -7,18 +7,12 @@ * * Generated by: https://github.com/swagger-api/swagger-codegen.git */ -using System; -using System.Linq; -using System.IO; -using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; using Newtonsoft.Json; +using System; +using System.Runtime.Serialization; +using System.Text; -namespace IO.Swagger.Models.dto +namespace IO.Swagger.Models.RequestDto { /// /// diff --git a/src/IO.Swagger/Models/dto/WalletTransferPhysicalBody.cs b/src/IO.Swagger/Models/RequestDto/WalletTransferPhysicalBody.cs similarity index 83% rename from src/IO.Swagger/Models/dto/WalletTransferPhysicalBody.cs rename to src/IO.Swagger/Models/RequestDto/WalletTransferPhysicalBody.cs index 5d68be0..b65224e 100644 --- a/src/IO.Swagger/Models/dto/WalletTransferPhysicalBody.cs +++ b/src/IO.Swagger/Models/RequestDto/WalletTransferPhysicalBody.cs @@ -7,18 +7,13 @@ * * Generated by: https://github.com/swagger-api/swagger-codegen.git */ +using Newtonsoft.Json; using System; -using System.Linq; -using System.IO; -using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; -using Newtonsoft.Json; +using System.Text; -namespace IO.Swagger.Models.dto +namespace IO.Swagger.Models.RequestDto { /// /// @@ -34,19 +29,25 @@ namespace IO.Swagger.Models.dto public string DestUserEmail { get; set; } /// - /// Gets or Sets Amount + /// Gets or Sets Amount of the transaction /// - [Range(0.1, float.MaxValue, ErrorMessage="Please enter a valid transfer amount")] + [Range(0.1, float.MaxValue, ErrorMessage = "Please enter a valid transfer amount")] [DataMember(Name = "amount")] public float Amount { get; set; } /// - /// Gets or Sets CurrencyId + /// Gets or Sets CurrencyId the transaction will be performed with /// [Required] [DataMember(Name = "currencyId")] public int CurrencyId { get; set; } + /// + /// Gets or sets the memo of the transaction. + /// + /// + /// The memo. + /// [DataMember(Name = "memo")] [StringLength(32, MinimumLength = 2)] [Required] @@ -60,9 +61,9 @@ namespace IO.Swagger.Models.dto { var sb = new StringBuilder(); sb.Append("class WalletTransferPhysicalBody {\n"); - sb.Append(" DestUserEmail: ").Append(DestUserEmail).Append("\n"); - sb.Append(" Amount: ").Append(Amount).Append("\n"); - sb.Append(" CurrencyId: ").Append(CurrencyId).Append("\n"); + sb.Append(" DestUserEmail: ").Append(DestUserEmail).Append('\n'); + sb.Append(" Amount: ").Append(Amount).Append('\n'); + sb.Append(" CurrencyId: ").Append(CurrencyId).Append('\n'); sb.Append("}\n"); return sb.ToString(); } @@ -83,7 +84,7 @@ namespace IO.Swagger.Models.dto /// Boolean public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) return false; + if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; return obj.GetType() == GetType() && Equals((WalletTransferPhysicalBody)obj); } @@ -95,7 +96,7 @@ namespace IO.Swagger.Models.dto /// Boolean public bool Equals(WalletTransferPhysicalBody other) { - if (ReferenceEquals(null, other)) return false; + if (other is null) return false; if (ReferenceEquals(this, other)) return true; return @@ -106,12 +107,10 @@ namespace IO.Swagger.Models.dto ) && ( Amount == other.Amount || - Amount != null && Amount.Equals(other.Amount) ) && ( CurrencyId == other.CurrencyId || - CurrencyId != null && CurrencyId.Equals(other.CurrencyId) ); } @@ -128,10 +127,8 @@ namespace IO.Swagger.Models.dto // Suitable nullity checks etc, of course :) if (DestUserEmail != null) hashCode = hashCode * 59 + DestUserEmail.GetHashCode(); - if (Amount != null) - hashCode = hashCode * 59 + Amount.GetHashCode(); - if (CurrencyId != null) - hashCode = hashCode * 59 + CurrencyId.GetHashCode(); + hashCode = hashCode * 59 + Amount.GetHashCode(); + hashCode = hashCode * 59 + CurrencyId.GetHashCode(); return hashCode; } } diff --git a/src/IO.Swagger/Models/ResponseDto/CurrencyDto.cs b/src/IO.Swagger/Models/ResponseDto/CurrencyDto.cs new file mode 100644 index 0000000..201d3e7 --- /dev/null +++ b/src/IO.Swagger/Models/ResponseDto/CurrencyDto.cs @@ -0,0 +1,34 @@ +using System.ComponentModel.DataAnnotations; + +namespace IO.Swagger.Models.ResponseDto +{ + /// + /// The output DTO for basic currency information + /// + public class CurrencyDto + { + /// + /// Gets or sets the currency identifier. + /// + /// + /// The currency identifier. + /// + public int CurrencyId { get; set; } + /// + /// Gets or sets the name of the currency. + /// + /// + /// The name. + /// + [StringLength(32, MinimumLength = 1)] + public string Name { get; set; } + /// + /// Gets or sets the symbol of the currency. + /// + /// + /// The symbol. + /// + [StringLength(4, MinimumLength = 1)] + public string Symbol { get; set; } + } +} diff --git a/src/IO.Swagger/Models/ResponseDto/CurrencyInfoDto.cs b/src/IO.Swagger/Models/ResponseDto/CurrencyInfoDto.cs new file mode 100644 index 0000000..4c61dd3 --- /dev/null +++ b/src/IO.Swagger/Models/ResponseDto/CurrencyInfoDto.cs @@ -0,0 +1,31 @@ +namespace IO.Swagger.Models.ResponseDto +{ + /// + /// The DTO for returning detailed currency information + /// + /// + public class CurrencyInfoDto : CurrencyDto + { + /// + /// Gets or sets the currency owner. + /// + /// + /// The currency owner. + /// + public UserDto CurrencyOwner { get; set; } + /// + /// Gets or sets a value indicating whether this logged in user is the owner of this currency. + /// + /// + /// true if this instance is owner; otherwise, false. + /// + public bool IsOwner { get; set; } + /// + /// Gets or sets the amount in circulation of this currency. + /// + /// + /// The amount in circulation. + /// + public float AmountInCirculation { get; set; } + } +} diff --git a/src/IO.Swagger/Models/ResponseDto/TokenDto.cs b/src/IO.Swagger/Models/ResponseDto/TokenDto.cs new file mode 100644 index 0000000..893e044 --- /dev/null +++ b/src/IO.Swagger/Models/ResponseDto/TokenDto.cs @@ -0,0 +1,16 @@ +namespace IO.Swagger.Models.ResponseDto +{ + /// + /// The DTO returned when a JWT is requested + /// + public class TokenDto + { + /// + /// Gets or sets the valid JWT that can be used for accessing other API routes. + /// + /// + /// The token. + /// + public string Token { get; set; } + } +} diff --git a/src/IO.Swagger/Models/ResponseDto/TransactionDto.cs b/src/IO.Swagger/Models/ResponseDto/TransactionDto.cs new file mode 100644 index 0000000..968f5d0 --- /dev/null +++ b/src/IO.Swagger/Models/ResponseDto/TransactionDto.cs @@ -0,0 +1,54 @@ +using System; + +namespace IO.Swagger.Models.ResponseDto +{ + /// + /// The DTO that is return when transactions are requested + /// + public class TransactionDto + { + /// + /// Gets or sets the user that originated the transaction. + /// + /// + /// From user. + /// + public UserDto FromUser { get; set; } + + /// + /// Gets or sets the user that received the transaction. + /// + /// + /// From user. + /// + public UserDto ToUser { get; set; } + /// + /// Gets or sets the amount of the transaction. + /// + /// + /// The amount. + /// + public float Amount { get; set; } + /// + /// Gets or sets the currency the transaction was performed with. + /// + /// + /// The currency. + /// + public CurrencyDto Currency { get; set; } + /// + /// Gets or sets the memo of the transaction. + /// + /// + /// The memo. + /// + public string Memo { get; set; } + /// + /// Gets or sets the time the transaction occurred. + /// + /// + /// The transaction time. + /// + public DateTime TransactionTime { get; set; } + } +} diff --git a/src/IO.Swagger/Models/ResponseDto/UserDto.cs b/src/IO.Swagger/Models/ResponseDto/UserDto.cs new file mode 100644 index 0000000..4189554 --- /dev/null +++ b/src/IO.Swagger/Models/ResponseDto/UserDto.cs @@ -0,0 +1,30 @@ +namespace IO.Swagger.Models.ResponseDto +{ + /// + /// The dto for returning user information + /// + public class UserDto + { + /// + /// Gets or sets the email of the user. + /// + /// + /// The email. + /// + public string Email { get; set; } + /// + /// Gets or sets the first name of the user. + /// + /// + /// The first name. + /// + public string FirstName { get; set; } + /// + /// Gets or sets the last name of the user. + /// + /// + /// The last name. + /// + public string LastName { get; set; } + } +} diff --git a/src/IO.Swagger/Models/ResponseDto/WalletBalanceDto.cs b/src/IO.Swagger/Models/ResponseDto/WalletBalanceDto.cs new file mode 100644 index 0000000..96b770f --- /dev/null +++ b/src/IO.Swagger/Models/ResponseDto/WalletBalanceDto.cs @@ -0,0 +1,23 @@ +namespace IO.Swagger.Models.ResponseDto +{ + /// + /// The DTP returned for the balance of a single currency type in a wallet. + /// + public class WalletBalanceDto + { + /// + /// Gets or sets the currency the balance is in. + /// + /// + /// The currency. + /// + public CurrencyDto Currency { get; set; } + /// + /// Gets or sets the amount of the currency. + /// + /// + /// The balance. + /// + public float Balance { get; set; } + } +} diff --git a/src/IO.Swagger/Models/db/Currency.cs b/src/IO.Swagger/Models/db/Currency.cs index 6cc3e39..0ef90c1 100644 --- a/src/IO.Swagger/Models/db/Currency.cs +++ b/src/IO.Swagger/Models/db/Currency.cs @@ -1,23 +1,59 @@ -using System.Collections; -using System.Collections.Generic; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Runtime.Serialization; -using System.Text.Json.Serialization; namespace IO.Swagger.Models.db { + /// + /// The basic representation of currency + /// public class Currency { + /// + /// Gets or sets the currency identifier. + /// + /// + /// The currency identifier. + /// public int CurrencyId { get; set; } + /// + /// Gets or sets the name of the currency. + /// + /// + /// The name. + /// [StringLength(32, MinimumLength = 1)] public string Name { get; set; } + /// + /// Gets or sets the symbol to use for shorthand representation of the currency. + /// + /// + /// The symbol. + /// [StringLength(4, MinimumLength = 1)] public string Symbol { get; set; } + /// + /// Gets or sets the user identifier that created the currency. + /// + /// + /// The user identifier. + /// [ForeignKey("FK_Currency_UserId")] public int UserId { get; set; } + /// + /// Gets or sets the user that created the currency. + /// + /// + /// The user. + /// public User User { get; set; } + /// + /// Gets or sets the transactions that have been performed with this currency. + /// + /// + /// The transactions. + /// public ICollection Transactions { get; set; } } } diff --git a/src/IO.Swagger/Models/db/Transaction.cs b/src/IO.Swagger/Models/db/Transaction.cs index eef81d3..24d72e5 100644 --- a/src/IO.Swagger/Models/db/Transaction.cs +++ b/src/IO.Swagger/Models/db/Transaction.cs @@ -1,29 +1,88 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.VisualBasic; -using System; +using System; using System.ComponentModel.DataAnnotations; -using System.Text.Json.Serialization; namespace IO.Swagger.Models.db { + /// + /// The basic unit of a transaction + /// public class Transaction { + /// + /// Gets or sets the transaction identifier. + /// + /// + /// The transaction identifier. + /// public int TransactionId { get; set; } + /// + /// Gets or sets the user identifier of the wallet the money came from. + /// + /// + /// From user identifier. + /// public int FromUserId { get; set; } + /// + /// Gets or sets the user that the money came from. + /// + /// + /// From user. + /// public User FromUser { get; set; } + /// + /// Gets or sets the user identifier of the wallet the money went to. + /// + /// + /// From user identifier. + /// public int ToUserId { get; set; } + /// + /// Gets or sets the user that the money went to. + /// + /// + /// From user. + /// public User ToUser { get; set; } + /// + /// Gets or sets the amount exchanged in the transaction. + /// + /// + /// The amount. + /// [Range(0.01, float.MaxValue)] public float Amount { get; set; } + /// + /// Gets or sets the memo of the transaction. + /// + /// + /// The memo. + /// [Required] [StringLength(32, MinimumLength = 2)] public string Memo { get; set; } + /// + /// Gets or sets the currency the transaction amount was issued in. + /// + /// + /// The currency. + /// public Currency Currency { get; set; } + /// + /// Gets or sets the currency identifier the transaction amount was issued in. + /// + /// + /// The currency identifier. + /// public int CurrencyId { get; set; } - + /// + /// Gets or sets the time the transaction occured. + /// + /// + /// The transaction time. + /// public DateTime TransactionTime { get; set; } = DateTime.UtcNow; } } diff --git a/src/IO.Swagger/Models/db/User.cs b/src/IO.Swagger/Models/db/User.cs index 4c0b45b..9860756 100644 --- a/src/IO.Swagger/Models/db/User.cs +++ b/src/IO.Swagger/Models/db/User.cs @@ -1,23 +1,77 @@ -using System.Collections; -using System.Collections.Generic; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using System.Text.Json.Serialization; namespace IO.Swagger.Models.db { + /// + /// The basic representation of a user + /// public class User { + /// + /// Gets or sets the identifier. + /// + /// + /// The identifier. + /// public int Id { get; set; } - + /// + /// Gets or sets the email of the user. + /// + /// + /// The email. + /// public string Email { get; set; } + /// + /// Gets or sets the first name of the user. + /// + /// + /// The first name. + /// [StringLength(32, MinimumLength = 3)] public string FirstName { get; set; } + /// + /// Gets or sets the last name of the user. + /// + /// + /// The last name. + /// [StringLength(32, MinimumLength = 3)] public string LastName { get; set; } + /// + /// Gets or sets the hashed and salted equivalent of the users password. + /// + /// + /// The password hash. + /// public string PasswordHash { get; set; } + /// + /// Gets or sets the randomly generated salt of the users password. + /// + /// + /// The salt. + /// public string Salt { get; set; } + /// + /// Gets or sets the currencies the user has created. + /// + /// + /// The currencies. + /// public ICollection Currencies { get; set; } + /// + /// Gets or sets the transactions from the user. + /// + /// + /// The transactions from. + /// public ICollection TransactionsFrom { get; set; } + /// + /// Gets or sets the transactions to the user. + /// + /// + /// The transactions to. + /// public ICollection TransactionsTo { get; set; } } diff --git a/src/IO.Swagger/Models/dto/CurrencyDto.cs b/src/IO.Swagger/Models/dto/CurrencyDto.cs deleted file mode 100644 index 24038c0..0000000 --- a/src/IO.Swagger/Models/dto/CurrencyDto.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace IO.Swagger.Models.dto -{ - public class CurrencyDto - { - public int CurrencyId { get; set; } - [StringLength(32, MinimumLength = 1)] - public string Name { get; set; } - [StringLength(4, MinimumLength = 1)] - public string Symbol { get; set; } - } -} diff --git a/src/IO.Swagger/Models/dto/CurrencyInfoDto.cs b/src/IO.Swagger/Models/dto/CurrencyInfoDto.cs deleted file mode 100644 index 1f4f055..0000000 --- a/src/IO.Swagger/Models/dto/CurrencyInfoDto.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace IO.Swagger.Models.dto -{ - public class CurrencyInfoDto : CurrencyDto - { - public UserDto CurrencyOwner { get; set; } - public bool IsOwner { get; set; } - public float AmountInCirculation { get; set; } - } -} diff --git a/src/IO.Swagger/Models/dto/TokenDto.cs b/src/IO.Swagger/Models/dto/TokenDto.cs deleted file mode 100644 index 11e6f84..0000000 --- a/src/IO.Swagger/Models/dto/TokenDto.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace IO.Swagger.Models.dto -{ - public class TokenDto - { - public string Token { get; set; } - } -} diff --git a/src/IO.Swagger/Models/dto/TransactionDto.cs b/src/IO.Swagger/Models/dto/TransactionDto.cs deleted file mode 100644 index 510994e..0000000 --- a/src/IO.Swagger/Models/dto/TransactionDto.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Microsoft.SqlServer.Server; -using Microsoft.VisualBasic; -using System; - -namespace IO.Swagger.Models.dto -{ - public class TransactionDto - { - public UserDto FromUser { get; set; } - public UserDto ToUser { get; set; } - public float Amount { get; set; } - public CurrencyDto Currency { get; set; } - public string Memo { get; set; } - public DateTime TransactionTime { get; set; } - } -} diff --git a/src/IO.Swagger/Models/dto/UserDto.cs b/src/IO.Swagger/Models/dto/UserDto.cs deleted file mode 100644 index 8fb115b..0000000 --- a/src/IO.Swagger/Models/dto/UserDto.cs +++ /dev/null @@ -1,13 +0,0 @@ -using IO.Swagger.Models.db; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; - -namespace IO.Swagger.Models.dto -{ - public class UserDto - { - public string Email { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } - } -} diff --git a/src/IO.Swagger/Models/dto/WalletBalanceDto.cs b/src/IO.Swagger/Models/dto/WalletBalanceDto.cs deleted file mode 100644 index d3f34cf..0000000 --- a/src/IO.Swagger/Models/dto/WalletBalanceDto.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace IO.Swagger.Models.dto -{ - public class WalletBalanceDto - { - public CurrencyDto Currency { get; set; } - public float Balance { get; set; } - } -} diff --git a/src/IO.Swagger/Program.cs b/src/IO.Swagger/Program.cs index ae409c1..fff33e5 100644 --- a/src/IO.Swagger/Program.cs +++ b/src/IO.Swagger/Program.cs @@ -1,5 +1,5 @@ -using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; namespace IO.Swagger { diff --git a/src/IO.Swagger/Repositories/CurrencyRepository.cs b/src/IO.Swagger/Repositories/CurrencyRepository.cs index cbdb7a5..15636f6 100644 --- a/src/IO.Swagger/Repositories/CurrencyRepository.cs +++ b/src/IO.Swagger/Repositories/CurrencyRepository.cs @@ -1,28 +1,38 @@ using IO.Swagger.Models.db; -using IO.Swagger.Models.dto; +using IO.Swagger.Models.RequestDto; using IO.Swagger.Services; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; namespace IO.Swagger.Repositories { + /// + /// The EF implementation of this interface + /// + /// public class CurrencyRepository : ICurrencyRepository { - BankDbContext context; + private readonly BankDbContext context; + /// + /// Initializes a new instance of the class. + /// + /// The db context. + /// context public CurrencyRepository(BankDbContext context) { this.context = context ?? throw new ArgumentNullException(nameof(context)); } + /// public async Task> GetAllCurrencies() { - return await context.Currencies.Include(c => c.User).Include(c=>c.Transactions).ToListAsync(); + return await context.Currencies.Include(c => c.User).Include(c => c.Transactions).ToListAsync(); } + /// public async Task CreateCurrency(CurrencyCreateBody request, int userId) { request.Symbol = request.Symbol.Trim(); @@ -36,10 +46,11 @@ namespace IO.Swagger.Repositories Symbol = request.Symbol, UserId = userId }); - + return await context.SaveChangesAsync() > 0; } - + + /// public async Task MintCurrency(CurrencyMintBody request, int userId) { var existsAndIsOwner = await context.Currencies.AnyAsync(c => c.CurrencyId == request.CurrencyId && c.UserId == userId); @@ -56,6 +67,6 @@ namespace IO.Swagger.Repositories }); return await context.SaveChangesAsync() > 0; - } + } } } diff --git a/src/IO.Swagger/Repositories/ICurrencyRepository.cs b/src/IO.Swagger/Repositories/ICurrencyRepository.cs index 58a5fdd..8ac623e 100644 --- a/src/IO.Swagger/Repositories/ICurrencyRepository.cs +++ b/src/IO.Swagger/Repositories/ICurrencyRepository.cs @@ -1,14 +1,33 @@ using IO.Swagger.Models.db; -using IO.Swagger.Models.dto; +using IO.Swagger.Models.RequestDto; using System.Collections.Generic; using System.Threading.Tasks; namespace IO.Swagger.Repositories { + /// + /// The interface defining all currency management activities + /// public interface ICurrencyRepository { - Task CreateCurrency(CurrencyCreateBody request, int userId); + /// + /// Gets all currencies. + /// + /// A list of all known currencies Task> GetAllCurrencies(); + /// + /// Creates the currency. + /// + /// The currency to create. + /// The user id creating the currency. + /// True if the creation was successful, false otherwise. + Task CreateCurrency(CurrencyCreateBody request, int userId); + /// + /// Mints the supplied amount of the supplied currency. + /// + /// The currency to mint and how much. + /// The user id mintung the currency. + /// True if the currency was minted, false otherwise. Task MintCurrency(CurrencyMintBody request, int userId); } } diff --git a/src/IO.Swagger/Repositories/ITransactionRepository.cs b/src/IO.Swagger/Repositories/ITransactionRepository.cs index 75f1401..bff4d6f 100644 --- a/src/IO.Swagger/Repositories/ITransactionRepository.cs +++ b/src/IO.Swagger/Repositories/ITransactionRepository.cs @@ -1,23 +1,57 @@ using IO.Swagger.Models.db; -using IO.Swagger.Models.dto; +using IO.Swagger.Models.RequestDto; using System; using System.Collections.Generic; using System.Threading.Tasks; namespace IO.Swagger.Repositories { + /// + /// The enum defining transaction creation results + /// public enum TransactionReturnCode { + /// + /// The success code + /// Success, + /// + /// The transaction had insufficient funds + /// InsufficientFunds, + /// + /// The the transaction had unknown destination user + /// UnknownDestinationUser, + /// + /// The transaction encountered database error + /// DbError } + /// + /// The interface defining all transaction actions + /// public interface ITransactionRepository { + /// + /// Gets the balances for user. + /// + /// The user identifier. + /// The currencies and associated balance of that currency Task>> GetBalancesForUser(int userId); + /// + /// Gets the transactions for user. + /// + /// The user identifier. + /// A list of all transactions the user has performed in time descending order. Task> GetTransactionsForUser(int userId); + /// + /// Transfers the physical currency from one account to another. + /// + /// The transfer request. + /// From user identifier. + /// The TransactionReturnCode corresponding to action that was performed. Task TransferPhysical(WalletTransferPhysicalBody request, int fromUserId); } } diff --git a/src/IO.Swagger/Repositories/IUserRepository.cs b/src/IO.Swagger/Repositories/IUserRepository.cs index 3796497..e54eb46 100644 --- a/src/IO.Swagger/Repositories/IUserRepository.cs +++ b/src/IO.Swagger/Repositories/IUserRepository.cs @@ -1,13 +1,31 @@ using IO.Swagger.Models.db; -using IO.Swagger.Models.dto; +using IO.Swagger.Models.RequestDto; using System.Threading.Tasks; namespace IO.Swagger.Repositories { + /// + /// The repository governing how to access user data + /// public interface IUserRepository { + /// + /// Logins the user. + /// + /// The login request. + /// The user if login was successful, null otherwise Task LoginUser(AuthLoginBody request); + /// + /// Registers the user. + /// + /// The request. + /// The user if registration was successful, null otherwise Task RegisterUser(AuthRegisterBody request); + /// + /// Retrieves the information about the user. + /// + /// The user identifier. + /// The users information if it exists, null otherwise. Task RetrieveUser(int userId); } } diff --git a/src/IO.Swagger/Repositories/TransactionRepository.cs b/src/IO.Swagger/Repositories/TransactionRepository.cs index 3f0ff20..b3cca77 100644 --- a/src/IO.Swagger/Repositories/TransactionRepository.cs +++ b/src/IO.Swagger/Repositories/TransactionRepository.cs @@ -1,5 +1,5 @@ using IO.Swagger.Models.db; -using IO.Swagger.Models.dto; +using IO.Swagger.Models.RequestDto; using IO.Swagger.Services; using Microsoft.EntityFrameworkCore; using System; @@ -9,16 +9,25 @@ using System.Threading.Tasks; namespace IO.Swagger.Repositories { - + /// + /// The EF implementation of this interface + /// + /// public class TransactionRepository : ITransactionRepository { - BankDbContext context; - + private readonly BankDbContext context; + /// + /// Initializes a new instance of the class. + /// + /// The context. + /// context public TransactionRepository(BankDbContext context) { this.context = context ?? throw new ArgumentNullException(nameof(context)); } + + /// public async Task> GetTransactionsForUser(int userId) { var transactions = await context.Transactions.Where(t => t.ToUserId == userId || t.FromUserId == userId) @@ -34,6 +43,8 @@ namespace IO.Swagger.Repositories return transactions; } + + /// public async Task>> GetBalancesForUser(int userId) { var transactions = await context.Transactions.Where(t => t.ToUserId == userId || t.FromUserId == userId) @@ -41,7 +52,7 @@ namespace IO.Swagger.Repositories .GroupBy(t => t.Currency) .Select(g => Tuple.Create( g.Key, - g.Sum(t =>t.ToUserId != t.FromUserId && t.FromUserId == userId + g.Sum(t => t.ToUserId != t.FromUserId && t.FromUserId == userId ? -t.Amount : t.Amount ) @@ -52,13 +63,15 @@ namespace IO.Swagger.Repositories return transactions; } + + /// public async Task TransferPhysical(WalletTransferPhysicalBody request, int fromUserId) { var trimmedDest = request.DestUserEmail.Trim().ToLower(); var destUser = await context.Users.FirstOrDefaultAsync(u => u.Email == trimmedDest); if (destUser == null) return TransactionReturnCode.UnknownDestinationUser; - + var balances = await GetBalancesForUser(fromUserId); var balance = balances.FirstOrDefault(b => b.Item1.CurrencyId == request.CurrencyId); if (balance == null || balance.Item2 < request.Amount) diff --git a/src/IO.Swagger/Repositories/UserRepository.cs b/src/IO.Swagger/Repositories/UserRepository.cs index 856331e..d5e1a82 100644 --- a/src/IO.Swagger/Repositories/UserRepository.cs +++ b/src/IO.Swagger/Repositories/UserRepository.cs @@ -1,23 +1,31 @@ using IO.Swagger.Models.db; -using System.Security.Cryptography; -using System; +using IO.Swagger.Models.RequestDto; using IO.Swagger.Services; -using IO.Swagger.Models.dto; -using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; -using System.Linq; +using System; +using System.Security.Cryptography; +using System.Threading.Tasks; namespace IO.Swagger.Repositories { + /// + /// The EF implementation of this interface + /// + /// public class UserRepository : IUserRepository { private readonly BankDbContext bankDbContext; + /// + /// Initializes a new instance of the class. + /// + /// The bank database context. public UserRepository(BankDbContext bankDbContext) { this.bankDbContext = bankDbContext; } + /// public async Task RegisterUser(AuthRegisterBody request) { request.Email = request.Email.ToLower(); @@ -25,15 +33,14 @@ namespace IO.Swagger.Repositories return null; // Generate a random salt - byte[] saltBytes = new byte[16]; - new RNGCryptoServiceProvider().GetBytes(saltBytes); + byte[] saltBytes = RandomNumberGenerator.GetBytes(16); string salt = Convert.ToBase64String(saltBytes); // Hash the password along with the salt string password = request.Password; string saltedPassword = password + salt; byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(saltedPassword); - byte[] hashedBytes = new SHA256Managed().ComputeHash(passwordBytes); + byte[] hashedBytes = SHA256.HashData(passwordBytes); string hashedPassword = Convert.ToBase64String(hashedBytes); // Create and insert the user @@ -51,24 +58,26 @@ namespace IO.Swagger.Repositories return newUser; } + /// public async Task LoginUser(AuthLoginBody request) { request.Email = request.Email.ToLower(); var user = await bankDbContext.Users.FirstOrDefaultAsync(u => u.Email.Equals(request.Email)); - if (user == null) + if (user == null) return null; // Hash the supplied password with the retrieved salt string password = request.Password; string saltedPassword = password + user.Salt; byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(saltedPassword); - byte[] hashedBytes = new SHA256Managed().ComputeHash(passwordBytes); + byte[] hashedBytes = SHA256.HashData(passwordBytes); string hashedPassword = Convert.ToBase64String(hashedBytes); if (hashedPassword != user.PasswordHash) return null; return user; } + /// public async Task RetrieveUser(int userId) { return await bankDbContext.Users.FirstOrDefaultAsync(u => u.Id == userId); diff --git a/src/IO.Swagger/Security/BearerAuthenticationHandler.cs b/src/IO.Swagger/Security/BearerAuthenticationHandler.cs index 3e74eff..a1e22c3 100644 --- a/src/IO.Swagger/Security/BearerAuthenticationHandler.cs +++ b/src/IO.Swagger/Security/BearerAuthenticationHandler.cs @@ -1,16 +1,14 @@ +using Microsoft.AspNetCore.Authentication; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; using System; using System.IdentityModel.Tokens.Jwt; -using System.Linq; using System.Net.Http.Headers; using System.Security.Claims; using System.Text; using System.Text.Encodings.Web; using System.Threading.Tasks; -using Microsoft.AspNetCore.Authentication; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using Microsoft.IdentityModel.Tokens; -using Newtonsoft.Json.Linq; namespace IO.Swagger.Security { @@ -19,6 +17,7 @@ namespace IO.Swagger.Security /// public class BearerAuthenticationHandler : AuthenticationHandler { + //TODO: Clean this up and use the service for it private readonly string secretKey; private readonly byte[] secretBytes; @@ -27,6 +26,7 @@ namespace IO.Swagger.Security /// public const string SchemeName = "Bearer"; + /// public BearerAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock) { secretKey = Environment.GetEnvironmentVariable("JWT_SECRET_KEY"); @@ -36,54 +36,54 @@ namespace IO.Swagger.Security /// /// verify that require authorization header exists. /// - protected override async Task HandleAuthenticateAsync() + protected override Task HandleAuthenticateAsync() { - if (!Request.Headers.ContainsKey("Authorization")) + return Task.Run(() => { - return AuthenticateResult.Fail("Missing Authorization Header"); - } - try - { - var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]); - - var tokenHandler = new JwtSecurityTokenHandler(); - var validationParameters = new TokenValidationParameters + if (!Request.Headers.ContainsKey("Authorization")) { - ValidateIssuerSigningKey = true, - IssuerSigningKey = new SymmetricSecurityKey(secretBytes), - ValidateIssuer = false, - ValidateAudience = false - }; - + return AuthenticateResult.Fail("Missing Authorization Header"); + } try { - var claimsPrincipal = tokenHandler.ValidateToken(authHeader.Parameter, validationParameters, out _); - var userIdClaim = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier); + var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]); - if (userIdClaim != null && int.TryParse(userIdClaim.Value, out int userId)) + var tokenHandler = new JwtSecurityTokenHandler(); + var validationParameters = new TokenValidationParameters { - var claims = new[]{ new Claim(ClaimTypes.NameIdentifier, userId.ToString()) }; - var identity = new ClaimsIdentity(claims, SchemeName); - var principal = new ClaimsPrincipal(identity); - var ticket = new AuthenticationTicket(principal, Scheme.Name); + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(secretBytes), + ValidateIssuer = false, + ValidateAudience = false + }; - return AuthenticateResult.Success(ticket); + try + { + var claimsPrincipal = tokenHandler.ValidateToken(authHeader.Parameter, validationParameters, out _); + var userIdClaim = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier); + + if (userIdClaim != null && int.TryParse(userIdClaim.Value, out int userId)) + { + var claims = new[] { new Claim(ClaimTypes.NameIdentifier, userId.ToString()) }; + var identity = new ClaimsIdentity(claims, SchemeName); + var principal = new ClaimsPrincipal(identity); + var ticket = new AuthenticationTicket(principal, Scheme.Name); + + return AuthenticateResult.Success(ticket); + } + } + catch (Exception) + { + return AuthenticateResult.Fail("Invalid Auth Token"); } } - catch (Exception) + catch { - return AuthenticateResult.Fail("Invalid Auth Token"); + return AuthenticateResult.Fail("Invalid Authorization Header"); } - - - } - catch - { - return AuthenticateResult.Fail("Invalid Authorization Header"); - } - - return AuthenticateResult.Fail("Missing Authorization Header"); + return AuthenticateResult.Fail("Missing Authorization Header"); + }); } } } diff --git a/src/IO.Swagger/Services/BankDbContext.cs b/src/IO.Swagger/Services/BankDbContext.cs index 48efb12..18d8be8 100644 --- a/src/IO.Swagger/Services/BankDbContext.cs +++ b/src/IO.Swagger/Services/BankDbContext.cs @@ -3,22 +3,44 @@ using Microsoft.EntityFrameworkCore; namespace IO.Swagger.Services { - + /// + /// The EF DbContext that owns all connections and interactions + /// + /// public class BankDbContext : DbContext { + /// public BankDbContext(DbContextOptions options) : base(options) { } + /// + /// Gets or sets the collections of users. + /// + /// + /// The users. + /// public DbSet Users { get; set; } + /// + /// Gets or sets the collection of currencies. + /// + /// + /// The currencies. + /// public DbSet Currencies { get; set; } + /// + /// Gets or sets the collection of transactions. + /// + /// + /// The transactions. + /// public DbSet Transactions { get; set; } - + /// protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); - + // currency -> user FK modelBuilder.Entity() .HasMany(u => u.Currencies) diff --git a/src/IO.Swagger/Services/JwtService.cs b/src/IO.Swagger/Services/JwtService.cs index ffbd279..de34a9b 100644 --- a/src/IO.Swagger/Services/JwtService.cs +++ b/src/IO.Swagger/Services/JwtService.cs @@ -1,28 +1,38 @@ using Microsoft.IdentityModel.Tokens; +using System; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; -using System; namespace IO.Swagger.Services { + /// + /// The internal service for creating and reading JWTs + /// public class JwtService { private readonly string secretKey; private readonly byte[] secretBytes; + /// + /// Initializes a new instance of the class. + /// public JwtService() { - secretKey = Environment.GetEnvironmentVariable("JWT_SECRET_KEY"); + secretKey = Environment.GetEnvironmentVariable("JWT_SECRET_KEY"); secretBytes = Encoding.UTF8.GetBytes(secretKey); } + /// + /// Generates the JWT. + /// + /// The user identifier. + /// A JWT that will expire in 1hr from time of issue enconding the user id supplied public string GenerateJwt(int userId) { var claims = new[] { new Claim(ClaimTypes.NameIdentifier, userId.ToString()) - // You can add more claims as needed }; var tokenHandler = new JwtSecurityTokenHandler(); @@ -36,11 +46,5 @@ namespace IO.Swagger.Services var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); } - - public int GetUserIdFromJwt(string jwtToken) - { - - return -1; // Return -1 if user ID extraction fails - } } } diff --git a/src/IO.Swagger/Services/MapperProfile.cs b/src/IO.Swagger/Services/MapperProfile.cs index 57bba6d..0b70da3 100644 --- a/src/IO.Swagger/Services/MapperProfile.cs +++ b/src/IO.Swagger/Services/MapperProfile.cs @@ -1,12 +1,19 @@ using AutoMapper; using IO.Swagger.Models.db; -using IO.Swagger.Models.dto; +using IO.Swagger.Models.ResponseDto; using System.Linq; namespace IO.Swagger.Services { + /// + /// The configuration of all automapper profiles + /// + /// public class MapperProfile : Profile { + /// + /// Initializes a new instance of the class. + /// public MapperProfile() { CreateMap(); diff --git a/src/IO.Swagger/Startup.cs b/src/IO.Swagger/Startup.cs index 90197ba..79e9b1b 100644 --- a/src/IO.Swagger/Startup.cs +++ b/src/IO.Swagger/Startup.cs @@ -7,11 +7,15 @@ * * Generated by: https://github.com/swagger-api/swagger-codegen.git */ -using System; -using System.IO; +using AutoMapper; +using IO.Swagger.Filters; +using IO.Swagger.Repositories; +using IO.Swagger.Security; +using IO.Swagger.Services; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -19,14 +23,8 @@ using Microsoft.Extensions.Logging; using Microsoft.OpenApi.Models; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; -using Swashbuckle.AspNetCore.Swagger; -using Swashbuckle.AspNetCore.SwaggerGen; -using IO.Swagger.Filters; -using IO.Swagger.Security; -using IO.Swagger.Repositories; -using IO.Swagger.Services; -using Microsoft.EntityFrameworkCore; -using AutoMapper; +using System; +using System.IO; namespace IO.Swagger { @@ -118,7 +116,7 @@ namespace IO.Swagger Id="bearerAuth" } }, - new string[]{} + Array.Empty() } }); }); @@ -131,7 +129,8 @@ namespace IO.Swagger // CORS sucks - services.AddCors(opt => { + services.AddCors(opt => + { opt.AddDefaultPolicy(po => { po.AllowAnyHeader()