diff --git a/src/IO.Swagger/Controllers/AuthApi.cs b/src/IO.Swagger/Controllers/AuthApi.cs
index d7766cb..c25da70 100644
--- a/src/IO.Swagger/Controllers/AuthApi.cs
+++ b/src/IO.Swagger/Controllers/AuthApi.cs
@@ -17,16 +17,30 @@ using System.ComponentModel.DataAnnotations;
using IO.Swagger.Attributes;
using IO.Swagger.Security;
using Microsoft.AspNetCore.Authorization;
-using IO.Swagger.Models;
+using IO.Swagger.Models.dto;
+using IO.Swagger.Repositories;
+using System.Threading.Tasks;
+using System.Linq;
+using IO.Swagger.Services;
+using System.Security.Claims;
namespace IO.Swagger.Controllers
-{
+{
///
///
///
[ApiController]
public class AuthApiController : ControllerBase
- {
+ {
+ private readonly IUserRepository repository;
+ private readonly JwtService jwt;
+
+ public AuthApiController(IUserRepository repository, JwtService jwt)
+ {
+ this.repository = repository ?? throw new ArgumentNullException(nameof(repository));
+ this.jwt = jwt ?? throw new ArgumentNullException(nameof(jwt));
+ }
+
///
/// Get user details
///
@@ -37,15 +51,13 @@ namespace IO.Swagger.Controllers
[Authorize(AuthenticationSchemes = BearerAuthenticationHandler.SchemeName)]
[ValidateModelState]
[SwaggerOperation("GetUserDetails")]
- public virtual IActionResult GetUserDetails()
- {
- //TODO: Uncomment the next line to return response 200 or use other options such as return this.NotFound(), return this.BadRequest(..), ...
- // return StatusCode(200);
-
- //TODO: Uncomment the next line to return response 401 or use other options such as return this.NotFound(), return this.BadRequest(..), ...
- // return StatusCode(401);
-
- throw new NotImplementedException();
+ public virtual async Task GetUserDetails()
+ {
+ var userIdString = HttpContext.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;
+ if (!int.TryParse(userIdString, out int userId))
+ return Unauthorized();
+ var user = await repository.RetrieveUser(userId);
+ return user == null ? NoContent() : Ok(user);
}
///
@@ -58,40 +70,39 @@ namespace IO.Swagger.Controllers
[Route("/v1/api/auth/login")]
[ValidateModelState]
[SwaggerOperation("LoginUser")]
- public virtual IActionResult LoginUser([FromBody]AuthLoginBody 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);
-
- //TODO: Uncomment the next line to return response 401 or use other options such as return this.NotFound(), return this.BadRequest(..), ...
- // return StatusCode(401);
-
- throw new NotImplementedException();
+ public virtual async Task LoginUser([FromBody]AuthLoginBody body)
+ {
+ if (!ModelState.IsValid)
+ {
+ var errors = ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage));
+ return BadRequest(errors);
+ }
+ var user = await repository.LoginUser(body);
+ return user == null ? Unauthorized() : Ok(new { token = jwt.GenerateJwt(user.Id) });
}
///
/// Register a new user
///
///
- /// User registered successfully
+ /// User registered successfully
/// Bad Request
/// Conflict (user with provided email already exists)
[HttpPost]
[Route("/v1/api/auth/register")]
[ValidateModelState]
+
[SwaggerOperation("RegisterUser")]
- public virtual IActionResult RegisterUser([FromBody]AuthRegisterBody 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);
+ public async Task RegisterUser([FromBody]AuthRegisterBody body)
+ {
+ if (!ModelState.IsValid)
+ {
+ var errors = ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage));
+ return BadRequest(errors);
+ }
- //TODO: Uncomment the next line to return response 400 or use other options such as return this.NotFound(), return this.BadRequest(..), ...
- // return StatusCode(400);
-
- //TODO: Uncomment the next line to return response 409 or use other options such as return this.NotFound(), return this.BadRequest(..), ...
- // return StatusCode(409);
-
- throw new NotImplementedException();
+ var user = await repository.RegisterUser(body);
+ return user == null ? StatusCode(409) : Ok(new { token = jwt.GenerateJwt(user.Id) });
}
}
}
diff --git a/src/IO.Swagger/Controllers/CurrencyApi.cs b/src/IO.Swagger/Controllers/CurrencyApi.cs
index 1279c00..e04f389 100644
--- a/src/IO.Swagger/Controllers/CurrencyApi.cs
+++ b/src/IO.Swagger/Controllers/CurrencyApi.cs
@@ -17,10 +17,10 @@ using System.ComponentModel.DataAnnotations;
using IO.Swagger.Attributes;
using IO.Swagger.Security;
using Microsoft.AspNetCore.Authorization;
-using IO.Swagger.Models;
+using IO.Swagger.Models.dto;
namespace IO.Swagger.Controllers
-{
+{
///
///
///
diff --git a/src/IO.Swagger/Controllers/WalletApi.cs b/src/IO.Swagger/Controllers/WalletApi.cs
index 6c8c07e..0b22031 100644
--- a/src/IO.Swagger/Controllers/WalletApi.cs
+++ b/src/IO.Swagger/Controllers/WalletApi.cs
@@ -17,10 +17,10 @@ using System.ComponentModel.DataAnnotations;
using IO.Swagger.Attributes;
using IO.Swagger.Security;
using Microsoft.AspNetCore.Authorization;
-using IO.Swagger.Models;
+using IO.Swagger.Models.dto;
namespace IO.Swagger.Controllers
-{
+{
///
///
///
diff --git a/src/IO.Swagger/IO.Swagger.csproj b/src/IO.Swagger/IO.Swagger.csproj
index 77cf8af..854fe09 100644
--- a/src/IO.Swagger/IO.Swagger.csproj
+++ b/src/IO.Swagger/IO.Swagger.csproj
@@ -9,6 +9,12 @@
IO.Swagger
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/src/IO.Swagger/Migrations/20230813022042_Initial creation.Designer.cs b/src/IO.Swagger/Migrations/20230813022042_Initial creation.Designer.cs
new file mode 100644
index 0000000..6ddcc00
--- /dev/null
+++ b/src/IO.Swagger/Migrations/20230813022042_Initial creation.Designer.cs
@@ -0,0 +1,60 @@
+//
+using IO.Swagger.Services;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace IO.Swagger.Migrations
+{
+ [DbContext(typeof(BankDbContext))]
+ [Migration("20230813022042_Initial creation")]
+ partial class Initialcreation
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.10")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("IO.Swagger.Models.db.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Email")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FirstName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PasswordHash")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Salt")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Username")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Users");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/IO.Swagger/Migrations/20230813022042_Initial creation.cs b/src/IO.Swagger/Migrations/20230813022042_Initial creation.cs
new file mode 100644
index 0000000..b9622b0
--- /dev/null
+++ b/src/IO.Swagger/Migrations/20230813022042_Initial creation.cs
@@ -0,0 +1,39 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace IO.Swagger.Migrations
+{
+ ///
+ public partial class Initialcreation : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "Users",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ Email = table.Column(type: "nvarchar(max)", nullable: true),
+ FirstName = table.Column(type: "nvarchar(max)", nullable: true),
+ LastName = table.Column(type: "nvarchar(max)", nullable: true),
+ Username = table.Column(type: "nvarchar(max)", nullable: true),
+ PasswordHash = table.Column(type: "nvarchar(max)", nullable: true),
+ Salt = table.Column(type: "nvarchar(max)", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Users", x => x.Id);
+ });
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "Users");
+ }
+ }
+}
diff --git a/src/IO.Swagger/Migrations/20230813022424_Change user table.Designer.cs b/src/IO.Swagger/Migrations/20230813022424_Change user table.Designer.cs
new file mode 100644
index 0000000..06cc4bd
--- /dev/null
+++ b/src/IO.Swagger/Migrations/20230813022424_Change user table.Designer.cs
@@ -0,0 +1,59 @@
+//
+using IO.Swagger.Services;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace IO.Swagger.Migrations
+{
+ [DbContext(typeof(BankDbContext))]
+ [Migration("20230813022424_Change user table")]
+ partial class Changeusertable
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.10")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("IO.Swagger.Models.db.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Email")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FirstName")
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("LastName")
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("PasswordHash")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Salt")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Users");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/IO.Swagger/Migrations/20230813022424_Change user table.cs b/src/IO.Swagger/Migrations/20230813022424_Change user table.cs
new file mode 100644
index 0000000..0731987
--- /dev/null
+++ b/src/IO.Swagger/Migrations/20230813022424_Change user table.cs
@@ -0,0 +1,68 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace IO.Swagger.Migrations
+{
+ ///
+ public partial class Changeusertable : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "Username",
+ table: "Users");
+
+ migrationBuilder.AlterColumn(
+ name: "LastName",
+ table: "Users",
+ type: "nvarchar(32)",
+ maxLength: 32,
+ nullable: true,
+ oldClrType: typeof(string),
+ oldType: "nvarchar(max)",
+ oldNullable: true);
+
+ migrationBuilder.AlterColumn(
+ name: "FirstName",
+ table: "Users",
+ type: "nvarchar(32)",
+ maxLength: 32,
+ nullable: true,
+ oldClrType: typeof(string),
+ oldType: "nvarchar(max)",
+ oldNullable: true);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AlterColumn(
+ name: "LastName",
+ table: "Users",
+ type: "nvarchar(max)",
+ nullable: true,
+ oldClrType: typeof(string),
+ oldType: "nvarchar(32)",
+ oldMaxLength: 32,
+ oldNullable: true);
+
+ migrationBuilder.AlterColumn(
+ name: "FirstName",
+ table: "Users",
+ type: "nvarchar(max)",
+ nullable: true,
+ oldClrType: typeof(string),
+ oldType: "nvarchar(32)",
+ oldMaxLength: 32,
+ oldNullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "Username",
+ table: "Users",
+ type: "nvarchar(max)",
+ nullable: true);
+ }
+ }
+}
diff --git a/src/IO.Swagger/Migrations/BankDbContextModelSnapshot.cs b/src/IO.Swagger/Migrations/BankDbContextModelSnapshot.cs
new file mode 100644
index 0000000..ca4ee56
--- /dev/null
+++ b/src/IO.Swagger/Migrations/BankDbContextModelSnapshot.cs
@@ -0,0 +1,56 @@
+//
+using IO.Swagger.Services;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace IO.Swagger.Migrations
+{
+ [DbContext(typeof(BankDbContext))]
+ partial class BankDbContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.10")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("IO.Swagger.Models.db.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Email")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FirstName")
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("LastName")
+ .HasMaxLength(32)
+ .HasColumnType("nvarchar(32)");
+
+ b.Property("PasswordHash")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Salt")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Users");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/IO.Swagger/Models/db/User.cs b/src/IO.Swagger/Models/db/User.cs
new file mode 100644
index 0000000..9a9e29f
--- /dev/null
+++ b/src/IO.Swagger/Models/db/User.cs
@@ -0,0 +1,17 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace IO.Swagger.Models.db
+{
+ public class User
+ {
+ public int Id { get; set; }
+ public string Email { get; set; }
+ [StringLength(32, MinimumLength = 3)]
+ public string FirstName { get; set; }
+ [StringLength(32, MinimumLength = 3)]
+ public string LastName { get; set; }
+ public string PasswordHash { get; set; }
+ public string Salt { get; set; }
+ }
+
+}
diff --git a/src/IO.Swagger/Models/AuthLoginBody.cs b/src/IO.Swagger/Models/dto/AuthLoginBody.cs
similarity index 92%
rename from src/IO.Swagger/Models/AuthLoginBody.cs
rename to src/IO.Swagger/Models/dto/AuthLoginBody.cs
index f821de0..b76d7e1 100644
--- a/src/IO.Swagger/Models/AuthLoginBody.cs
+++ b/src/IO.Swagger/Models/dto/AuthLoginBody.cs
@@ -18,26 +18,26 @@ using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Newtonsoft.Json;
-namespace IO.Swagger.Models
+namespace IO.Swagger.Models.dto
{
///
///
///
[DataContract]
public partial class AuthLoginBody : IEquatable
- {
+ {
///
/// Gets or Sets Email
///
- [DataMember(Name="email")]
+ [DataMember(Name = "email")]
public string Email { get; set; }
///
/// Gets or Sets Password
///
- [DataMember(Name="password")]
+ [DataMember(Name = "password")]
public string Password { get; set; }
///
@@ -85,12 +85,12 @@ namespace IO.Swagger.Models
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
- return
+ return
(
Email == other.Email ||
Email != null &&
Email.Equals(other.Email)
- ) &&
+ ) &&
(
Password == other.Password ||
Password != null &&
@@ -108,16 +108,16 @@ namespace IO.Swagger.Models
{
var hashCode = 41;
// Suitable nullity checks etc, of course :)
- if (Email != null)
+ if (Email != null)
hashCode = hashCode * 59 + Email.GetHashCode();
- if (Password != null)
+ if (Password != null)
hashCode = hashCode * 59 + Password.GetHashCode();
return hashCode;
}
}
#region Operators
- #pragma warning disable 1591
+#pragma warning disable 1591
public static bool operator ==(AuthLoginBody left, AuthLoginBody right)
{
@@ -129,7 +129,7 @@ namespace IO.Swagger.Models
return !Equals(left, right);
}
- #pragma warning restore 1591
+#pragma warning restore 1591
#endregion Operators
}
}
diff --git a/src/IO.Swagger/Models/AuthRegisterBody.cs b/src/IO.Swagger/Models/dto/AuthRegisterBody.cs
similarity index 85%
rename from src/IO.Swagger/Models/AuthRegisterBody.cs
rename to src/IO.Swagger/Models/dto/AuthRegisterBody.cs
index 1374ecf..ef2c3eb 100644
--- a/src/IO.Swagger/Models/AuthRegisterBody.cs
+++ b/src/IO.Swagger/Models/dto/AuthRegisterBody.cs
@@ -18,42 +18,48 @@ using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Newtonsoft.Json;
-namespace IO.Swagger.Models
+namespace IO.Swagger.Models.dto
{
///
///
///
[DataContract]
public partial class AuthRegisterBody : IEquatable
- {
+ {
///
/// Gets or Sets FirstName
///
- [StringLength(32, MinimumLength=3)]
- [DataMember(Name="firstName")]
+ [StringLength(32, MinimumLength = 3)]
+ [DataMember(Name = "firstName")]
+ [Required]
public string FirstName { get; set; }
///
/// Gets or Sets LastName
///
- [StringLength(32, MinimumLength=3)]
- [DataMember(Name="lastName")]
+ [StringLength(32, MinimumLength = 3)]
+ [DataMember(Name = "lastName")]
+ [Required]
public string LastName { get; set; }
///
/// Gets or Sets Email
///
- [DataMember(Name="email")]
+ [DataMember(Name = "email")]
+ [EmailAddress(ErrorMessage = "Invalid email format.")]
+ [Required]
public string Email { get; set; }
///
/// Gets or Sets Password
///
- [DataMember(Name="password")]
+ [DataMember(Name = "password")]
+ [StringLength(32, MinimumLength = 8)]
+ [Required]
public string Password { get; set; }
///
@@ -103,22 +109,22 @@ namespace IO.Swagger.Models
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
- return
+ return
(
FirstName == other.FirstName ||
FirstName != null &&
FirstName.Equals(other.FirstName)
- ) &&
+ ) &&
(
LastName == other.LastName ||
LastName != null &&
LastName.Equals(other.LastName)
- ) &&
+ ) &&
(
Email == other.Email ||
Email != null &&
Email.Equals(other.Email)
- ) &&
+ ) &&
(
Password == other.Password ||
Password != null &&
@@ -136,20 +142,20 @@ namespace IO.Swagger.Models
{
var hashCode = 41;
// Suitable nullity checks etc, of course :)
- if (FirstName != null)
+ if (FirstName != null)
hashCode = hashCode * 59 + FirstName.GetHashCode();
- if (LastName != null)
+ if (LastName != null)
hashCode = hashCode * 59 + LastName.GetHashCode();
- if (Email != null)
+ if (Email != null)
hashCode = hashCode * 59 + Email.GetHashCode();
- if (Password != null)
+ if (Password != null)
hashCode = hashCode * 59 + Password.GetHashCode();
return hashCode;
}
}
#region Operators
- #pragma warning disable 1591
+#pragma warning disable 1591
public static bool operator ==(AuthRegisterBody left, AuthRegisterBody right)
{
@@ -161,7 +167,7 @@ namespace IO.Swagger.Models
return !Equals(left, right);
}
- #pragma warning restore 1591
+#pragma warning restore 1591
#endregion Operators
}
}
diff --git a/src/IO.Swagger/Models/CurrencyAddAssetBody.cs b/src/IO.Swagger/Models/dto/CurrencyAddAssetBody.cs
similarity index 90%
rename from src/IO.Swagger/Models/CurrencyAddAssetBody.cs
rename to src/IO.Swagger/Models/dto/CurrencyAddAssetBody.cs
index db780c8..ab21642 100644
--- a/src/IO.Swagger/Models/CurrencyAddAssetBody.cs
+++ b/src/IO.Swagger/Models/dto/CurrencyAddAssetBody.cs
@@ -18,34 +18,34 @@ using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Newtonsoft.Json;
-namespace IO.Swagger.Models
+namespace IO.Swagger.Models.dto
{
///
///
///
[DataContract]
public partial class CurrencyAddAssetBody : IEquatable
- {
+ {
///
/// Gets or Sets CollectionId
///
- [DataMember(Name="collectionId")]
+ [DataMember(Name = "collectionId")]
public int? CollectionId { get; set; }
///
/// Gets or Sets AssetName
///
- [StringLength(32, MinimumLength=1)]
- [DataMember(Name="assetName")]
+ [StringLength(32, MinimumLength = 1)]
+ [DataMember(Name = "assetName")]
public string AssetName { get; set; }
///
/// Gets or Sets AssetLink
///
[RegularExpression("/^(https?|ftp)://[^\\s/$.?#].[^\\s]*$/")]
- [DataMember(Name="assetLink")]
+ [DataMember(Name = "assetLink")]
public string AssetLink { get; set; }
///
@@ -94,17 +94,17 @@ namespace IO.Swagger.Models
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
- return
+ return
(
CollectionId == other.CollectionId ||
CollectionId != null &&
CollectionId.Equals(other.CollectionId)
- ) &&
+ ) &&
(
AssetName == other.AssetName ||
AssetName != null &&
AssetName.Equals(other.AssetName)
- ) &&
+ ) &&
(
AssetLink == other.AssetLink ||
AssetLink != null &&
@@ -122,18 +122,18 @@ namespace IO.Swagger.Models
{
var hashCode = 41;
// Suitable nullity checks etc, of course :)
- if (CollectionId != null)
+ if (CollectionId != null)
hashCode = hashCode * 59 + CollectionId.GetHashCode();
- if (AssetName != null)
+ if (AssetName != null)
hashCode = hashCode * 59 + AssetName.GetHashCode();
- if (AssetLink != null)
+ if (AssetLink != null)
hashCode = hashCode * 59 + AssetLink.GetHashCode();
return hashCode;
}
}
#region Operators
- #pragma warning disable 1591
+#pragma warning disable 1591
public static bool operator ==(CurrencyAddAssetBody left, CurrencyAddAssetBody right)
{
@@ -145,7 +145,7 @@ namespace IO.Swagger.Models
return !Equals(left, right);
}
- #pragma warning restore 1591
+#pragma warning restore 1591
#endregion Operators
}
}
diff --git a/src/IO.Swagger/Models/CurrencyCreateBody.cs b/src/IO.Swagger/Models/dto/CurrencyCreateBody.cs
similarity index 90%
rename from src/IO.Swagger/Models/CurrencyCreateBody.cs
rename to src/IO.Swagger/Models/dto/CurrencyCreateBody.cs
index 0b506bf..092c278 100644
--- a/src/IO.Swagger/Models/CurrencyCreateBody.cs
+++ b/src/IO.Swagger/Models/dto/CurrencyCreateBody.cs
@@ -18,28 +18,28 @@ using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Newtonsoft.Json;
-namespace IO.Swagger.Models
+namespace IO.Swagger.Models.dto
{
///
///
///
[DataContract]
public partial class CurrencyCreateBody : IEquatable
- {
+ {
///
/// Gets or Sets Name
///
- [StringLength(32, MinimumLength=1)]
- [DataMember(Name="name")]
+ [StringLength(32, MinimumLength = 1)]
+ [DataMember(Name = "name")]
public string Name { get; set; }
///
/// Gets or Sets Symbol
///
- [StringLength(4, MinimumLength=1)]
- [DataMember(Name="symbol")]
+ [StringLength(4, MinimumLength = 1)]
+ [DataMember(Name = "symbol")]
public string Symbol { get; set; }
///
@@ -87,12 +87,12 @@ namespace IO.Swagger.Models
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
- return
+ return
(
Name == other.Name ||
Name != null &&
Name.Equals(other.Name)
- ) &&
+ ) &&
(
Symbol == other.Symbol ||
Symbol != null &&
@@ -110,16 +110,16 @@ namespace IO.Swagger.Models
{
var hashCode = 41;
// Suitable nullity checks etc, of course :)
- if (Name != null)
+ if (Name != null)
hashCode = hashCode * 59 + Name.GetHashCode();
- if (Symbol != null)
+ if (Symbol != null)
hashCode = hashCode * 59 + Symbol.GetHashCode();
return hashCode;
}
}
#region Operators
- #pragma warning disable 1591
+#pragma warning disable 1591
public static bool operator ==(CurrencyCreateBody left, CurrencyCreateBody right)
{
@@ -131,7 +131,7 @@ namespace IO.Swagger.Models
return !Equals(left, right);
}
- #pragma warning restore 1591
+#pragma warning restore 1591
#endregion Operators
}
}
diff --git a/src/IO.Swagger/Models/CurrencyCreateCollectionBody.cs b/src/IO.Swagger/Models/dto/CurrencyCreateCollectionBody.cs
similarity index 93%
rename from src/IO.Swagger/Models/CurrencyCreateCollectionBody.cs
rename to src/IO.Swagger/Models/dto/CurrencyCreateCollectionBody.cs
index 9d7f8b0..e0942c5 100644
--- a/src/IO.Swagger/Models/CurrencyCreateCollectionBody.cs
+++ b/src/IO.Swagger/Models/dto/CurrencyCreateCollectionBody.cs
@@ -18,19 +18,19 @@ using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Newtonsoft.Json;
-namespace IO.Swagger.Models
+namespace IO.Swagger.Models.dto
{
///
///
///
[DataContract]
public partial class CurrencyCreateCollectionBody : IEquatable
- {
+ {
///
/// Gets or Sets CollectionName
///
- [DataMember(Name="collectionName")]
+ [DataMember(Name = "collectionName")]
public string CollectionName { get; set; }
///
@@ -77,12 +77,12 @@ namespace IO.Swagger.Models
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
- return
- (
+ return
+
CollectionName == other.CollectionName ||
CollectionName != null &&
CollectionName.Equals(other.CollectionName)
- );
+ ;
}
///
@@ -95,14 +95,14 @@ namespace IO.Swagger.Models
{
var hashCode = 41;
// Suitable nullity checks etc, of course :)
- if (CollectionName != null)
+ if (CollectionName != null)
hashCode = hashCode * 59 + CollectionName.GetHashCode();
return hashCode;
}
}
#region Operators
- #pragma warning disable 1591
+#pragma warning disable 1591
public static bool operator ==(CurrencyCreateCollectionBody left, CurrencyCreateCollectionBody right)
{
@@ -114,7 +114,7 @@ namespace IO.Swagger.Models
return !Equals(left, right);
}
- #pragma warning restore 1591
+#pragma warning restore 1591
#endregion Operators
}
}
diff --git a/src/IO.Swagger/Models/CurrencyMintBody.cs b/src/IO.Swagger/Models/dto/CurrencyMintBody.cs
similarity index 92%
rename from src/IO.Swagger/Models/CurrencyMintBody.cs
rename to src/IO.Swagger/Models/dto/CurrencyMintBody.cs
index 8ff6244..704da0d 100644
--- a/src/IO.Swagger/Models/CurrencyMintBody.cs
+++ b/src/IO.Swagger/Models/dto/CurrencyMintBody.cs
@@ -18,26 +18,26 @@ using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Newtonsoft.Json;
-namespace IO.Swagger.Models
+namespace IO.Swagger.Models.dto
{
///
///
///
[DataContract]
public partial class CurrencyMintBody : IEquatable
- {
+ {
///
/// Gets or Sets CurrencyId
///
- [DataMember(Name="currencyId")]
+ [DataMember(Name = "currencyId")]
public int? CurrencyId { get; set; }
///
/// Gets or Sets Amount
///
- [DataMember(Name="amount")]
+ [DataMember(Name = "amount")]
public decimal? Amount { get; set; }
///
@@ -85,12 +85,12 @@ namespace IO.Swagger.Models
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
- return
+ return
(
CurrencyId == other.CurrencyId ||
CurrencyId != null &&
CurrencyId.Equals(other.CurrencyId)
- ) &&
+ ) &&
(
Amount == other.Amount ||
Amount != null &&
@@ -108,16 +108,16 @@ namespace IO.Swagger.Models
{
var hashCode = 41;
// Suitable nullity checks etc, of course :)
- if (CurrencyId != null)
+ if (CurrencyId != null)
hashCode = hashCode * 59 + CurrencyId.GetHashCode();
- if (Amount != null)
+ if (Amount != null)
hashCode = hashCode * 59 + Amount.GetHashCode();
return hashCode;
}
}
#region Operators
- #pragma warning disable 1591
+#pragma warning disable 1591
public static bool operator ==(CurrencyMintBody left, CurrencyMintBody right)
{
@@ -129,7 +129,7 @@ namespace IO.Swagger.Models
return !Equals(left, right);
}
- #pragma warning restore 1591
+#pragma warning restore 1591
#endregion Operators
}
}
diff --git a/src/IO.Swagger/Models/WalletTransferDigitalBody.cs b/src/IO.Swagger/Models/dto/WalletTransferDigitalBody.cs
similarity index 92%
rename from src/IO.Swagger/Models/WalletTransferDigitalBody.cs
rename to src/IO.Swagger/Models/dto/WalletTransferDigitalBody.cs
index 358c7d2..6e3b5db 100644
--- a/src/IO.Swagger/Models/WalletTransferDigitalBody.cs
+++ b/src/IO.Swagger/Models/dto/WalletTransferDigitalBody.cs
@@ -18,26 +18,26 @@ using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Newtonsoft.Json;
-namespace IO.Swagger.Models
+namespace IO.Swagger.Models.dto
{
///
///
///
[DataContract]
public partial class WalletTransferDigitalBody : IEquatable
- {
+ {
///
/// Gets or Sets Email
///
- [DataMember(Name="email")]
+ [DataMember(Name = "email")]
public string Email { get; set; }
///
/// Gets or Sets AssetId
///
- [DataMember(Name="assetId")]
+ [DataMember(Name = "assetId")]
public int? AssetId { get; set; }
///
@@ -85,12 +85,12 @@ namespace IO.Swagger.Models
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
- return
+ return
(
Email == other.Email ||
Email != null &&
Email.Equals(other.Email)
- ) &&
+ ) &&
(
AssetId == other.AssetId ||
AssetId != null &&
@@ -108,16 +108,16 @@ namespace IO.Swagger.Models
{
var hashCode = 41;
// Suitable nullity checks etc, of course :)
- if (Email != null)
+ if (Email != null)
hashCode = hashCode * 59 + Email.GetHashCode();
- if (AssetId != null)
+ if (AssetId != null)
hashCode = hashCode * 59 + AssetId.GetHashCode();
return hashCode;
}
}
#region Operators
- #pragma warning disable 1591
+#pragma warning disable 1591
public static bool operator ==(WalletTransferDigitalBody left, WalletTransferDigitalBody right)
{
@@ -129,7 +129,7 @@ namespace IO.Swagger.Models
return !Equals(left, right);
}
- #pragma warning restore 1591
+#pragma warning restore 1591
#endregion Operators
}
}
diff --git a/src/IO.Swagger/Models/WalletTransferPhysicalBody.cs b/src/IO.Swagger/Models/dto/WalletTransferPhysicalBody.cs
similarity index 91%
rename from src/IO.Swagger/Models/WalletTransferPhysicalBody.cs
rename to src/IO.Swagger/Models/dto/WalletTransferPhysicalBody.cs
index 2233bcc..fca7ef9 100644
--- a/src/IO.Swagger/Models/WalletTransferPhysicalBody.cs
+++ b/src/IO.Swagger/Models/dto/WalletTransferPhysicalBody.cs
@@ -18,33 +18,33 @@ using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Newtonsoft.Json;
-namespace IO.Swagger.Models
+namespace IO.Swagger.Models.dto
{
///
///
///
[DataContract]
public partial class WalletTransferPhysicalBody : IEquatable
- {
+ {
///
/// Gets or Sets Email
///
- [DataMember(Name="email")]
+ [DataMember(Name = "email")]
public string Email { get; set; }
///
/// Gets or Sets Amount
///
- [DataMember(Name="amount")]
+ [DataMember(Name = "amount")]
public decimal? Amount { get; set; }
///
/// Gets or Sets CurrencyId
///
- [DataMember(Name="currencyId")]
+ [DataMember(Name = "currencyId")]
public int? CurrencyId { get; set; }
///
@@ -93,17 +93,17 @@ namespace IO.Swagger.Models
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
- return
+ return
(
Email == other.Email ||
Email != null &&
Email.Equals(other.Email)
- ) &&
+ ) &&
(
Amount == other.Amount ||
Amount != null &&
Amount.Equals(other.Amount)
- ) &&
+ ) &&
(
CurrencyId == other.CurrencyId ||
CurrencyId != null &&
@@ -121,18 +121,18 @@ namespace IO.Swagger.Models
{
var hashCode = 41;
// Suitable nullity checks etc, of course :)
- if (Email != null)
+ if (Email != null)
hashCode = hashCode * 59 + Email.GetHashCode();
- if (Amount != null)
+ if (Amount != null)
hashCode = hashCode * 59 + Amount.GetHashCode();
- if (CurrencyId != null)
+ if (CurrencyId != null)
hashCode = hashCode * 59 + CurrencyId.GetHashCode();
return hashCode;
}
}
#region Operators
- #pragma warning disable 1591
+#pragma warning disable 1591
public static bool operator ==(WalletTransferPhysicalBody left, WalletTransferPhysicalBody right)
{
@@ -144,7 +144,7 @@ namespace IO.Swagger.Models
return !Equals(left, right);
}
- #pragma warning restore 1591
+#pragma warning restore 1591
#endregion Operators
}
}
diff --git a/src/IO.Swagger/Properties/launchSettings.json b/src/IO.Swagger/Properties/launchSettings.json
index 5bb6f82..b231764 100644
--- a/src/IO.Swagger/Properties/launchSettings.json
+++ b/src/IO.Swagger/Properties/launchSettings.json
@@ -1,12 +1,4 @@
{
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:50352/",
- "sslPort": 0
- }
- },
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
@@ -20,10 +12,12 @@
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
- "applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "DATABASE_CONNECTION_STRING": "Server=localhost\\SQLEXPRESS;Database=BankDb;Trusted_Connection=True;Integrated Security=True;TrustServerCertificate=True",
+ "JWT_SECRET_KEY": "mysuperduperubereepykeepysecretkey"
+ },
+ "applicationUrl": "https://localhost:5001;http://localhost:5000"
},
"Docker": {
"commandName": "Docker",
@@ -32,5 +26,13 @@
"publishAllPorts": true,
"useSSL": true
}
+ },
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:50352/",
+ "sslPort": 0
+ }
}
}
\ No newline at end of file
diff --git a/src/IO.Swagger/Repositories/IUserRepository.cs b/src/IO.Swagger/Repositories/IUserRepository.cs
new file mode 100644
index 0000000..3796497
--- /dev/null
+++ b/src/IO.Swagger/Repositories/IUserRepository.cs
@@ -0,0 +1,13 @@
+using IO.Swagger.Models.db;
+using IO.Swagger.Models.dto;
+using System.Threading.Tasks;
+
+namespace IO.Swagger.Repositories
+{
+ public interface IUserRepository
+ {
+ Task LoginUser(AuthLoginBody request);
+ Task RegisterUser(AuthRegisterBody request);
+ Task RetrieveUser(int userId);
+ }
+}
diff --git a/src/IO.Swagger/Repositories/UserRepository.cs b/src/IO.Swagger/Repositories/UserRepository.cs
new file mode 100644
index 0000000..856331e
--- /dev/null
+++ b/src/IO.Swagger/Repositories/UserRepository.cs
@@ -0,0 +1,77 @@
+using IO.Swagger.Models.db;
+using System.Security.Cryptography;
+using System;
+using IO.Swagger.Services;
+using IO.Swagger.Models.dto;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+using System.Linq;
+
+namespace IO.Swagger.Repositories
+{
+ public class UserRepository : IUserRepository
+ {
+ private readonly BankDbContext bankDbContext;
+
+ public UserRepository(BankDbContext bankDbContext)
+ {
+ this.bankDbContext = bankDbContext;
+ }
+
+ public async Task RegisterUser(AuthRegisterBody request)
+ {
+ request.Email = request.Email.ToLower();
+ if (await bankDbContext.Users.CountAsync((User u) => u.Email == request.Email) > 0)
+ return null;
+
+ // Generate a random salt
+ byte[] saltBytes = new byte[16];
+ new RNGCryptoServiceProvider().GetBytes(saltBytes);
+ 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);
+ string hashedPassword = Convert.ToBase64String(hashedBytes);
+
+ // Create and insert the user
+ var newUser = new User
+ {
+ PasswordHash = hashedPassword,
+ Salt = salt,
+ Email = request.Email,
+ FirstName = request.FirstName,
+ LastName = request.LastName
+ };
+
+ await bankDbContext.Users.AddAsync(newUser);
+ await bankDbContext.SaveChangesAsync();
+ 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)
+ 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);
+ 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 15c7ab0..3e74eff 100644
--- a/src/IO.Swagger/Security/BearerAuthenticationHandler.cs
+++ b/src/IO.Swagger/Security/BearerAuthenticationHandler.cs
@@ -1,4 +1,6 @@
using System;
+using System.IdentityModel.Tokens.Jwt;
+using System.Linq;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text;
@@ -7,6 +9,8 @@ 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
{
@@ -15,6 +19,9 @@ namespace IO.Swagger.Security
///
public class BearerAuthenticationHandler : AuthenticationHandler
{
+ private readonly string secretKey;
+ private readonly byte[] secretBytes;
+
///
/// scheme name for authentication handler.
///
@@ -22,6 +29,8 @@ namespace IO.Swagger.Security
public BearerAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
{
+ secretKey = Environment.GetEnvironmentVariable("JWT_SECRET_KEY");
+ secretBytes = Encoding.UTF8.GetBytes(secretKey);
}
///
@@ -37,22 +46,44 @@ namespace IO.Swagger.Security
{
var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);
- /// TODO handle token.
+ var tokenHandler = new JwtSecurityTokenHandler();
+ var validationParameters = new TokenValidationParameters
+ {
+ ValidateIssuerSigningKey = true,
+ IssuerSigningKey = new SymmetricSecurityKey(secretBytes),
+ ValidateIssuer = false,
+ ValidateAudience = false
+ };
+
+ 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
{
return AuthenticateResult.Fail("Invalid Authorization Header");
}
- var claims = new[] {
- new Claim(ClaimTypes.NameIdentifier, "changeme"),
- new Claim(ClaimTypes.Name, "changeme"),
- };
- var identity = new ClaimsIdentity(claims, Scheme.Name);
- var principal = new ClaimsPrincipal(identity);
- var ticket = new AuthenticationTicket(principal, Scheme.Name);
-
- return AuthenticateResult.Success(ticket);
+ return AuthenticateResult.Fail("Missing Authorization Header");
}
}
}
diff --git a/src/IO.Swagger/Services/BankDbContext.cs b/src/IO.Swagger/Services/BankDbContext.cs
new file mode 100644
index 0000000..71e0528
--- /dev/null
+++ b/src/IO.Swagger/Services/BankDbContext.cs
@@ -0,0 +1,17 @@
+using IO.Swagger.Models.db;
+using Microsoft.EntityFrameworkCore;
+
+namespace IO.Swagger.Services
+{
+
+ public class BankDbContext : DbContext
+ {
+ public BankDbContext(DbContextOptions options) : base(options)
+ {
+ }
+
+ public DbSet Users { get; set; }
+
+
+ }
+}
diff --git a/src/IO.Swagger/Services/JwtService.cs b/src/IO.Swagger/Services/JwtService.cs
new file mode 100644
index 0000000..ffbd279
--- /dev/null
+++ b/src/IO.Swagger/Services/JwtService.cs
@@ -0,0 +1,46 @@
+using Microsoft.IdentityModel.Tokens;
+using System.IdentityModel.Tokens.Jwt;
+using System.Security.Claims;
+using System.Text;
+using System;
+
+namespace IO.Swagger.Services
+{
+ public class JwtService
+ {
+ private readonly string secretKey;
+ private readonly byte[] secretBytes;
+
+ public JwtService()
+ {
+ secretKey = Environment.GetEnvironmentVariable("JWT_SECRET_KEY");
+ secretBytes = Encoding.UTF8.GetBytes(secretKey);
+ }
+
+ 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();
+ var tokenDescriptor = new SecurityTokenDescriptor
+ {
+ Subject = new ClaimsIdentity(claims),
+ Expires = DateTime.UtcNow.AddHours(1), // Token expiration time
+ SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(secretBytes), SecurityAlgorithms.HmacSha256Signature)
+ };
+
+ 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/Startup.cs b/src/IO.Swagger/Startup.cs
index 9a497e9..2f65e9b 100644
--- a/src/IO.Swagger/Startup.cs
+++ b/src/IO.Swagger/Startup.cs
@@ -23,6 +23,9 @@ 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;
namespace IO.Swagger
{
@@ -80,9 +83,9 @@ namespace IO.Swagger
Description = "T&J Central Bank API (ASP.NET 7.0)",
Contact = new OpenApiContact()
{
- Name = "Swagger Codegen Contributors",
- Url = new Uri("https://github.com/swagger-api/swagger-codegen"),
- Email = ""
+ Name = "Swagger Codegen Contributors",
+ Url = new Uri("https://github.com/swagger-api/swagger-codegen"),
+ Email = ""
},
// TermsOfService = new Uri("")
});
@@ -94,7 +97,40 @@ namespace IO.Swagger
// Include DataAnnotation attributes on Controller Action parameters as Swagger validation rules (e.g required, pattern, ..)
// Use [ValidateModelState] on Actions to actually validate it in C# as well!
c.OperationFilter();
+ c.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme()
+ {
+ In = ParameterLocation.Header,
+ Description = "Please enter a valid token",
+ Name = "Authorization",
+ Type = SecuritySchemeType.Http,
+ BearerFormat = "JWT",
+ Scheme = "bearer"
+ });
+ c.AddSecurityRequirement(new OpenApiSecurityRequirement()
+ {
+ {
+ new OpenApiSecurityScheme
+ {
+ Reference = new OpenApiReference
+ {
+ Type=ReferenceType.SecurityScheme,
+ Id="bearerAuth"
+ }
+ },
+ new string[]{}
+ }
+ });
});
+
+ string connectionString = Environment.GetEnvironmentVariable("DATABASE_CONNECTION_STRING");
+
+ if (string.IsNullOrEmpty(connectionString))
+ {
+ throw new Exception("Database connection string not found in environment variable.");
+ }
+ services.AddScoped();
+ services.AddDbContext(x => x.UseSqlServer(connectionString: connectionString));
+ services.AddSingleton();
}
///
@@ -103,8 +139,10 @@ namespace IO.Swagger
///
///
///
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
+ ///
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory, BankDbContext context)
{
+ context.Database.Migrate();
app.UseRouting();
//TODO: Uncomment this if you need wwwroot folder
diff --git a/src/IO.Swagger/web.config b/src/IO.Swagger/web.config
index 2c68e3c..c846261 100644
--- a/src/IO.Swagger/web.config
+++ b/src/IO.Swagger/web.config
@@ -17,7 +17,7 @@
-
+