summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHombreLaser <sebastian-440@live.com>2022-11-27 12:46:26 -0600
committerHombreLaser <sebastian-440@live.com>2022-11-27 12:46:26 -0600
commit3da900a30e788d0acf2fcee7dba2aecdb16aab43 (patch)
treeec8312f37d26f81b22fb498728572f08983d67e5
parent45eb6bcac6eaa57efba955dd45aad46f988aaf35 (diff)
Añadido logout
-rw-r--r--Controllers/RafflesController.cs2
-rw-r--r--Controllers/UserAccountSessionsController.cs15
-rw-r--r--Logics/BaseUserAccountLogic.cs2
-rw-r--r--Logics/DestroyUserAccountSessionLogic.cs30
-rw-r--r--Logics/RefreshTokenLogic.cs1
-rw-r--r--Migrations/20221127165449_AddCurrentTokenToUser.Designer.cs468
-rw-r--r--Migrations/20221127165449_AddCurrentTokenToUser.cs28
-rw-r--r--Migrations/ApplicationDbContextModelSnapshot.cs7
-rw-r--r--Models/UserAccount.cs1
-rw-r--r--Policies/CorrectTokenHandler.cs29
-rw-r--r--Policies/CorrectTokenRequirement.cs5
-rw-r--r--Program.cs8
12 files changed, 593 insertions, 3 deletions
diff --git a/Controllers/RafflesController.cs b/Controllers/RafflesController.cs
index c649b70..aff4085 100644
--- a/Controllers/RafflesController.cs
+++ b/Controllers/RafflesController.cs
@@ -68,7 +68,7 @@ namespace BackendPIA.Controllers {
return StatusCode(303, new { Message = "The resource has been deleted"} );
}
- [Authorize]
+ [Authorize(Policy = "ValidToken")]
[HttpGet("{id:int}/available_tickets")]
public async Task<ActionResult<IEnumerable<int>>> AvailableTickets(long id) {
IEnumerable<int> available_tickets = from number in Enumerable.Range(1, 54) select number;
diff --git a/Controllers/UserAccountSessionsController.cs b/Controllers/UserAccountSessionsController.cs
index 217c05c..ebeca96 100644
--- a/Controllers/UserAccountSessionsController.cs
+++ b/Controllers/UserAccountSessionsController.cs
@@ -32,11 +32,24 @@ namespace BackendPIA.Controllers {
return StatusCode(401, new InvalidLoginError(401, "Check your credentials"));
}
+ [Authorize(Policy = "ValidToken")]
+ [HttpDelete("logout")]
+ public async Task<ActionResult> Delete() {
+ string email = HttpContext.User.Claims.Where(c => c.Type.Contains("email")).First().Value;
+ DestroyUserAccountSessionLogic logic = new DestroyUserAccountSessionLogic(_manager, email);
+ bool result = await logic.Call();
+
+ if(result)
+ return Ok();
+
+ return NotFound(new NotFoundError(404, "Couldn't find the user."));
+ }
+
// [Authorize]
[HttpPost("refresh")]
public async Task<ActionResult<AuthenticationToken>> Refresh(AuthenticationToken form) {
RefreshTokenLogic logic = new RefreshTokenLogic(_token_generator, _manager, form);
- var result = await logic.Call();
+ bool result = await logic.Call();
if(result)
return Ok(logic.Token);
diff --git a/Logics/BaseUserAccountLogic.cs b/Logics/BaseUserAccountLogic.cs
index 4ce17e0..43a8ed9 100644
--- a/Logics/BaseUserAccountLogic.cs
+++ b/Logics/BaseUserAccountLogic.cs
@@ -19,6 +19,8 @@ namespace BackendPIA.Logics {
var roles = await _manager.GetRolesAsync(user);
_token = new AuthenticationToken { Token = _token_generator.Generate(user, roles[0]),
RefreshToken = _token_generator.GenerateRefreshToken() };
+ user.CurrentToken = _token.Token;
+ await _manager.UpdateAsync(user);
}
// We overwrite or set the value of the session token in the database: all other previous logins are invalid.
diff --git a/Logics/DestroyUserAccountSessionLogic.cs b/Logics/DestroyUserAccountSessionLogic.cs
new file mode 100644
index 0000000..1e5a5f5
--- /dev/null
+++ b/Logics/DestroyUserAccountSessionLogic.cs
@@ -0,0 +1,30 @@
+using Microsoft.AspNetCore.Identity;
+using BackendPIA.Services;
+using BackendPIA.Models;
+using BackendPIA.Forms;
+
+namespace BackendPIA.Logics {
+ public class DestroyUserAccountSessionLogic {
+ private readonly UserManager<UserAccount> _manager;
+ private readonly string _email;
+
+ public DestroyUserAccountSessionLogic(UserManager<UserAccount> manager, string email) {
+ _manager = manager;
+ _email = email;
+ }
+
+ public async Task<bool> Call() {
+ var user = await _manager.FindByEmailAsync(_email);
+
+ if(user == null)
+ return false;
+
+ user.SessionToken = null;
+ user.CurrentToken = null;
+ user.SessionTokenExpiryTime = null;
+ await _manager.UpdateAsync(user);
+
+ return true;
+ }
+ }
+} \ No newline at end of file
diff --git a/Logics/RefreshTokenLogic.cs b/Logics/RefreshTokenLogic.cs
index 200438a..3493f47 100644
--- a/Logics/RefreshTokenLogic.cs
+++ b/Logics/RefreshTokenLogic.cs
@@ -26,6 +26,7 @@ namespace BackendPIA.Logics {
|| user.SessionToken == null || user.SessionToken != _form.RefreshToken) {
user.SessionToken = null;
user.SessionTokenExpiryTime = null;
+ user.CurrentToken = null;
_manager.UpdateAsync(user);
return false;
diff --git a/Migrations/20221127165449_AddCurrentTokenToUser.Designer.cs b/Migrations/20221127165449_AddCurrentTokenToUser.Designer.cs
new file mode 100644
index 0000000..3576dd7
--- /dev/null
+++ b/Migrations/20221127165449_AddCurrentTokenToUser.Designer.cs
@@ -0,0 +1,468 @@
+// <auto-generated />
+using System;
+using BackendPIA.Models;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace BackendPIA.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ [Migration("20221127165449_AddCurrentTokenToUser")]
+ partial class AddCurrentTokenToUser
+ {
+ /// <inheritdoc />
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.0")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("BackendPIA.Models.Prize", b =>
+ {
+ b.Property<long>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+ b.Property<string>("Category")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property<long>("RaffleId")
+ .HasColumnType("bigint");
+
+ b.Property<int>("Tier")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RaffleId");
+
+ b.ToTable("Prizes");
+ });
+
+ modelBuilder.Entity("BackendPIA.Models.Raffle", b =>
+ {
+ b.Property<long>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+ b.Property<bool>("IsClosed")
+ .HasColumnType("boolean");
+
+ b.Property<string>("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("character varying(128)");
+
+ b.Property<int>("Winners")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("Raffles");
+ });
+
+ modelBuilder.Entity("BackendPIA.Models.RaffleWinner", b =>
+ {
+ b.Property<long>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+ b.Property<long>("PrizeId")
+ .HasColumnType("bigint");
+
+ b.Property<long>("RaffleId")
+ .HasColumnType("bigint");
+
+ b.Property<string>("UserAccountId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PrizeId");
+
+ b.HasIndex("RaffleId");
+
+ b.HasIndex("UserAccountId");
+
+ b.ToTable("RaffleWinners");
+ });
+
+ modelBuilder.Entity("BackendPIA.Models.Ticket", b =>
+ {
+ b.Property<long>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
+
+ b.Property<bool>("IsWinner")
+ .HasColumnType("boolean");
+
+ b.Property<int>("Number")
+ .HasColumnType("integer");
+
+ b.Property<long>("RaffleId")
+ .HasColumnType("bigint");
+
+ b.Property<string>("UserAccountId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RaffleId");
+
+ b.HasIndex("UserAccountId");
+
+ b.ToTable("Tickets");
+ });
+
+ modelBuilder.Entity("BackendPIA.Models.UserAccount", b =>
+ {
+ b.Property<string>("Id")
+ .HasColumnType("text");
+
+ b.Property<int>("AccessFailedCount")
+ .HasColumnType("integer");
+
+ b.Property<string>("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property<string>("CurrentToken")
+ .HasColumnType("text");
+
+ b.Property<string>("Email")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<bool>("EmailConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property<bool>("LockoutEnabled")
+ .HasColumnType("boolean");
+
+ b.Property<DateTimeOffset?>("LockoutEnd")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<string>("NormalizedEmail")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("NormalizedUserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("PasswordHash")
+ .HasColumnType("text");
+
+ b.Property<string>("PhoneNumber")
+ .HasColumnType("text");
+
+ b.Property<bool>("PhoneNumberConfirmed")
+ .HasColumnType("boolean");
+
+ b.Property<string>("SecurityStamp")
+ .HasColumnType("text");
+
+ b.Property<string>("SessionToken")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.Property<DateTime?>("SessionTokenExpiryTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property<bool>("TwoFactorEnabled")
+ .HasColumnType("boolean");
+
+ b.Property<string>("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasDatabaseName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasDatabaseName("UserNameIndex");
+
+ b.ToTable("AspNetUsers", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+ {
+ b.Property<string>("Id")
+ .HasColumnType("text");
+
+ b.Property<string>("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property<string>("NormalizedName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasDatabaseName("RoleNameIndex");
+
+ b.ToTable("AspNetRoles", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+
+ b.Property<string>("ClaimType")
+ .HasColumnType("text");
+
+ b.Property<string>("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property<string>("RoleId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+ {
+ b.Property<int>("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
+
+ b.Property<string>("ClaimType")
+ .HasColumnType("text");
+
+ b.Property<string>("ClaimValue")
+ .HasColumnType("text");
+
+ b.Property<string>("UserId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+ {
+ b.Property<string>("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property<string>("ProviderKey")
+ .HasColumnType("text");
+
+ b.Property<string>("ProviderDisplayName")
+ .HasColumnType("text");
+
+ b.Property<string>("UserId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+ {
+ b.Property<string>("UserId")
+ .HasColumnType("text");
+
+ b.Property<string>("RoleId")
+ .HasColumnType("text");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+ {
+ b.Property<string>("UserId")
+ .HasColumnType("text");
+
+ b.Property<string>("LoginProvider")
+ .HasColumnType("text");
+
+ b.Property<string>("Name")
+ .HasColumnType("text");
+
+ b.Property<string>("Value")
+ .HasColumnType("text");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens", (string)null);
+ });
+
+ modelBuilder.Entity("BackendPIA.Models.Prize", b =>
+ {
+ b.HasOne("BackendPIA.Models.Raffle", "Raffle")
+ .WithMany("Prizes")
+ .HasForeignKey("RaffleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Raffle");
+ });
+
+ modelBuilder.Entity("BackendPIA.Models.RaffleWinner", b =>
+ {
+ b.HasOne("BackendPIA.Models.Prize", "Prize")
+ .WithMany()
+ .HasForeignKey("PrizeId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("BackendPIA.Models.Raffle", "Raffle")
+ .WithMany()
+ .HasForeignKey("RaffleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("BackendPIA.Models.UserAccount", "UserAccount")
+ .WithMany()
+ .HasForeignKey("UserAccountId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Prize");
+
+ b.Navigation("Raffle");
+
+ b.Navigation("UserAccount");
+ });
+
+ modelBuilder.Entity("BackendPIA.Models.Ticket", b =>
+ {
+ b.HasOne("BackendPIA.Models.Raffle", "Raffle")
+ .WithMany("Tickets")
+ .HasForeignKey("RaffleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("BackendPIA.Models.UserAccount", "Owner")
+ .WithMany("Tickets")
+ .HasForeignKey("UserAccountId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Owner");
+
+ b.Navigation("Raffle");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
+ {
+ b.HasOne("BackendPIA.Models.UserAccount", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
+ {
+ b.HasOne("BackendPIA.Models.UserAccount", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("BackendPIA.Models.UserAccount", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
+ {
+ b.HasOne("BackendPIA.Models.UserAccount", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("BackendPIA.Models.Raffle", b =>
+ {
+ b.Navigation("Prizes");
+
+ b.Navigation("Tickets");
+ });
+
+ modelBuilder.Entity("BackendPIA.Models.UserAccount", b =>
+ {
+ b.Navigation("Tickets");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Migrations/20221127165449_AddCurrentTokenToUser.cs b/Migrations/20221127165449_AddCurrentTokenToUser.cs
new file mode 100644
index 0000000..cc998b2
--- /dev/null
+++ b/Migrations/20221127165449_AddCurrentTokenToUser.cs
@@ -0,0 +1,28 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace BackendPIA.Migrations
+{
+ /// <inheritdoc />
+ public partial class AddCurrentTokenToUser : Migration
+ {
+ /// <inheritdoc />
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn<string>(
+ name: "CurrentToken",
+ table: "AspNetUsers",
+ type: "text",
+ nullable: true);
+ }
+
+ /// <inheritdoc />
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "CurrentToken",
+ table: "AspNetUsers");
+ }
+ }
+}
diff --git a/Migrations/ApplicationDbContextModelSnapshot.cs b/Migrations/ApplicationDbContextModelSnapshot.cs
index 917cafd..37dac6d 100644
--- a/Migrations/ApplicationDbContextModelSnapshot.cs
+++ b/Migrations/ApplicationDbContextModelSnapshot.cs
@@ -146,6 +146,9 @@ namespace BackendPIA.Migrations
.IsConcurrencyToken()
.HasColumnType("text");
+ b.Property<string>("CurrentToken")
+ .HasColumnType("text");
+
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("character varying(256)");
@@ -340,7 +343,7 @@ namespace BackendPIA.Migrations
modelBuilder.Entity("BackendPIA.Models.Prize", b =>
{
b.HasOne("BackendPIA.Models.Raffle", "Raffle")
- .WithMany()
+ .WithMany("Prizes")
.HasForeignKey("RaffleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
@@ -447,6 +450,8 @@ namespace BackendPIA.Migrations
modelBuilder.Entity("BackendPIA.Models.Raffle", b =>
{
+ b.Navigation("Prizes");
+
b.Navigation("Tickets");
});
diff --git a/Models/UserAccount.cs b/Models/UserAccount.cs
index 333138d..94ee69b 100644
--- a/Models/UserAccount.cs
+++ b/Models/UserAccount.cs
@@ -5,6 +5,7 @@ namespace BackendPIA.Models {
public class UserAccount : IdentityUser {
[StringLength(64)]
public string? SessionToken { get; set; }
+ public string? CurrentToken { get; set; }
public DateTime? SessionTokenExpiryTime { get; set; }
public ICollection<Ticket>? Tickets { get; set; }
}
diff --git a/Policies/CorrectTokenHandler.cs b/Policies/CorrectTokenHandler.cs
new file mode 100644
index 0000000..7663ec8
--- /dev/null
+++ b/Policies/CorrectTokenHandler.cs
@@ -0,0 +1,29 @@
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Authorization;
+using BackendPIA.Models;
+
+namespace BackendPIA.Policies {
+ public class CorrectTokenHandler : AuthorizationHandler<CorrectTokenRequirement> {
+ private readonly UserManager<UserAccount> _manager;
+
+ public CorrectTokenHandler(UserManager<UserAccount> manager) {
+ _manager = manager;
+ }
+
+ protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CorrectTokenRequirement requirement) {
+ if(context.Resource is HttpContext httpContext) {
+ var user = _manager.FindByEmailAsync(context.User.Claims.Where(c => c.Type.Contains("email")).First().Value).Result;
+
+ if(user != null) {
+ string token = httpContext.Request.Headers["Authorization"].ToString().Split(' ')[1];
+
+ if(user.CurrentToken != null && user.CurrentToken == token)
+ context.Succeed(requirement);
+ }
+ }
+
+ return Task.CompletedTask;
+ }
+ }
+} \ No newline at end of file
diff --git a/Policies/CorrectTokenRequirement.cs b/Policies/CorrectTokenRequirement.cs
new file mode 100644
index 0000000..d89615f
--- /dev/null
+++ b/Policies/CorrectTokenRequirement.cs
@@ -0,0 +1,5 @@
+using Microsoft.AspNetCore.Authorization;
+
+namespace BackendPIA.Policies {
+ public class CorrectTokenRequirement : IAuthorizationRequirement{}
+} \ No newline at end of file
diff --git a/Program.cs b/Program.cs
index ed98bd4..793aa1e 100644
--- a/Program.cs
+++ b/Program.cs
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
@@ -8,6 +9,7 @@ using System.Text;
using Microsoft.EntityFrameworkCore;
using BackendPIA;
using BackendPIA.Models;
+using BackendPIA.Policies;
using BackendPIA.Services;
var builder = WebApplication.CreateBuilder(args);
@@ -32,6 +34,8 @@ builder.Services.AddScoped<IRaffleService, RaffleService>();
builder.Services.AddScoped<ITicketService, TicketService>();
builder.Services.AddScoped<IPrizeService, PrizeService>();
// End of custom services configuration.
+// Register the custom authorization handler.
+builder.Services.AddScoped<IAuthorizationHandler, CorrectTokenHandler>();
// Swagger configuration.
builder.Services.AddEndpointsApiExplorer();
@@ -75,6 +79,10 @@ builder.Services.AddAuthentication(options => {
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])),
ClockSkew = TimeSpan.Zero }
);
+
+builder.Services.AddAuthorization(options => {
+ options.AddPolicy("ValidToken", policy => policy.Requirements.Add(new CorrectTokenRequirement()));
+});
// End of authentication configuration.
// Identity configuration.