From e2140d83f2dc920771573db0543a979eb19b971c Mon Sep 17 00:00:00 2001 From: quentin Date: Wed, 10 Jul 2024 18:35:53 -0500 Subject: [PATCH] Changed phone number to use PhoneNumber.cs implicit string --- API/DTO/Base/Update/UserUpdateDTO.cs | 5 +- API/DTO/Base/UserDTO.cs | 3 +- API/DTO/Login/UserLoginDTO.cs | 3 +- API/Services/UserManager.cs | 2 +- DAL/Contexts/SASGContext.cs | 8 +++ DAL/Converters/PhoneNumberConverter.cs | 19 +++++++ DAL/Models/Audits/AuditUser.cs | 3 +- DAL/Models/User.cs | 4 +- DAL/Values/PhoneNumber.cs | 71 ++++++++++++++++++++++++++ 9 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 DAL/Converters/PhoneNumberConverter.cs create mode 100644 DAL/Values/PhoneNumber.cs diff --git a/API/DTO/Base/Update/UserUpdateDTO.cs b/API/DTO/Base/Update/UserUpdateDTO.cs index 2244d6c..956ce32 100644 --- a/API/DTO/Base/Update/UserUpdateDTO.cs +++ b/API/DTO/Base/Update/UserUpdateDTO.cs @@ -1,4 +1,5 @@ using DAL.Models; +using DAL.Values; using System.ComponentModel.DataAnnotations; namespace API.DTO.Base.Update @@ -11,7 +12,7 @@ namespace API.DTO.Base.Update [MaxLength(64)] public string? lastName { get; set; } - public ulong? phoneNumber { get; set; } + public PhoneNumber? phoneNumber { get; set; } public ulong? permissionId { get; set; } @@ -19,7 +20,7 @@ namespace API.DTO.Base.Update { if (firstName != null) model.firstName = firstName; if (lastName != null) model.lastName = lastName; - if (phoneNumber != null) model.phoneNumber = (ulong)phoneNumber; + if (phoneNumber != null) model.phoneNumber = phoneNumber; if (permissionId != null) model.permissionId = (ulong)permissionId; } } diff --git a/API/DTO/Base/UserDTO.cs b/API/DTO/Base/UserDTO.cs index cb640d9..468900a 100644 --- a/API/DTO/Base/UserDTO.cs +++ b/API/DTO/Base/UserDTO.cs @@ -1,4 +1,5 @@ using DAL.Models; +using DAL.Values; using System.ComponentModel.DataAnnotations; namespace API.DTO.Base @@ -13,7 +14,7 @@ namespace API.DTO.Base [MaxLength(64)] public string lastName { get; set; } = null!; - public ulong phoneNumber { get; set; } + public PhoneNumber phoneNumber { get; set; } = null!; public ulong permissionId { get; set; } diff --git a/API/DTO/Login/UserLoginDTO.cs b/API/DTO/Login/UserLoginDTO.cs index cde6a8d..279e384 100644 --- a/API/DTO/Login/UserLoginDTO.cs +++ b/API/DTO/Login/UserLoginDTO.cs @@ -1,10 +1,11 @@ +using DAL.Values; using System.ComponentModel.DataAnnotations; namespace API.DTO.Login { public class UserLoginDTO { - public ulong phoneNumber { get; set; } + public PhoneNumber phoneNumber { get; set; } = null!; [MaxLength(100)] public string password { get; set; } = null!; diff --git a/API/Services/UserManager.cs b/API/Services/UserManager.cs index 720c903..d104d70 100644 --- a/API/Services/UserManager.cs +++ b/API/Services/UserManager.cs @@ -23,7 +23,7 @@ namespace API.Services public UserDTO? AuthenticateUser(UserLoginDTO loginDTO) { - User? user = _userService.getNoAuthentication(x => x.phoneNumber == loginDTO.phoneNumber).FirstOrDefault(); + User? user = _userService.getNoAuthentication(x => x.phoneNumber.Equals(loginDTO.phoneNumber)).FirstOrDefault(); if (user == null) return null; diff --git a/DAL/Contexts/SASGContext.cs b/DAL/Contexts/SASGContext.cs index c55de12..f21a7f1 100644 --- a/DAL/Contexts/SASGContext.cs +++ b/DAL/Contexts/SASGContext.cs @@ -1,5 +1,7 @@ +using DAL.Converters; using DAL.Models; using DAL.Models.Audits; +using DAL.Values; using Microsoft.EntityFrameworkCore; namespace DAL.Contexts @@ -31,6 +33,11 @@ namespace DAL.Contexts public virtual DbSet auditSavedEvents { get; set; } public virtual DbSet auditUsers { get; set; } + protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) + { + configurationBuilder.Properties().HaveConversion(); + } + protected override void OnModelCreating(ModelBuilder builder) { builder.Entity(entity => @@ -89,6 +96,7 @@ namespace DAL.Contexts { entity.HasOne(e => e.updaterRelation).WithMany() .HasForeignKey(e => e.updater).HasConstraintName("events_users_id_fk"); + entity.Property(e => e.hashingType).HasConversion(); }); builder.Entity(entity => diff --git a/DAL/Converters/PhoneNumberConverter.cs b/DAL/Converters/PhoneNumberConverter.cs new file mode 100644 index 0000000..1f2b708 --- /dev/null +++ b/DAL/Converters/PhoneNumberConverter.cs @@ -0,0 +1,19 @@ +using DAL.Values; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace DAL.Converters +{ + public class PhoneNumberConverter : ValueConverter + { + public PhoneNumberConverter() : base( + v => v.value, + v => new PhoneNumber + { + value = v + } + ) + { + + } + } +} diff --git a/DAL/Models/Audits/AuditUser.cs b/DAL/Models/Audits/AuditUser.cs index 6e78dd8..121f514 100644 --- a/DAL/Models/Audits/AuditUser.cs +++ b/DAL/Models/Audits/AuditUser.cs @@ -1,3 +1,4 @@ +using DAL.Values; using Microsoft.EntityFrameworkCore; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -17,7 +18,7 @@ namespace DAL.Models.Audits public string lastName { get; set; } = null!; [Column("phoneNumber")] - public ulong phoneNumber { get; set; } + public PhoneNumber phoneNumber { get; set; } = null!; [Column("hashingType")] [MaxLength(64)] diff --git a/DAL/Models/User.cs b/DAL/Models/User.cs index 482f8a1..1e9acd6 100644 --- a/DAL/Models/User.cs +++ b/DAL/Models/User.cs @@ -1,4 +1,5 @@ using DAL.Models.Audits; +using DAL.Values; using Microsoft.EntityFrameworkCore; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -26,7 +27,8 @@ namespace DAL.Models public string lastName { get; set; } = null!; [Column("phoneNumber")] - public ulong phoneNumber { get; set; } + [MaxLength(32)] + public PhoneNumber phoneNumber { get; set; } = null!; [Column("password")] [MaxLength(1000)] diff --git a/DAL/Values/PhoneNumber.cs b/DAL/Values/PhoneNumber.cs new file mode 100644 index 0000000..22a8a85 --- /dev/null +++ b/DAL/Values/PhoneNumber.cs @@ -0,0 +1,71 @@ +using System.ComponentModel.DataAnnotations; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Text.RegularExpressions; + +namespace DAL.Values +{ + [JsonConverter(typeof(PhoneNumberJsonConverter))] + public partial class PhoneNumber + { + [MaxLength(32)] private string _phoneNumber = null!; + + [JsonIgnore] + [MaxLength(32)] + public string value + { + get => _phoneNumber; + set + { + if (phoneNumberConfirmation().IsMatch(value)) + { + _phoneNumber = phoneNumberConfirmation().Replace(value, "$1 ($2) $3-$4"); + _phoneNumber = _phoneNumber.Trim(); + } + else + { + throw new ValidationException("Phone number is invalid"); + } + } + } + + public static implicit operator string(PhoneNumber phoneNumber) + { + return phoneNumber.value; + } + public static implicit operator PhoneNumber(string str) + { + return new PhoneNumber { value = str }; + } + + // https://www.abstractapi.com/guides/phone-validation/c-validate-phone-number + [GeneratedRegex(@"^([+]?[0-9]{1,3})?[-. ]?\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$")] + public static partial Regex phoneNumberConfirmation(); + } + + public class PhoneNumberJsonConverter : JsonConverter + { + public override PhoneNumber? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + string? phoneNumber = reader.GetString(); + if (phoneNumber != null) + { + if (!PhoneNumber.phoneNumberConfirmation().IsMatch(phoneNumber)) + { + throw new JsonException("Phone number invalid. Match '^([+]?[0-9]{1,3})?[-. ]?\\(?([0-9]{3})\\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$'"); + } + + return new PhoneNumber + { + value = phoneNumber + }; + } + + throw new JsonException("Expected string for PhoneNumber deserialization."); + } + public override void Write(Utf8JsonWriter writer, PhoneNumber value, JsonSerializerOptions options) + { + writer.WriteStringValue(value); + } + } +}