Added signup support

This commit is contained in:
quentin 2024-08-31 18:38:07 -05:00
parent fe1213ed90
commit f212f85d00
14 changed files with 310 additions and 11 deletions

5
.gitignore vendored
View File

@ -5,7 +5,4 @@
/API/appsettings.*
/Setup/bin/
/Setup/obj/
/Setup/appsettings.*
/web/bin/
/web/obj/
/web/appsettings.*
/Setup/appsettings.*

View File

@ -0,0 +1,14 @@
namespace API.Authentication.GrantNames
{
public static class SignupGrantNames
{
public const string CanGetAll = "api.signup.get.all";
public const string CanGetAny = "api.signup.get.any";
public const string CanGet = "api.signup.get";
public const string CanAdd = "api.signup.add";
public const string CanUpdateAny = "api.signup.update.any";
public const string CanUpdate = "api.signup.update";
public const string CanDeleteAny = "api.signup.delete.any";
public const string CanDelete = "api.signup.delete";
}
}

View File

@ -0,0 +1,9 @@
using API.DTO.Base.Update;
using DAL.Models;
namespace API.Authentication.Interfaces
{
public interface ISignupAuthentication : IGenericAuthentication<SignupDTO, Signup>
{
}
}

View File

@ -0,0 +1,46 @@
using API.Authentication.GrantNames;
using API.Authentication.Interfaces;
using API.DTO.Base.Update;
using API.Services.Interfaces;
using DAL.Models;
namespace API.Authentication
{
public class SignupAuthentication : ISignupAuthentication
{
private readonly IGrantManager _grantManager;
private readonly ILogger<SignupAuthentication> _logger;
public SignupAuthentication(IGrantManager grantManager, ILogger<SignupAuthentication> logger)
{
_grantManager = grantManager;
_logger = logger;
}
//todo make more restrictive
public bool canGetAll(User user)
{
return _grantManager.hasGrant(user.permissionId, SignupGrantNames.CanGetAll);
}
public bool canGet(Signup model, User user)
{
return _grantManager.hasGrant(user.permissionId, SignupGrantNames.CanGetAny) ||
_grantManager.getULongValues(user.permissionId, SignupGrantNames.CanGet).Exists(x => x == model.id);
}
public bool canAdd(SignupDTO item, User user)
{
return _grantManager.hasGrant(user.permissionId, SignupGrantNames.CanAdd);
}
public bool canUpdate(Signup model, User user)
{
return _grantManager.hasGrant(user.permissionId, SignupGrantNames.CanUpdateAny) ||
_grantManager.getULongValues(user.permissionId, SignupGrantNames.CanUpdate).Exists(x => x == model.id);
}
public bool canDelete(Signup model, User user)
{
return _grantManager.hasGrant(user.permissionId, SignupGrantNames.CanDeleteAny) ||
_grantManager.getULongValues(user.permissionId, SignupGrantNames.CanDelete).Exists(x => x == model.id);
}
}
}

View File

@ -0,0 +1,62 @@
using API.Authentication;
using API.Authentication.Interfaces;
using API.DTO.Base.Update;
using API.Services;
using DAL.Models;
using DAL.Models.Audits;
using Microsoft.AspNetCore.Mvc;
using MUser = DAL.Models.User;
namespace API.Controllers
{
[ApiController]
[Route("api/v1/[controller]")]
public class SignupController : CRUDBase<SignupController, SignupDTO, SignupUpdateDTO, Signup, AuditSignup, ISignupAuthentication, SignupService>
{
public SignupController(ILogger<SignupController> logger, UserService userService, SignupService service) : base(logger, userService, service)
{
}
[HttpPost]
public override ActionResult<SignupDTO> add(SignupDTO createDTO)
{
MUser? user = getUser(User);
if (user == null)
return Unauthorized();
// todo
createDTO.userId = user.id;
if (createDTO.userId != user.id)
{
return Forbid();
}
Signup? result = Service.add(createDTO, user);
if (result == null)
return Forbid();
SignupDTO dto = new SignupDTO();
dto.adaptFromModel(result);
return Ok(dto);
}
[HttpDelete("event/{eventId}")]
public virtual ActionResult delete(ulong eventId)
{
MUser? user = getUser(User);
if (user == null)
return Unauthorized();
Signup? result = Service.getNoAuthentication(x => x.userId == user.id && x.eventId == eventId).FirstOrDefault();
if (result == null)
return Forbid();
AuditSignup? auditModel = Service.delete(result, user);
if (auditModel == null)
return Forbid();
return NoContent();
}
}
}

33
API/DTO/Base/SignupDTO.cs Normal file
View File

@ -0,0 +1,33 @@
using DAL.Models;
namespace API.DTO.Base.Update
{
public class SignupDTO : IAdaptable<Signup>
{
public ulong id { get; set; }
public ulong eventId { get; set; }
public ulong userId { get; set; }
public DateTime updated { get; set; }
public ulong updater { get; set; }
public Signup adaptToModel()
{
return new Signup
{
id = id,
eventId = eventId,
userId = userId,
updated = updated,
updater = updater
};
}
public void adaptFromModel(in Signup model)
{
id = model.id;
eventId = model.eventId;
userId = model.userId;
updated = model.updated;
updater = model.updater;
}
}
}

View File

@ -0,0 +1,16 @@
using DAL.Models;
namespace API.DTO.Base.Update
{
public class SignupUpdateDTO : IUpdateAdaptable<Signup>
{
public ulong? eventId { get; set; }
public ulong? userId { get; set; }
public void adaptModel(ref Signup model)
{
if (eventId != null) model.eventId = (ulong)eventId;
if (userId != null) model.userId = (ulong)userId;
}
}
}

View File

@ -56,6 +56,7 @@ namespace API
builder.Services.AddTransient<ImageService>();
builder.Services.AddTransient<PermissionService>();
builder.Services.AddTransient<SavedEventService>();
builder.Services.AddTransient<SignupService>();
builder.Services.AddTransient<UserService>(options =>
{
ILogger<UserService> logger = options.GetRequiredService<ILogger<UserService>>();
@ -76,6 +77,7 @@ namespace API
builder.Services.AddTransient<IPermissionAuthentication, PermissionAuthentication>();
builder.Services.AddTransient<ISavedEventAuthentication, SavedEventAuthentication>();
builder.Services.AddTransient<IUserAuthentication, UserAuthentication>();
builder.Services.AddTransient<ISignupAuthentication, SignupAuthentication>();
builder.Services.AddTransient<IHashingFactory, HashingFactory>();
@ -96,11 +98,12 @@ namespace API
});
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
{
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
// builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
// {
// options.Cookie.SameSite = SameSiteMode.None;
// options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
// });
builder.Services.AddLazyResolution();
@ -114,7 +117,7 @@ namespace API
app.UseCookiePolicy(new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.None
MinimumSameSitePolicy = SameSiteMode.Strict
});
app.UseAuthorization();

View File

@ -14,7 +14,7 @@ namespace API.Services
where TAudit : AuditModel<TModel>
where TDTO : IAdaptable<TModel>
{
private readonly TAuthentication _auth;
public readonly TAuthentication _auth;
private readonly ILogger<TLoggerCategory> _logger;
public readonly SASGContext Context;

View File

@ -0,0 +1,16 @@
using API.Authentication.Interfaces;
using API.DTO.Base.Update;
using DAL.Contexts;
using DAL.Models;
using DAL.Models.Audits;
namespace API.Services
{
public class SignupService : ServiceBase<SignupService, SignupDTO, Signup, AuditSignup, ISignupAuthentication>
{
public SignupService(ILogger<SignupService> logger, SASGContext context, ISignupAuthentication auth) : base(logger, context, auth)
{
}
}
}

View File

@ -24,6 +24,7 @@ namespace DAL.Contexts
public virtual DbSet<Image> images { get; set; }
public virtual DbSet<Permission> permissions { get; set; }
public virtual DbSet<SavedEvent> savedEvents { get; set; }
public virtual DbSet<Signup> signups { get; set; }
public virtual DbSet<User> users { get; set; }
public virtual DbSet<AuditColor> auditColors { get; set; }
public virtual DbSet<AuditEvent> auditEvents { get; set; }
@ -32,6 +33,7 @@ namespace DAL.Contexts
public virtual DbSet<AuditPermission> auditPermissions { get; set; }
public virtual DbSet<AuditSavedEvent> auditSavedEvents { get; set; }
public virtual DbSet<AuditUser> auditUsers { get; set; }
public virtual DbSet<AuditSignup> auditSignups { get; set; }
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
@ -98,6 +100,16 @@ namespace DAL.Contexts
.HasForeignKey(e => e.updater).HasConstraintName("events_users_id_fk");
entity.Property(e => e.hashingType).HasConversion<string>();
});
builder.Entity<Signup>(entity =>
{
entity.HasOne(e => e.eventIdRelation).WithMany()
.HasForeignKey(e => e.eventId).HasConstraintName("signup_events_id_fk");
entity.HasOne(e => e.userIdRelation).WithMany()
.HasForeignKey(e => e.userId).HasConstraintName("signup_users_id_fk");
entity.HasOne(e => e.updaterRelation).WithMany()
.HasForeignKey(e => e.updater).HasConstraintName("events_users_id_fk2");
});
}
}
}

View File

@ -0,0 +1,28 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations.Schema;
namespace DAL.Models.Audits
{
[Table("audit_signup")]
[Index("id", Name = "audit_signup_originalId_index")]
public class AuditSignup : AuditModel<Signup>
{
[Column("eventId")]
public ulong eventId { get; set; }
[Column("userId")]
public ulong userId { get; set; }
public override Signup adaptToModel()
{
return new Signup
{
id = originalId,
eventId = eventId,
userId = userId,
updated = updated,
updater = updater
};
}
}
}

39
DAL/Models/Signup.cs Normal file
View File

@ -0,0 +1,39 @@
using DAL.Models.Audits;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations.Schema;
namespace DAL.Models
{
[Table("signup")]
[Index("eventId", Name = "signup_event_id_fk")]
[Index("userId", Name = "signup_users_id_fk")]
[Index("updater", Name = "signup_users_id_fk_2")]
public class Signup : Model<Signup, AuditSignup>
{
[Column("eventId")]
public ulong eventId { get; set; }
[Column("userid")]
public ulong userId { get; set; }
public Event eventIdRelation { get; set; } = null!;
public User userIdRelation { get; set; } = null!;
public override AuditSignup adaptToAudit()
{
return new AuditSignup
{
id = id,
eventId = eventId,
userId = userId,
};
}
public override void updateModel(ref Signup dest)
{
dest.eventId = eventId;
dest.userId = userId;
}
}
}

View File

@ -177,4 +177,28 @@ VALUES ('api.user.update.permission', 1, NOW(), 1);
INSERT INTO san_antonio_senior_golf.grants (name, permissionId, updated, updater)
VALUES ('api.user.delete.any', 1, NOW(), 1);
INSERT INTO san_antonio_senior_golf.grants (name, permissionId, updated, updater)
VALUES ('api.signup.get.all', 1, NOW(), 1);
INSERT INTO san_antonio_senior_golf.grants (name, permissionId, updated, updater)
VALUES ('api.signup.get.any', 1, NOW(), 1);
INSERT INTO san_antonio_senior_golf.grants (name, permissionId, updated, updater)
VALUES ('api.signup.get', 1, NOW(), 1);
INSERT INTO san_antonio_senior_golf.grants (name, permissionId, updated, updater)
VALUES ('api.signup.add', 1, NOW(), 1);
INSERT INTO san_antonio_senior_golf.grants (name, permissionId, updated, updater)
VALUES ('api.signup.update.any', 1, NOW(), 1);
INSERT INTO san_antonio_senior_golf.grants (name, permissionId, updated, updater)
VALUES ('api.signup.update', 1, NOW(), 1);
INSERT INTO san_antonio_senior_golf.grants (name, permissionId, updated, updater)
VALUES ('api.signup.delete.any', 1, NOW(), 1);
INSERT INTO san_antonio_senior_golf.grants (name, permissionId, updated, updater)
VALUES ('api.signup.delete', 1, NOW(), 1);
SET FOREIGN_KEY_CHECKS = 1;