Compare commits
52 Commits
Author | SHA1 | Date | |
---|---|---|---|
93ee75d021 | |||
0b88ebd2e8 | |||
cb5c5b6b4f | |||
777fb1c4c9 | |||
4fc88d90ce | |||
d48186d4d6 | |||
048ccd7c4c | |||
eac9c784fb | |||
e62f390942 | |||
787cdf5c6d | |||
f212f85d00 | |||
fe1213ed90 | |||
ea3799e9b0 | |||
374b8c64c9 | |||
63b95b7ee6 | |||
13f92d49cc | |||
a07f5f5869 | |||
d8b98ac5cc | |||
4afb3b0c54 | |||
588abd2712 | |||
d5a7ffc596 | |||
71cabbd548 | |||
7ae98f4bb4 | |||
58cf1cd74c | |||
0cdc5ebb20 | |||
18ab0b592f | |||
1dd4d3dca7 | |||
d58eb8d973 | |||
e2140d83f2 | |||
1086396ccd | |||
ca059ce75d | |||
8b6bcc7c37 | |||
a44fb7b278 | |||
6876b623ac | |||
2a99a5ba62 | |||
e5522ed559 | |||
d5642e4744 | |||
08efea943c | |||
cce57a4aec | |||
9fb3e52079 | |||
bce57e4cf0 | |||
890c521675 | |||
8c58bb2fa3 | |||
71eea092c7 | |||
03a72c365d | |||
27846f596e | |||
10cce72fbc | |||
99b3f65c97 | |||
f7b337e25a | |||
0b2c77d4cc | |||
37536443d3 | |||
46b57505ef |
12
.gitignore
vendored
12
.gitignore
vendored
@ -1,4 +1,8 @@
|
||||
/website/bin/
|
||||
/website/obj/
|
||||
/unitTests/bin/
|
||||
/unitTests/obj/
|
||||
/DAL/bin/
|
||||
/DAL/obj/
|
||||
/API/bin/
|
||||
/API/obj/
|
||||
/API/appsettings.*
|
||||
/Setup/bin/
|
||||
/Setup/obj/
|
||||
/Setup/appsettings.*
|
@ -6,6 +6,12 @@
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:mysql://192.168.1.52:5618</jdbc-url>
|
||||
<jdbc-additional-properties>
|
||||
<property name="com.intellij.clouds.kubernetes.db.host.port" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.resource.type" value="Deployment" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.container.port" />
|
||||
</jdbc-additional-properties>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
<driver-properties>
|
||||
<property name="serverTimezone" value="UTC" />
|
||||
@ -19,5 +25,18 @@
|
||||
<jdbc-url>jdbc:sqlite:$USER_HOME$/.local/share/scoreSphere/core.sqlite</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
<data-source source="LOCAL" name="SASG" uuid="65a22a18-3e0c-46e8-afbf-198b2bbb4f78">
|
||||
<driver-ref>mysql.8</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:mysql://localhost:5618</jdbc-url>
|
||||
<jdbc-additional-properties>
|
||||
<property name="com.intellij.clouds.kubernetes.db.host.port" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.resource.type" value="Deployment" />
|
||||
<property name="com.intellij.clouds.kubernetes.db.container.port" />
|
||||
</jdbc-additional-properties>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
@ -1,14 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PublishConfigData" serverName="boysserver" remoteFilesAllowedToDisappearOnAutoupload="false">
|
||||
<serverData>
|
||||
<paths name="boysserver">
|
||||
<serverdata>
|
||||
<mappings>
|
||||
<mapping deploy="/" local="$PROJECT_DIR$" web="/" />
|
||||
</mappings>
|
||||
</serverdata>
|
||||
</paths>
|
||||
</serverData>
|
||||
</component>
|
||||
<component name="PublishConfigData" serverName="temp" remoteFilesAllowedToDisappearOnAutoupload="false" />
|
||||
</project>
|
6
.idea/.idea.sanAntonioSeniorGolf/.idea/sqldialects.xml
generated
Normal file
6
.idea/.idea.sanAntonioSeniorGolf/.idea/sqldialects.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="SqlDialectMappings">
|
||||
<file url="file://$PROJECT_DIR$/Setup/Filler/Permissions.sql" dialect="MySQL" />
|
||||
</component>
|
||||
</project>
|
@ -2,6 +2,8 @@
|
||||
<project version="4">
|
||||
<component name="SshConfigs">
|
||||
<configs>
|
||||
<sshConfig host="4.72.148.132.host.secureserver.net" id="803b7675-648e-4d0f-8433-0abf8725c35f" keyPath="$USER_HOME$/.ssh/dotnetSanAntonioSeniorGolf" port="22" nameFormat="DESCRIPTIVE" username="dotnet" useOpenSSHConfig="false" />
|
||||
<sshConfig host="4.72.148.132.host.secureserver.net" id="7db7f912-3e0a-4cfc-90fe-563abe88fa2c" keyPath="$USER_HOME$/.ssh/sanantonioseniorgolf" port="22" nameFormat="DESCRIPTIVE" username="oaksana" useOpenSSHConfig="true" />
|
||||
<sshConfig host="192.168.1.52" id="e58264ea-75c0-4f9e-aa5c-b6ece113fffb" keyPath="$USER_HOME$/.ssh/dotnet" port="22" nameFormat="DESCRIPTIVE" username="dotnet" />
|
||||
</configs>
|
||||
</component>
|
||||
|
14
.idea/.idea.sanAntonioSeniorGolf/.idea/webServers.xml
generated
Normal file
14
.idea/.idea.sanAntonioSeniorGolf/.idea/webServers.xml
generated
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="WebServers">
|
||||
<option name="servers">
|
||||
<webServer id="a7501199-1083-42a2-9cb8-0a02a845371d" name="temp" url="http://signup.sanantonioseniorgolf.com/">
|
||||
<fileTransfer rootFolder="/home/dotnet/signupBackend.rewrite/API" accessType="SFTP" host="4.72.148.132.host.secureserver.net" port="22" sshConfigId="803b7675-648e-4d0f-8433-0abf8725c35f" sshConfig="dotnet@4.72.148.132.host.secureserver.net:22 key" keyPair="true">
|
||||
<advancedOptions>
|
||||
<advancedOptions dataProtectionLevel="Private" keepAliveTimeout="0" passiveMode="true" shareSSLContext="true" />
|
||||
</advancedOptions>
|
||||
</fileTransfer>
|
||||
</webServer>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
23
API/API.csproj
Normal file
23
API/API.csproj
Normal file
@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<InvariantGlobalization>true</InvariantGlobalization>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<NoWarn>1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.7"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.7"/>
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2-dev-00338"/>
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DAL\DAL.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
44
API/Authentication/ColorAuthentication.cs
Normal file
44
API/Authentication/ColorAuthentication.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using API.Authentication.GrantNames;
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using API.Services;
|
||||
using API.Services.Interfaces;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication
|
||||
{
|
||||
public class ColorAuthentication : IColorAuthentication
|
||||
{
|
||||
private readonly IGrantManager _grantManager;
|
||||
private readonly ILogger<ColorAuthentication> _logger;
|
||||
public ColorAuthentication(ILogger<ColorAuthentication> logger, IGrantManager grantManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_grantManager = grantManager;
|
||||
}
|
||||
|
||||
public bool canGetAll(User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, ColorGrantNames.CanGetAll);
|
||||
}
|
||||
public bool canGet(Color model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, ColorGrantNames.CanGetAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, ColorGrantNames.CanGet).Exists(x => x == model.id);
|
||||
}
|
||||
public bool canAdd(ColorDTO item, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, ColorGrantNames.CanAdd);
|
||||
}
|
||||
public bool canUpdate(Color model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, ColorGrantNames.CanUpdateAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, ColorGrantNames.CanUpdate).Exists(x => x == model.id);
|
||||
}
|
||||
public bool canDelete(Color model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, ColorGrantNames.CanDeleteAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, ColorGrantNames.CanDelete).Exists(x => x == model.id);
|
||||
}
|
||||
}
|
||||
}
|
50
API/Authentication/EventAuthentication.cs
Normal file
50
API/Authentication/EventAuthentication.cs
Normal file
@ -0,0 +1,50 @@
|
||||
using API.Authentication.GrantNames;
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using API.Services;
|
||||
using API.Services.Interfaces;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication
|
||||
{
|
||||
public class EventAuthentication : IEventAuthentication
|
||||
{
|
||||
private readonly IGrantManager _grantManager;
|
||||
private readonly ILogger<EventAuthentication> _logger;
|
||||
|
||||
public EventAuthentication(IGrantManager grantManager, ILogger<EventAuthentication> logger)
|
||||
{
|
||||
_grantManager = grantManager;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public bool canGetAll(User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, EventGrantNames.CanGetAll);
|
||||
}
|
||||
public bool canGet(Event model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, EventGrantNames.CanGetAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, EventGrantNames.CanGet).Exists(x => x == model.id);
|
||||
}
|
||||
public bool canAdd(EventDTO item, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, EventGrantNames.CanAdd);
|
||||
}
|
||||
public bool canUpdate(Event model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, EventGrantNames.CanUpdateAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, EventGrantNames.CanUpdate).Exists(x => x == model.id);
|
||||
}
|
||||
public bool canDelete(Event model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, EventGrantNames.CanDeleteAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, EventGrantNames.CanDelete).Exists(x => x == model.id);
|
||||
}
|
||||
public bool canCheckSelfSignup(User user)
|
||||
{
|
||||
//todo grants
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
51
API/Authentication/GrantAuthentication.cs
Normal file
51
API/Authentication/GrantAuthentication.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using API.Authentication.GrantNames;
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using API.Services;
|
||||
using API.Services.Interfaces;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication
|
||||
{
|
||||
public class GrantAuthentication : IGrantAuthentication
|
||||
{
|
||||
private readonly IGrantManager _grantManager;
|
||||
private readonly ILogger<GrantAuthentication> _logger;
|
||||
|
||||
public GrantAuthentication(IGrantManager grantManager, ILogger<GrantAuthentication> logger)
|
||||
{
|
||||
_grantManager = grantManager;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public bool canGetAll(User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, GrantGrantNames.CanGetAll);
|
||||
}
|
||||
public bool canGet(Grant model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, GrantGrantNames.CanGetAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, GrantGrantNames.CanGet).Exists(x => x == model.id);
|
||||
}
|
||||
public bool canAdd(GrantDTO item, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, GrantGrantNames.CanAdd) &&
|
||||
_grantManager.hasGrant(user.permissionId, item.name);
|
||||
}
|
||||
public bool canUpdate(Grant model, User user)
|
||||
{
|
||||
// Doesn't make sense to update the name of a grant. The updater can just delete and remake.
|
||||
return false;
|
||||
}
|
||||
public bool canDelete(Grant model, User user)
|
||||
{
|
||||
return (_grantManager.hasGrant(user.permissionId, GrantGrantNames.CanDeleteAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, GrantGrantNames.CanDelete).Exists(x => x == model.id))
|
||||
&& _grantManager.hasGrant(user.permissionId, model.name);
|
||||
}
|
||||
public bool canGetMine(User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, GrantGrantNames.CanGetSelf);
|
||||
}
|
||||
}
|
||||
}
|
14
API/Authentication/GrantNames/ColorGrantNames.cs
Normal file
14
API/Authentication/GrantNames/ColorGrantNames.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace API.Authentication.GrantNames
|
||||
{
|
||||
public static class ColorGrantNames
|
||||
{
|
||||
public const string CanGetAll = "api.color.get.all";
|
||||
public const string CanGetAny = "api.color.get.any";
|
||||
public const string CanGet = "api.color.get";
|
||||
public const string CanAdd = "api.color.add";
|
||||
public const string CanUpdateAny = "api.color.update.any";
|
||||
public const string CanUpdate = "api.color.update";
|
||||
public const string CanDeleteAny = "api.color.delete.any";
|
||||
public const string CanDelete = "api.color.delete";
|
||||
}
|
||||
}
|
14
API/Authentication/GrantNames/EventGrantNames.cs
Normal file
14
API/Authentication/GrantNames/EventGrantNames.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace API.Authentication.GrantNames
|
||||
{
|
||||
public static class EventGrantNames
|
||||
{
|
||||
public const string CanGetAll = "api.event.get.all";
|
||||
public const string CanGetAny = "api.event.get.any";
|
||||
public const string CanGet = "api.event.get";
|
||||
public const string CanAdd = "api.event.add";
|
||||
public const string CanUpdateAny = "api.event.update.any";
|
||||
public const string CanUpdate = "api.event.update";
|
||||
public const string CanDeleteAny = "api.event.delete.any";
|
||||
public const string CanDelete = "api.event.delete";
|
||||
}
|
||||
}
|
15
API/Authentication/GrantNames/GrantGrantNames.cs
Normal file
15
API/Authentication/GrantNames/GrantGrantNames.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace API.Authentication.GrantNames
|
||||
{
|
||||
public static class GrantGrantNames
|
||||
{
|
||||
public const string CanGetSelf = "api.grant.get.self";
|
||||
public const string CanGetAll = "api.grant.get.all";
|
||||
public const string CanGetAny = "api.grant.get.any";
|
||||
public const string CanGet = "api.grant.get";
|
||||
public const string CanAdd = "api.grant.add";
|
||||
public const string CanUpdateAny = "api.grant.update.any";
|
||||
public const string CanUpdate = "api.grant.update";
|
||||
public const string CanDeleteAny = "api.grant.delete.any";
|
||||
public const string CanDelete = "api.grant.delete";
|
||||
}
|
||||
}
|
14
API/Authentication/GrantNames/ImageGrantNames.cs
Normal file
14
API/Authentication/GrantNames/ImageGrantNames.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace API.Authentication.GrantNames
|
||||
{
|
||||
public static class ImageGrantNames
|
||||
{
|
||||
public const string CanGetAll = "api.image.get.all";
|
||||
public const string CanGetAny = "api.image.get.any";
|
||||
public const string CanGet = "api.image.get";
|
||||
public const string CanAdd = "api.image.add";
|
||||
public const string CanUpdateAny = "api.image.update.any";
|
||||
public const string CanUpdate = "api.image.update";
|
||||
public const string CanDeleteAny = "api.image.delete.any";
|
||||
public const string CanDelete = "api.image.delete";
|
||||
}
|
||||
}
|
14
API/Authentication/GrantNames/PermissionGrantNames.cs
Normal file
14
API/Authentication/GrantNames/PermissionGrantNames.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace API.Authentication.GrantNames
|
||||
{
|
||||
public static class PermissionGrantNames
|
||||
{
|
||||
public const string CanGetAll = "api.permission.get.all";
|
||||
public const string CanGetAny = "api.permission.get.any";
|
||||
public const string CanGet = "api.permission.get";
|
||||
public const string CanAdd = "api.permission.add";
|
||||
public const string CanUpdateAny = "api.permission.update.any";
|
||||
public const string CanUpdate = "api.permission.update";
|
||||
public const string CanDeleteAny = "api.permission.delete.any";
|
||||
public const string CanDelete = "api.permission.delete";
|
||||
}
|
||||
}
|
14
API/Authentication/GrantNames/SavedEventGrantNames.cs
Normal file
14
API/Authentication/GrantNames/SavedEventGrantNames.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace API.Authentication.GrantNames
|
||||
{
|
||||
public static class SavedEventGrantNames
|
||||
{
|
||||
public const string CanGetAll = "api.savedEvent.get.all";
|
||||
public const string CanGetAny = "api.savedEvent.get.any";
|
||||
public const string CanGet = "api.savedEvent.get";
|
||||
public const string CanAdd = "api.savedEvent.add";
|
||||
public const string CanUpdateAny = "api.savedEvent.update.any";
|
||||
public const string CanUpdate = "api.savedEvent.update";
|
||||
public const string CanDeleteAny = "api.savedEvent.delete.any";
|
||||
public const string CanDelete = "api.savedEvent.delete";
|
||||
}
|
||||
}
|
16
API/Authentication/GrantNames/SignupGrantNames.cs
Normal file
16
API/Authentication/GrantNames/SignupGrantNames.cs
Normal file
@ -0,0 +1,16 @@
|
||||
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";
|
||||
public const string CanDeleteSelf = "api.signup.delete.self";
|
||||
public const string CanAddOthers = "api.signup.add.others";
|
||||
}
|
||||
}
|
20
API/Authentication/GrantNames/UserGrantNames.cs
Normal file
20
API/Authentication/GrantNames/UserGrantNames.cs
Normal file
@ -0,0 +1,20 @@
|
||||
namespace API.Authentication.GrantNames
|
||||
{
|
||||
public static class UserGrantNames
|
||||
{
|
||||
public const string CanGetAll = "api.user.get.all";
|
||||
public const string CanGetAny = "api.user.get.any";
|
||||
public const string CanGet = "api.user.get";
|
||||
public const string CanAdd = "api.user.add";
|
||||
public const string CanUpdateAny = "api.user.update.any";
|
||||
public const string CanUpdate = "api.user.update";
|
||||
public const string CanUpdateSelf = "api.user.update.self";
|
||||
public const string CanUpdateNames = "api.user.update.names";
|
||||
public const string CanUpdatePhoneNumber = "api.user.update.phoneNumber";
|
||||
public const string CanUpdatePermission = "api.user.update.permission";
|
||||
public const string CanDeleteAny = "api.user.delete.any";
|
||||
public const string CanDelete = "api.user.delete";
|
||||
public const string CanChangePasswordSelf = "api.user.update.password.self";
|
||||
public const string CanChangePasswordOthers = "api.user.update.password.others";
|
||||
}
|
||||
}
|
44
API/Authentication/ImageAuthentication.cs
Normal file
44
API/Authentication/ImageAuthentication.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using API.Authentication.GrantNames;
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using API.Services;
|
||||
using API.Services.Interfaces;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication
|
||||
{
|
||||
public class ImageAuthentication : IImageAuthentication
|
||||
{
|
||||
private readonly IGrantManager _grantManager;
|
||||
private readonly ILogger<ImageAuthentication> _logger;
|
||||
public ImageAuthentication(ILogger<ImageAuthentication> logger, IGrantManager grantManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_grantManager = grantManager;
|
||||
}
|
||||
|
||||
public bool canGetAll(User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, ImageGrantNames.CanGetAll);
|
||||
}
|
||||
public bool canGet(Image model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, ImageGrantNames.CanGetAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, ImageGrantNames.CanGet).Exists(x => x == model.id);
|
||||
}
|
||||
public bool canAdd(ImageDTO item, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, ImageGrantNames.CanAdd);
|
||||
}
|
||||
public bool canUpdate(Image model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, ImageGrantNames.CanUpdateAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, ImageGrantNames.CanUpdate).Exists(x => x == model.id);
|
||||
}
|
||||
public bool canDelete(Image model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, ImageGrantNames.CanDeleteAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, ImageGrantNames.CanDelete).Exists(x => x == model.id);
|
||||
}
|
||||
}
|
||||
}
|
9
API/Authentication/Interfaces/IColorAuthentication.cs
Normal file
9
API/Authentication/Interfaces/IColorAuthentication.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using API.DTO.Base;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication.Interfaces
|
||||
{
|
||||
public interface IColorAuthentication : IGenericAuthentication<ColorDTO, Color>
|
||||
{
|
||||
}
|
||||
}
|
10
API/Authentication/Interfaces/IEventAuthentication.cs
Normal file
10
API/Authentication/Interfaces/IEventAuthentication.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using API.DTO.Base;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication.Interfaces
|
||||
{
|
||||
public interface IEventAuthentication : IGenericAuthentication<EventDTO, Event>
|
||||
{
|
||||
bool canCheckSelfSignup(User user);
|
||||
}
|
||||
}
|
13
API/Authentication/Interfaces/IGenericAuthentication.cs
Normal file
13
API/Authentication/Interfaces/IGenericAuthentication.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication.Interfaces
|
||||
{
|
||||
public interface IGenericAuthentication<in T, in TModel>
|
||||
{
|
||||
bool canGetAll(User user);
|
||||
bool canGet(TModel model, User user);
|
||||
bool canAdd(T item, User user);
|
||||
bool canUpdate(TModel model, User user);
|
||||
bool canDelete(TModel model, User user);
|
||||
}
|
||||
}
|
10
API/Authentication/Interfaces/IGrantAuthentication.cs
Normal file
10
API/Authentication/Interfaces/IGrantAuthentication.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using API.DTO.Base;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication.Interfaces
|
||||
{
|
||||
public interface IGrantAuthentication : IGenericAuthentication<GrantDTO, Grant>
|
||||
{
|
||||
bool canGetMine(User user);
|
||||
}
|
||||
}
|
9
API/Authentication/Interfaces/IImageAuthentication.cs
Normal file
9
API/Authentication/Interfaces/IImageAuthentication.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using API.DTO.Base;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication.Interfaces
|
||||
{
|
||||
public interface IImageAuthentication : IGenericAuthentication<ImageDTO, Image>
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
using API.DTO.Base;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication.Interfaces
|
||||
{
|
||||
public interface IPermissionAuthentication : IGenericAuthentication<PermissionDTO, Permission>
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
using API.DTO.Base;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication.Interfaces
|
||||
{
|
||||
public interface ISavedEventAuthentication : IGenericAuthentication<SavedEventDTO, SavedEvent>
|
||||
{
|
||||
}
|
||||
}
|
9
API/Authentication/Interfaces/ISignupAuthentication.cs
Normal file
9
API/Authentication/Interfaces/ISignupAuthentication.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using API.DTO.Base.Update;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication.Interfaces
|
||||
{
|
||||
public interface ISignupAuthentication : IGenericAuthentication<SignupDTO, Signup>
|
||||
{
|
||||
}
|
||||
}
|
10
API/Authentication/Interfaces/IUserAuthentication.cs
Normal file
10
API/Authentication/Interfaces/IUserAuthentication.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using API.DTO.Base;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication.Interfaces
|
||||
{
|
||||
public interface IUserAuthentication : IGenericAuthentication<UserDTO, User>
|
||||
{
|
||||
bool canChangePassword(User destUser, User changingUser, bool oldPasswordMatchNew);
|
||||
}
|
||||
}
|
45
API/Authentication/PermissionAuthentication.cs
Normal file
45
API/Authentication/PermissionAuthentication.cs
Normal file
@ -0,0 +1,45 @@
|
||||
using API.Authentication.GrantNames;
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using API.Services;
|
||||
using API.Services.Interfaces;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication
|
||||
{
|
||||
public class PermissionAuthentication : IPermissionAuthentication
|
||||
{
|
||||
private readonly IGrantManager _grantManager;
|
||||
private readonly ILogger<PermissionAuthentication> _logger;
|
||||
public PermissionAuthentication(ILogger<PermissionAuthentication> logger, IGrantManager grantManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_grantManager = grantManager;
|
||||
}
|
||||
|
||||
public bool canGetAll(User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, PermissionGrantNames.CanGetAll);
|
||||
}
|
||||
public bool canGet(Permission model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, PermissionGrantNames.CanGetAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, PermissionGrantNames.CanGet).Exists(x => x == model.id);
|
||||
}
|
||||
public bool canAdd(PermissionDTO item, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, PermissionGrantNames.CanAdd);
|
||||
}
|
||||
public bool canUpdate(Permission model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, PermissionGrantNames.CanUpdateAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, PermissionGrantNames.CanUpdate).Exists(x => x == model.id);
|
||||
}
|
||||
public bool canDelete(Permission model, User user)
|
||||
{
|
||||
return (_grantManager.hasGrant(user.permissionId, PermissionGrantNames.CanDeleteAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, PermissionGrantNames.CanDelete).Exists(x => x == model.id))
|
||||
&& model.id != user.permissionId;
|
||||
}
|
||||
}
|
||||
}
|
44
API/Authentication/SavedEventAuthentication.cs
Normal file
44
API/Authentication/SavedEventAuthentication.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using API.Authentication.GrantNames;
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using API.Services;
|
||||
using API.Services.Interfaces;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication
|
||||
{
|
||||
public class SavedEventAuthentication : ISavedEventAuthentication
|
||||
{
|
||||
private readonly IGrantManager _grantManager;
|
||||
private readonly ILogger<SavedEventAuthentication> _logger;
|
||||
public SavedEventAuthentication(ILogger<SavedEventAuthentication> logger, IGrantManager grantManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_grantManager = grantManager;
|
||||
}
|
||||
|
||||
public bool canGetAll(User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, SavedEventGrantNames.CanGetAll);
|
||||
}
|
||||
public bool canGet(SavedEvent model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, SavedEventGrantNames.CanGetAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, SavedEventGrantNames.CanGet).Exists(x => x == model.id);
|
||||
}
|
||||
public bool canAdd(SavedEventDTO item, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, SavedEventGrantNames.CanAdd);
|
||||
}
|
||||
public bool canUpdate(SavedEvent model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, SavedEventGrantNames.CanUpdateAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, SavedEventGrantNames.CanUpdate).Exists(x => x == model.id);
|
||||
}
|
||||
public bool canDelete(SavedEvent model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, SavedEventGrantNames.CanDeleteAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, SavedEventGrantNames.CanDelete).Exists(x => x == model.id);
|
||||
}
|
||||
}
|
||||
}
|
49
API/Authentication/SignupAuthentication.cs
Normal file
49
API/Authentication/SignupAuthentication.cs
Normal file
@ -0,0 +1,49 @@
|
||||
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)
|
||||
{
|
||||
if (item.userId == user.id)
|
||||
return _grantManager.hasGrant(user.permissionId, SignupGrantNames.CanAdd);
|
||||
return _grantManager.hasGrant(user.permissionId, SignupGrantNames.CanAddOthers);
|
||||
}
|
||||
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) ||
|
||||
(model.userId == user.id && _grantManager.hasGrant(user.permissionId, SignupGrantNames.CanDeleteSelf)) ||
|
||||
_grantManager.getULongValues(user.permissionId, SignupGrantNames.CanDelete).Exists(x => x == model.id);
|
||||
}
|
||||
}
|
||||
}
|
90
API/Authentication/UserAuthentication.cs
Normal file
90
API/Authentication/UserAuthentication.cs
Normal file
@ -0,0 +1,90 @@
|
||||
using API.Authentication.GrantNames;
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using API.Services;
|
||||
using API.Services.Interfaces;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Authentication
|
||||
{
|
||||
public class UserAuthentication : IUserAuthentication
|
||||
{
|
||||
private readonly IGrantManager _grantManager;
|
||||
private readonly ILogger<UserAuthentication> _logger;
|
||||
public UserAuthentication(ILogger<UserAuthentication> logger, IGrantManager grantManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_grantManager = grantManager;
|
||||
}
|
||||
|
||||
public bool canGetAll(User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, UserGrantNames.CanGetAll);
|
||||
}
|
||||
public bool canGet(User model, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, UserGrantNames.CanGetAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, UserGrantNames.CanGet).Exists(x => x == model.id);
|
||||
}
|
||||
public bool canAdd(UserDTO item, User user)
|
||||
{
|
||||
return _grantManager.hasGrant(user.permissionId, UserGrantNames.CanAdd);
|
||||
}
|
||||
|
||||
// todo this needs to be made much better
|
||||
public bool canUpdate(User model, User user)
|
||||
{
|
||||
User origUser = user;
|
||||
if (model.id == user.id)
|
||||
{
|
||||
if (!_grantManager.hasGrant(user.permissionId, UserGrantNames.CanUpdateSelf)
|
||||
|| !_grantManager.hasGrant(user.permissionId, UserGrantNames.CanUpdateAny)
|
||||
)
|
||||
return false;
|
||||
|
||||
// Don't let the user change their own permissionId
|
||||
if (model.permissionId != user.permissionId)
|
||||
return false;
|
||||
origUser = user;
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// origUser = _userService.getNoAuthentication(model.id) ?? throw new InvalidOperationException("Model is null.");
|
||||
// }
|
||||
|
||||
if (origUser.permissionId != model.permissionId)
|
||||
{
|
||||
if (!_grantManager.hasGrant(user.permissionId, UserGrantNames.CanUpdatePermission))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (origUser.firstName != user.firstName || origUser.lastName != user.lastName)
|
||||
{
|
||||
if (!_grantManager.hasGrant(user.permissionId, UserGrantNames.CanUpdateNames))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (origUser.phoneNumber != user.phoneNumber)
|
||||
{
|
||||
if (!_grantManager.hasGrant(user.permissionId, UserGrantNames.CanUpdatePhoneNumber))
|
||||
return false;
|
||||
}
|
||||
|
||||
return _grantManager.hasGrant(user.permissionId, UserGrantNames.CanUpdateAny)
|
||||
|| model.id == user.id &&
|
||||
_grantManager.hasGrant(user.permissionId, UserGrantNames.CanUpdateSelf)
|
||||
|| _grantManager.getULongValues(user.permissionId, UserGrantNames.CanUpdate).Exists(x => x == model.id);
|
||||
}
|
||||
public bool canDelete(User model, User user)
|
||||
{
|
||||
return (_grantManager.hasGrant(user.permissionId, UserGrantNames.CanDeleteAny) ||
|
||||
_grantManager.getULongValues(user.permissionId, UserGrantNames.CanDelete).Exists(x => x == model.id))
|
||||
&& model.id != user.id;
|
||||
}
|
||||
public bool canChangePassword(User destUser, User changingUser, bool oldPasswordMatchNew)
|
||||
{
|
||||
return (destUser.id == changingUser.id && _grantManager.hasGrant(changingUser.permissionId, UserGrantNames.CanChangePasswordSelf) && oldPasswordMatchNew) ||
|
||||
_grantManager.hasGrant(changingUser.permissionId, UserGrantNames.CanChangePasswordOthers);
|
||||
}
|
||||
}
|
||||
}
|
107
API/Controllers/AuthController.cs
Normal file
107
API/Controllers/AuthController.cs
Normal file
@ -0,0 +1,107 @@
|
||||
using API.DTO.Base;
|
||||
using API.DTO.Base.Update;
|
||||
using API.DTO.Login;
|
||||
using API.Errors;
|
||||
using API.Services;
|
||||
using API.Services.Interfaces;
|
||||
using DAL.Models;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace API.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v1/[controller]")]
|
||||
public class AuthController : ControllerBase
|
||||
{
|
||||
private readonly ILogger<AuthController> _logger;
|
||||
private readonly IUserManager _userManager;
|
||||
private readonly UserService _userService;
|
||||
|
||||
public AuthController(ILogger<AuthController> logger, IUserManager userManager, UserService userService)
|
||||
{
|
||||
_logger = logger;
|
||||
_userManager = userManager;
|
||||
_userService = userService;
|
||||
}
|
||||
|
||||
[HttpPost("login")]
|
||||
public ActionResult<UserDTO> login(UserLoginDTO userLogin)
|
||||
{
|
||||
UserDTO? user = _userManager.authenticateUser(userLogin);
|
||||
if (user == null)
|
||||
return new UnauthorizedResult();
|
||||
|
||||
Claim[] claims =
|
||||
{
|
||||
new Claim(ClaimTypes.NameIdentifier, user.id.ToString())
|
||||
};
|
||||
|
||||
ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
|
||||
//todo confirm if this is accurate
|
||||
AuthenticationProperties authProperties = new AuthenticationProperties();
|
||||
|
||||
HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);
|
||||
|
||||
return Ok(user);
|
||||
}
|
||||
|
||||
[HttpPost("register")]
|
||||
public ActionResult<UserDTO> register(UserRegisterDTO registerDTO, ulong? permissionId = null)
|
||||
{
|
||||
if (registerDTO.password == null)
|
||||
registerDTO.password = registerDTO.phoneNumber;
|
||||
|
||||
if (permissionId != null)
|
||||
{
|
||||
User? user = getUser(User);
|
||||
if (user == null)
|
||||
return Unauthorized();
|
||||
|
||||
UserDTO? createdUser = _userManager.registerUser(registerDTO, user, permissionId);
|
||||
if (createdUser == null)
|
||||
return Conflict(Strings.UserExists);
|
||||
|
||||
return Ok(createdUser);
|
||||
}
|
||||
else {
|
||||
UserDTO? user = _userManager.registerUser(registerDTO);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
return Conflict(Strings.UserExists);
|
||||
}
|
||||
|
||||
return Ok(user);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut("changePassword")]
|
||||
public ActionResult<UserDTO> changePassword(UserPasswordUpdateDTO passwordUpdateDTO)
|
||||
{
|
||||
User? user = getUser(User);
|
||||
if (user == null)
|
||||
return Unauthorized();
|
||||
|
||||
UserDTO? result = _userManager.changePassword(passwordUpdateDTO, user);
|
||||
if (result == null)
|
||||
return Forbid();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public User? getUser(ClaimsPrincipal user)
|
||||
{
|
||||
Claim? idClaim = user.FindFirst(ClaimTypes.NameIdentifier);
|
||||
|
||||
if (idClaim == null)
|
||||
return null;
|
||||
|
||||
return _userService.getNoAuthentication(UInt64.Parse(idClaim.Value));
|
||||
}
|
||||
}
|
||||
}
|
141
API/Controllers/CRUDBase.cs
Normal file
141
API/Controllers/CRUDBase.cs
Normal file
@ -0,0 +1,141 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO;
|
||||
using API.Services;
|
||||
using DAL.Models;
|
||||
using DAL.Models.Audits;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Security.Claims;
|
||||
using MUser = DAL.Models.User;
|
||||
|
||||
namespace API.Controllers
|
||||
{
|
||||
public class CRUDBase<TLoggerCategory, TDTO, TUpdateDTO, TModel, TAuditModel, TAuthentication, TService> : ControllerBase
|
||||
where TAuthentication : IGenericAuthentication<TDTO, TModel>
|
||||
where TModel : Model<TModel, TAuditModel>
|
||||
where TAuditModel : AuditModel<TModel>
|
||||
where TDTO : IAdaptable<TModel>, new()
|
||||
where TUpdateDTO : IUpdateAdaptable<TModel>
|
||||
where TService : ServiceBase<TService, TDTO, TModel, TAuditModel, TAuthentication>
|
||||
{
|
||||
public readonly ILogger<TLoggerCategory> Logger;
|
||||
public readonly TService Service;
|
||||
public readonly UserService UserService;
|
||||
|
||||
public CRUDBase(ILogger<TLoggerCategory> logger, UserService userService, TService service)
|
||||
{
|
||||
Logger = logger;
|
||||
UserService = userService;
|
||||
Service = service;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public virtual ActionResult<List<TDTO>> get()
|
||||
{
|
||||
MUser? user = getUser(User);
|
||||
if (user == null)
|
||||
return Unauthorized();
|
||||
|
||||
IEnumerable<TModel>? result = Service.get(user);
|
||||
if (result == null)
|
||||
return Forbid();
|
||||
|
||||
List<TDTO> dtos = [];
|
||||
|
||||
Parallel.ForEach(result, item =>
|
||||
{
|
||||
TDTO dto = new TDTO();
|
||||
dto.adaptFromModel(item);
|
||||
dtos.Add(dto);
|
||||
});
|
||||
|
||||
return Ok(dtos);
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
public virtual ActionResult<TDTO> get(ulong id)
|
||||
{
|
||||
MUser? user = getUser(User);
|
||||
if (user == null)
|
||||
return Unauthorized();
|
||||
|
||||
TModel? result = Service.get(id, user);
|
||||
if (result == null)
|
||||
return Forbid();
|
||||
|
||||
TDTO dto = new TDTO();
|
||||
dto.adaptFromModel(result);
|
||||
|
||||
return Ok(dto);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public virtual ActionResult<TDTO> add(TDTO createDTO)
|
||||
{
|
||||
MUser? user = getUser(User);
|
||||
if (user == null)
|
||||
return Unauthorized();
|
||||
|
||||
TModel? result = Service.add(createDTO, user);
|
||||
if (result == null)
|
||||
return Forbid();
|
||||
|
||||
TDTO dto = new TDTO();
|
||||
dto.adaptFromModel(result);
|
||||
|
||||
return Ok(dto);
|
||||
}
|
||||
|
||||
[HttpPut("{id}")]
|
||||
public virtual ActionResult<TDTO> update(ulong id, TUpdateDTO updateDTO)
|
||||
{
|
||||
MUser? user = getUser(User);
|
||||
if (user == null)
|
||||
return Unauthorized();
|
||||
|
||||
TModel? result = Service.get(id, user);
|
||||
if (result == null)
|
||||
return Forbid();
|
||||
|
||||
updateDTO.adaptModel(ref result);
|
||||
|
||||
TModel? newResult = Service.update(result, user);
|
||||
if (newResult == null)
|
||||
return Forbid();
|
||||
|
||||
TDTO dto = new TDTO();
|
||||
dto.adaptFromModel(newResult);
|
||||
|
||||
return Ok(dto);
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
public virtual ActionResult delete(ulong id)
|
||||
{
|
||||
MUser? user = getUser(User);
|
||||
if (user == null)
|
||||
return Unauthorized();
|
||||
|
||||
TModel? result = Service.get(id, user);
|
||||
if (result == null)
|
||||
return Forbid();
|
||||
|
||||
TAuditModel? auditModel = Service.delete(result, user);
|
||||
if (auditModel == null)
|
||||
return Forbid();
|
||||
|
||||
// todo in the future we should return the audit
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public MUser? getUser(ClaimsPrincipal user)
|
||||
{
|
||||
Claim? idClaim = user.FindFirst(ClaimTypes.NameIdentifier);
|
||||
|
||||
if (idClaim == null)
|
||||
return null;
|
||||
|
||||
return UserService.getNoAuthentication(UInt64.Parse(idClaim.Value));
|
||||
}
|
||||
}
|
||||
}
|
19
API/Controllers/ColorController.cs
Normal file
19
API/Controllers/ColorController.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using API.DTO.Base.Update;
|
||||
using API.Services;
|
||||
using DAL.Models;
|
||||
using DAL.Models.Audits;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace API.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v1/[controller]")]
|
||||
public class ColorController : CRUDBase<ColorController, ColorDTO, ColorUpdateDTO, Color, AuditColor, IColorAuthentication, ColorService>
|
||||
{
|
||||
public ColorController(ILogger<ColorController> logger, UserService userService, ColorService service) : base(logger, userService, service)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
60
API/Controllers/EventController.cs
Normal file
60
API/Controllers/EventController.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
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 EventController : CRUDBase<EventController, EventDTO, EventUpdateDTO, Event, AuditEvent, IEventAuthentication, EventService>
|
||||
{
|
||||
public EventController(ILogger<EventController> logger, UserService userService, EventService service) : base(logger, userService, service)
|
||||
{
|
||||
}
|
||||
|
||||
//todo slow
|
||||
[HttpGet("period")]
|
||||
public virtual ActionResult<List<EventDTO>> getPeriod(DateTime start, DateTime end)
|
||||
{
|
||||
MUser? user = getUser(User);
|
||||
if (user == null)
|
||||
return Unauthorized();
|
||||
|
||||
IEnumerable<Event>? result = Service.get(user, x => x.when >= start && x.when <= end && x.hidden == false);
|
||||
if (result == null)
|
||||
return Forbid();
|
||||
|
||||
List<EventDTO> dtos = [];
|
||||
|
||||
List<Event> temp = result.ToList();
|
||||
|
||||
Parallel.ForEach(temp, item =>
|
||||
{
|
||||
EventDTO dto = new EventDTO();
|
||||
dto.adaptFromModel(item);
|
||||
dtos.Add(dto);
|
||||
});
|
||||
|
||||
return Ok(dtos);
|
||||
}
|
||||
|
||||
[HttpGet("{eventId}/isSignedUp")]
|
||||
public ActionResult<bool> isSignedUp(ulong eventId)
|
||||
{
|
||||
MUser? user = getUser(User);
|
||||
if (user == null)
|
||||
return Unauthorized();
|
||||
|
||||
bool? isSignedUp = Service.isSignedUp(user, eventId);
|
||||
if (isSignedUp == null)
|
||||
return Forbid();
|
||||
|
||||
return isSignedUp;
|
||||
}
|
||||
}
|
||||
}
|
43
API/Controllers/GrantController.cs
Normal file
43
API/Controllers/GrantController.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
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 GrantController : CRUDBase<GrantController, GrantDTO, GrantUpdateDTO, Grant, AuditGrant, IGrantAuthentication, GrantService>
|
||||
{
|
||||
public GrantController(ILogger<GrantController> logger, UserService userService, GrantService service) : base(logger, userService, service)
|
||||
{
|
||||
}
|
||||
|
||||
[HttpGet("mine")]
|
||||
public ActionResult<List<GrantDTO>> getMine()
|
||||
{
|
||||
MUser? user = getUser(User);
|
||||
if (user == null)
|
||||
return Unauthorized();
|
||||
|
||||
IEnumerable<Grant>? result = Service.getMine(user);
|
||||
if (result == null)
|
||||
return Forbid();
|
||||
|
||||
List<GrantDTO> dtos = [];
|
||||
|
||||
Parallel.ForEach(result, item =>
|
||||
{
|
||||
GrantDTO dto = new GrantDTO();
|
||||
dto.adaptFromModel(item);
|
||||
dtos.Add(dto);
|
||||
});
|
||||
|
||||
return Ok(dtos);
|
||||
}
|
||||
}
|
||||
}
|
19
API/Controllers/ImageController.cs
Normal file
19
API/Controllers/ImageController.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using API.DTO.Base.Update;
|
||||
using API.Services;
|
||||
using DAL.Models;
|
||||
using DAL.Models.Audits;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace API.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v1/[controller]")]
|
||||
public class ImageController : CRUDBase<ImageController, ImageDTO, ImageUpdateDTO, Image, AuditImage, IImageAuthentication, ImageService>
|
||||
{
|
||||
public ImageController(ILogger<ImageController> logger, UserService userService, ImageService service) : base(logger, userService, service)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
19
API/Controllers/PermissionController.cs
Normal file
19
API/Controllers/PermissionController.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using API.DTO.Base.Update;
|
||||
using API.Services;
|
||||
using DAL.Models;
|
||||
using DAL.Models.Audits;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace API.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v1/[controller]")]
|
||||
public class PermissionController : CRUDBase<PermissionController, PermissionDTO, PermissionUpdateDTO, Permission, AuditPermission, IPermissionAuthentication, PermissionService>
|
||||
{
|
||||
public PermissionController(ILogger<PermissionController> logger, UserService userService, PermissionService service) : base(logger, userService, service)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
19
API/Controllers/SavedEventController.cs
Normal file
19
API/Controllers/SavedEventController.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using API.DTO.Base.Update;
|
||||
using API.Services;
|
||||
using DAL.Models;
|
||||
using DAL.Models.Audits;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace API.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v1/[controller]")]
|
||||
public class SavedEventController : CRUDBase<SavedEventController, SavedEventDTO, SavedEventUpdateDTO, SavedEvent, AuditSavedEvent, ISavedEventAuthentication, SavedEventService>
|
||||
{
|
||||
public SavedEventController(ILogger<SavedEventController> logger, UserService userService, SavedEventService service) : base(logger, userService, service)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
84
API/Controllers/SignupController.cs
Normal file
84
API/Controllers/SignupController.cs
Normal file
@ -0,0 +1,84 @@
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
[HttpGet("forEvent/{eventId}")]
|
||||
public ActionResult<SignupDTO> getForEvent(ulong eventId)
|
||||
{
|
||||
MUser? user = getUser(User);
|
||||
if (user == null)
|
||||
return Unauthorized();
|
||||
|
||||
IEnumerable<Signup>? result = Service.get(user, e => e.eventId == eventId);
|
||||
if (result == null)
|
||||
return Forbid();
|
||||
|
||||
List<SignupDTO> dtos = [];
|
||||
|
||||
Parallel.ForEach(result, item =>
|
||||
{
|
||||
SignupDTO dto = new SignupDTO();
|
||||
dto.adaptFromModel(item);
|
||||
dtos.Add(dto);
|
||||
});
|
||||
|
||||
return Ok(dtos);
|
||||
}
|
||||
|
||||
[HttpPost("autoUser")]
|
||||
public 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 ActionResult deleteForEvent(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();
|
||||
}
|
||||
}
|
||||
}
|
19
API/Controllers/UserController.cs
Normal file
19
API/Controllers/UserController.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using API.DTO.Base.Update;
|
||||
using API.Services;
|
||||
using DAL.Models;
|
||||
using DAL.Models.Audits;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace API.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v1/[controller]")]
|
||||
public class UserController : CRUDBase<UserController, UserDTO, UserUpdateDTO, User, AuditUser, IUserAuthentication, UserService>
|
||||
{
|
||||
public UserController(ILogger<UserController> logger, UserService userService, UserService service) : base(logger, userService, service)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
42
API/DTO/Base/ColorDTO.cs
Normal file
42
API/DTO/Base/ColorDTO.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using DAL.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Base
|
||||
{
|
||||
public class ColorDTO : IAdaptable<Color>
|
||||
{
|
||||
public ulong id { get; set; }
|
||||
public byte red { get; set; }
|
||||
public byte blue { get; set; }
|
||||
public byte green { get; set; }
|
||||
|
||||
[MaxLength(64)]
|
||||
public string name { get; set; } = null!;
|
||||
|
||||
public DateTime updated { get; set; }
|
||||
public ulong updater { get; set; }
|
||||
public Color adaptToModel()
|
||||
{
|
||||
return new Color
|
||||
{
|
||||
id = id,
|
||||
red = red,
|
||||
blue = blue,
|
||||
green = green,
|
||||
name = name,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
public void adaptFromModel(in Color model)
|
||||
{
|
||||
id = model.id;
|
||||
red = model.red;
|
||||
blue = model.blue;
|
||||
green = model.green;
|
||||
name = model.name;
|
||||
updated = model.updated;
|
||||
updater = model.updater;
|
||||
}
|
||||
}
|
||||
}
|
52
API/DTO/Base/EventDTO.cs
Normal file
52
API/DTO/Base/EventDTO.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using DAL.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Base
|
||||
{
|
||||
public class EventDTO : IAdaptable<Event>
|
||||
{
|
||||
public ulong id { get; set; }
|
||||
public ulong savedEventId { get; set; }
|
||||
|
||||
[MaxLength(64)]
|
||||
public string? name { get; set; }
|
||||
|
||||
public ulong? bgColorId { get; set; }
|
||||
public ulong? fgColorId { get; set; }
|
||||
public ulong? imageId { get; set; }
|
||||
public DateTime when { get; set; }
|
||||
public bool hidden { get; set; }
|
||||
public DateTime updated { get; set; }
|
||||
public ulong updater { get; set; }
|
||||
|
||||
public Event adaptToModel()
|
||||
{
|
||||
return new Event
|
||||
{
|
||||
id = id,
|
||||
savedEventId = savedEventId,
|
||||
name = name,
|
||||
bgColorId = bgColorId,
|
||||
fgColorId = fgColorId,
|
||||
imageId = imageId,
|
||||
when = when,
|
||||
hidden = hidden,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
public void adaptFromModel(in Event model)
|
||||
{
|
||||
id = model.id;
|
||||
savedEventId = model.savedEventId;
|
||||
name = model.name;
|
||||
bgColorId = model.bgColorId;
|
||||
fgColorId = model.fgColorId;
|
||||
imageId = model.imageId;
|
||||
when = model.when;
|
||||
hidden = model.hidden;
|
||||
updated = model.updated;
|
||||
updater = model.updater;
|
||||
}
|
||||
}
|
||||
}
|
39
API/DTO/Base/GrantDTO.cs
Normal file
39
API/DTO/Base/GrantDTO.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using DAL.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Base
|
||||
{
|
||||
public class GrantDTO : IAdaptable<Grant>
|
||||
{
|
||||
public ulong id { get; set; }
|
||||
|
||||
[MaxLength(128)]
|
||||
public string name { get; set; } = null!;
|
||||
|
||||
public ulong permissionId { get; set; }
|
||||
|
||||
public DateTime updated { get; set; }
|
||||
|
||||
public ulong updater { get; set; }
|
||||
|
||||
public Grant adaptToModel()
|
||||
{
|
||||
return new Grant
|
||||
{
|
||||
id = id,
|
||||
name = name,
|
||||
permissionId = permissionId,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
public void adaptFromModel(in Grant model)
|
||||
{
|
||||
id = model.id;
|
||||
name = model.name;
|
||||
permissionId = model.permissionId;
|
||||
updated = model.updated;
|
||||
updater = model.updater;
|
||||
}
|
||||
}
|
||||
}
|
40
API/DTO/Base/ImageDTO.cs
Normal file
40
API/DTO/Base/ImageDTO.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using DAL.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Base
|
||||
{
|
||||
public class ImageDTO : IAdaptable<Image>
|
||||
{
|
||||
public ulong id { get; set; }
|
||||
|
||||
[MaxLength(64)]
|
||||
public string name { get; set; } = null!;
|
||||
|
||||
[MaxLength(128)]
|
||||
public string filename { get; set; } = null!;
|
||||
|
||||
public DateTime updated { get; set; }
|
||||
|
||||
public ulong updater { get; set; }
|
||||
|
||||
public Image adaptToModel()
|
||||
{
|
||||
return new Image
|
||||
{
|
||||
id = id,
|
||||
name = name,
|
||||
filename = filename,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
public void adaptFromModel(in Image model)
|
||||
{
|
||||
id = model.id;
|
||||
name = model.name;
|
||||
filename = model.filename;
|
||||
updated = model.updated;
|
||||
updater = model.updater;
|
||||
}
|
||||
}
|
||||
}
|
35
API/DTO/Base/PermissionDTO.cs
Normal file
35
API/DTO/Base/PermissionDTO.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using DAL.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Base
|
||||
{
|
||||
public class PermissionDTO : IAdaptable<Permission>
|
||||
{
|
||||
public ulong id { get; set; }
|
||||
|
||||
[MaxLength(64)]
|
||||
public string name { get; set; } = null!;
|
||||
|
||||
public DateTime updated { get; set; }
|
||||
|
||||
public ulong updater { get; set; }
|
||||
|
||||
public Permission adaptToModel()
|
||||
{
|
||||
return new Permission
|
||||
{
|
||||
id = id,
|
||||
name = name,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
public void adaptFromModel(in Permission model)
|
||||
{
|
||||
id = model.id;
|
||||
name = model.name;
|
||||
updated = model.updated;
|
||||
updater = model.updater;
|
||||
}
|
||||
}
|
||||
}
|
47
API/DTO/Base/SavedEventDTO.cs
Normal file
47
API/DTO/Base/SavedEventDTO.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using DAL.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Base
|
||||
{
|
||||
public class SavedEventDTO : IAdaptable<SavedEvent>
|
||||
{
|
||||
public ulong id { get; set; }
|
||||
|
||||
[MaxLength(64)]
|
||||
public string name { get; set; } = null!;
|
||||
|
||||
public ulong bgColorId { get; set; }
|
||||
|
||||
public ulong fgColorId { get; set; }
|
||||
|
||||
public ulong? imageId { get; set; }
|
||||
|
||||
public DateTime updated { get; set; }
|
||||
|
||||
public ulong updater { get; set; }
|
||||
|
||||
public SavedEvent adaptToModel()
|
||||
{
|
||||
return new SavedEvent
|
||||
{
|
||||
id = id,
|
||||
name = name,
|
||||
bgColorId = bgColorId,
|
||||
fgColorId = fgColorId,
|
||||
imageId = imageId,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
public void adaptFromModel(in SavedEvent model)
|
||||
{
|
||||
id = model.id;
|
||||
name = model.name;
|
||||
bgColorId = model.bgColorId;
|
||||
fgColorId = model.fgColorId;
|
||||
imageId = model.imageId;
|
||||
updated = model.updated;
|
||||
updater = model.updater;
|
||||
}
|
||||
}
|
||||
}
|
33
API/DTO/Base/SignupDTO.cs
Normal file
33
API/DTO/Base/SignupDTO.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
23
API/DTO/Base/Update/ColorUpdateDTO.cs
Normal file
23
API/DTO/Base/Update/ColorUpdateDTO.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using DAL.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Base.Update
|
||||
{
|
||||
public class ColorUpdateDTO : IUpdateAdaptable<Color>
|
||||
{
|
||||
public byte? red { get; set; }
|
||||
public byte? blue { get; set; }
|
||||
public byte? green { get; set; }
|
||||
|
||||
[MaxLength(64)]
|
||||
public string? name { get; set; }
|
||||
|
||||
public void adaptModel(ref Color model)
|
||||
{
|
||||
if (red != null) model.red = (byte)red;
|
||||
if (blue != null) model.blue = (byte)blue;
|
||||
if (green != null) model.green = (byte)green;
|
||||
if (name != null) model.name = name;
|
||||
}
|
||||
}
|
||||
}
|
29
API/DTO/Base/Update/EventUpdateDTO.cs
Normal file
29
API/DTO/Base/Update/EventUpdateDTO.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.DTO.Base.Update
|
||||
{
|
||||
public class EventUpdateDTO : IUpdateAdaptable<Event>
|
||||
{
|
||||
public ulong? savedEventId { get; set; }
|
||||
|
||||
// [MaxLength(64)]
|
||||
public UnSettable<string?>? name { get; set; }
|
||||
|
||||
public UnSettable<ulong?>? bgColorId { get; set; }
|
||||
public UnSettable<ulong?>? fgColorId { get; set; }
|
||||
public UnSettable<ulong?>? imageId { get; set; }
|
||||
public DateTime? when { get; set; }
|
||||
public bool? hidden { get; set; }
|
||||
|
||||
public void adaptModel(ref Event model)
|
||||
{
|
||||
if (savedEventId != null) model.savedEventId = (ulong)savedEventId;
|
||||
if (name != null) model.name = name.Value.value;
|
||||
if (bgColorId != null) model.bgColorId = bgColorId.Value.value;
|
||||
if (fgColorId != null) model.fgColorId = fgColorId.Value.value;
|
||||
if (imageId != null) model.imageId = imageId.Value.value;
|
||||
if (when != null) model.when = (DateTime)when;
|
||||
if (hidden != null) model.hidden = (bool)hidden;
|
||||
}
|
||||
}
|
||||
}
|
19
API/DTO/Base/Update/GrantUpdateDTO.cs
Normal file
19
API/DTO/Base/Update/GrantUpdateDTO.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using DAL.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Base.Update
|
||||
{
|
||||
public class GrantUpdateDTO : IUpdateAdaptable<Grant>
|
||||
{
|
||||
[MaxLength(128)]
|
||||
public string? name { get; set; }
|
||||
|
||||
public ulong? permissionId { get; set; }
|
||||
|
||||
public void adaptModel(ref Grant model)
|
||||
{
|
||||
if (name != null) model.name = name;
|
||||
if (permissionId != null) model.permissionId = (ulong)permissionId;
|
||||
}
|
||||
}
|
||||
}
|
20
API/DTO/Base/Update/ImageUpdateDTO.cs
Normal file
20
API/DTO/Base/Update/ImageUpdateDTO.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using DAL.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Base.Update
|
||||
{
|
||||
public class ImageUpdateDTO : IUpdateAdaptable<Image>
|
||||
{
|
||||
[MaxLength(64)]
|
||||
public string? name { get; set; }
|
||||
|
||||
[MaxLength(128)]
|
||||
public string? filename { get; set; }
|
||||
|
||||
public void adaptModel(ref Image model)
|
||||
{
|
||||
if (name != null) model.name = name;
|
||||
if (filename != null) model.filename = filename;
|
||||
}
|
||||
}
|
||||
}
|
16
API/DTO/Base/Update/PermissionUpdateDTO.cs
Normal file
16
API/DTO/Base/Update/PermissionUpdateDTO.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using DAL.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Base.Update
|
||||
{
|
||||
public class PermissionUpdateDTO : IUpdateAdaptable<Permission>
|
||||
{
|
||||
[MaxLength(64)]
|
||||
public string? name { get; set; }
|
||||
|
||||
public void adaptModel(ref Permission model)
|
||||
{
|
||||
if (name != null) model.name = name;
|
||||
}
|
||||
}
|
||||
}
|
25
API/DTO/Base/Update/SavedEventUpdateDTO.cs
Normal file
25
API/DTO/Base/Update/SavedEventUpdateDTO.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using DAL.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Base.Update
|
||||
{
|
||||
public class SavedEventUpdateDTO : IUpdateAdaptable<SavedEvent>
|
||||
{
|
||||
[MaxLength(64)]
|
||||
public string? name { get; set; }
|
||||
|
||||
public ulong? bgColorId { get; set; }
|
||||
|
||||
public ulong? fgColorId { get; set; }
|
||||
|
||||
public UnSettable<ulong?>? imageId { get; set; }
|
||||
|
||||
public void adaptModel(ref SavedEvent model)
|
||||
{
|
||||
if (name != null) model.name = name;
|
||||
if (bgColorId != null) model.bgColorId = (ulong)bgColorId;
|
||||
if (fgColorId != null) model.fgColorId = (ulong)fgColorId;
|
||||
if (imageId != null) model.imageId = imageId.Value.value;
|
||||
}
|
||||
}
|
||||
}
|
16
API/DTO/Base/Update/SignupUpdateDTO.cs
Normal file
16
API/DTO/Base/Update/SignupUpdateDTO.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
16
API/DTO/Base/Update/UserPasswordUpdateDTO.cs
Normal file
16
API/DTO/Base/Update/UserPasswordUpdateDTO.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using DAL.Values;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Base.Update
|
||||
{
|
||||
public class UserPasswordUpdateDTO
|
||||
{
|
||||
public PhoneNumber phoneNumber { get; set; } = null!;
|
||||
|
||||
[MaxLength(100)]
|
||||
public string? oldPassword { get; set; }
|
||||
|
||||
[MaxLength(100)]
|
||||
public string newPassword { get; set; } = null!;
|
||||
}
|
||||
}
|
27
API/DTO/Base/Update/UserUpdateDTO.cs
Normal file
27
API/DTO/Base/Update/UserUpdateDTO.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using DAL.Models;
|
||||
using DAL.Values;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Base.Update
|
||||
{
|
||||
public class UserUpdateDTO : IUpdateAdaptable<User>
|
||||
{
|
||||
[MaxLength(64)]
|
||||
public string? firstName { get; set; }
|
||||
|
||||
[MaxLength(64)]
|
||||
public string? lastName { get; set; }
|
||||
|
||||
public PhoneNumber? phoneNumber { get; set; }
|
||||
|
||||
public ulong? permissionId { get; set; }
|
||||
|
||||
public void adaptModel(ref User model)
|
||||
{
|
||||
if (firstName != null) model.firstName = firstName;
|
||||
if (lastName != null) model.lastName = lastName;
|
||||
if (phoneNumber != null) model.phoneNumber = phoneNumber;
|
||||
if (permissionId != null) model.permissionId = (ulong)permissionId;
|
||||
}
|
||||
}
|
||||
}
|
49
API/DTO/Base/UserDTO.cs
Normal file
49
API/DTO/Base/UserDTO.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using DAL.Models;
|
||||
using DAL.Values;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Base
|
||||
{
|
||||
public class UserDTO : IAdaptable<User>
|
||||
{
|
||||
public ulong id { get; set; }
|
||||
|
||||
[MaxLength(64)]
|
||||
public string firstName { get; set; } = null!;
|
||||
|
||||
[MaxLength(64)]
|
||||
public string lastName { get; set; } = null!;
|
||||
|
||||
public PhoneNumber phoneNumber { get; set; } = null!;
|
||||
|
||||
public ulong permissionId { get; set; }
|
||||
|
||||
public DateTime updated { get; set; }
|
||||
|
||||
public ulong? updater { get; set; }
|
||||
|
||||
public User adaptToModel()
|
||||
{
|
||||
return new User
|
||||
{
|
||||
id = id,
|
||||
firstName = firstName,
|
||||
lastName = lastName,
|
||||
phoneNumber = phoneNumber,
|
||||
permissionId = permissionId,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
public void adaptFromModel(in User model)
|
||||
{
|
||||
id = model.id;
|
||||
firstName = model.firstName;
|
||||
lastName = model.lastName;
|
||||
phoneNumber = model.phoneNumber;
|
||||
permissionId = model.permissionId;
|
||||
updated = model.updated;
|
||||
updater = model.updater;
|
||||
}
|
||||
}
|
||||
}
|
8
API/DTO/IAdaptable.cs
Normal file
8
API/DTO/IAdaptable.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace API.DTO
|
||||
{
|
||||
public interface IAdaptable<TModel>
|
||||
{
|
||||
TModel adaptToModel();
|
||||
void adaptFromModel(in TModel model);
|
||||
}
|
||||
}
|
7
API/DTO/IUpdateAdaptable.cs
Normal file
7
API/DTO/IUpdateAdaptable.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace API.DTO
|
||||
{
|
||||
public interface IUpdateAdaptable<TModel>
|
||||
{
|
||||
void adaptModel(ref TModel model);
|
||||
}
|
||||
}
|
13
API/DTO/Login/UserLoginDTO.cs
Normal file
13
API/DTO/Login/UserLoginDTO.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using DAL.Values;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Login
|
||||
{
|
||||
public class UserLoginDTO
|
||||
{
|
||||
public PhoneNumber phoneNumber { get; set; } = null!;
|
||||
|
||||
[MaxLength(100)]
|
||||
public string password { get; set; } = null!;
|
||||
}
|
||||
}
|
19
API/DTO/Login/UserRegisterDTO.cs
Normal file
19
API/DTO/Login/UserRegisterDTO.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using DAL.Values;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace API.DTO.Login
|
||||
{
|
||||
public class UserRegisterDTO
|
||||
{
|
||||
[MaxLength(64)]
|
||||
public string firstName { get; set; } = null!;
|
||||
|
||||
[MaxLength(64)]
|
||||
public string lastName { get; set; } = null!;
|
||||
|
||||
public PhoneNumber phoneNumber { get; set; } = null!;
|
||||
|
||||
[MaxLength(1000)]
|
||||
public string? password { get; set; }
|
||||
}
|
||||
}
|
7
API/DTO/UnSettable.cs
Normal file
7
API/DTO/UnSettable.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace API.DTO
|
||||
{
|
||||
public struct UnSettable<T>
|
||||
{
|
||||
public T value { get; set; }
|
||||
}
|
||||
}
|
7
API/Errors/Strings.cs
Normal file
7
API/Errors/Strings.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace API.Errors
|
||||
{
|
||||
public static class Strings
|
||||
{
|
||||
public const string UserExists = "User with that phone number or first and last name already exists.\nIf you would like to change your phone number please login.";
|
||||
}
|
||||
}
|
19
API/Hashing/HashingFactory.cs
Normal file
19
API/Hashing/HashingFactory.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using API.Hashing.Interfaces;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Hashing
|
||||
{
|
||||
public class HashingFactory : IHashingFactory
|
||||
{
|
||||
public IHashingAlgorithm? getAlgorithm(HashingType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case HashingType.PBKDF2_SHA512_64_250000:
|
||||
return new Pbkdf2();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
API/Hashing/Interfaces/IHashingAlgorithm.cs
Normal file
9
API/Hashing/Interfaces/IHashingAlgorithm.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace API.Hashing.Interfaces
|
||||
{
|
||||
public interface IHashingAlgorithm
|
||||
{
|
||||
public string hash(string password, out byte[] salt);
|
||||
|
||||
public string hash(string password, byte[] salt);
|
||||
}
|
||||
}
|
9
API/Hashing/Interfaces/IHashingFactory.cs
Normal file
9
API/Hashing/Interfaces/IHashingFactory.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Hashing.Interfaces
|
||||
{
|
||||
public interface IHashingFactory
|
||||
{
|
||||
public IHashingAlgorithm? getAlgorithm(HashingType type);
|
||||
}
|
||||
}
|
28
API/Hashing/Pbkdf2.cs
Normal file
28
API/Hashing/Pbkdf2.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using API.Hashing.Interfaces;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace API.Hashing
|
||||
{
|
||||
public class Pbkdf2 : IHashingAlgorithm
|
||||
{
|
||||
private const int KeySize = 512;
|
||||
private const int Iterations = 250000;
|
||||
private readonly HashAlgorithmName _algorithmName = HashAlgorithmName.SHA512;
|
||||
|
||||
public string hash(string password, out byte[] salt)
|
||||
{
|
||||
salt = RandomNumberGenerator.GetBytes(KeySize);
|
||||
|
||||
byte[] hash = Rfc2898DeriveBytes.Pbkdf2(Encoding.UTF8.GetBytes(password), salt, Iterations, _algorithmName, KeySize);
|
||||
|
||||
return Convert.ToHexString(hash);
|
||||
}
|
||||
public string hash(string password, byte[] salt)
|
||||
{
|
||||
byte[] hash = Rfc2898DeriveBytes.Pbkdf2(Encoding.UTF8.GetBytes(password), salt, Iterations, _algorithmName, KeySize);
|
||||
|
||||
return Convert.ToHexString(hash);
|
||||
}
|
||||
}
|
||||
}
|
141
API/Program.cs
Normal file
141
API/Program.cs
Normal file
@ -0,0 +1,141 @@
|
||||
using API.Authentication;
|
||||
using API.Authentication.Interfaces;
|
||||
using API.Hashing;
|
||||
using API.Hashing.Interfaces;
|
||||
using API.Services;
|
||||
using API.Services.Interfaces;
|
||||
using DAL.Contexts;
|
||||
using DAL.Models;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Serilog;
|
||||
using System.Reflection;
|
||||
using ConfigurationManager = Microsoft.Extensions.Configuration.ConfigurationManager;
|
||||
using InvalidOperationException = System.InvalidOperationException;
|
||||
|
||||
namespace API
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
public static IServiceCollection AddLazyResolution(this IServiceCollection services)
|
||||
{
|
||||
return services.AddTransient(
|
||||
typeof(Lazy<>),
|
||||
typeof(LazilyResolved<>));
|
||||
}
|
||||
|
||||
private class LazilyResolved<T> : Lazy<T>
|
||||
{
|
||||
public LazilyResolved(IServiceProvider serviceProvider)
|
||||
: base(serviceProvider.GetRequiredService<T>)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
|
||||
ConfigurationManager configManager = builder.Configuration;
|
||||
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen(options =>
|
||||
{
|
||||
string xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||
string xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
||||
options.IncludeXmlComments(xmlPath, true);
|
||||
});
|
||||
|
||||
builder.Host.UseSerilog((context, configuration) => configuration.ReadFrom.Configuration(context.Configuration));
|
||||
|
||||
builder.Services.AddDbContext<SASGContext>(options => { options.UseMySQL(builder.Configuration["connectionString"] ?? throw new InvalidOperationException("Connection String is null")); });
|
||||
|
||||
builder.Services.AddTransient<ColorService>();
|
||||
builder.Services.AddTransient<EventService>();
|
||||
builder.Services.AddTransient<GrantService>();
|
||||
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>>();
|
||||
SASGContext context = options.GetRequiredService<SASGContext>();
|
||||
IUserAuthentication authentication = options.GetRequiredService<IUserAuthentication>();
|
||||
PermissionService permissionService = options.GetRequiredService<PermissionService>();
|
||||
|
||||
ulong defaultUserPermission = UInt64.Parse(builder.Configuration["defaultUserPermission"] ?? throw new InvalidOperationException("defaultUserPermission is null"));
|
||||
|
||||
return new UserService(logger, context, authentication, permissionService, defaultUserPermission);
|
||||
});
|
||||
|
||||
builder.Services.AddTransient<IColorAuthentication, ColorAuthentication>();
|
||||
builder.Services.AddTransient<IEventAuthentication, EventAuthentication>();
|
||||
builder.Services.AddTransient<IGrantAuthentication, GrantAuthentication>();
|
||||
builder.Services.AddTransient<IImageAuthentication, ImageAuthentication>();
|
||||
builder.Services.AddTransient<IColorAuthentication, ColorAuthentication>();
|
||||
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>();
|
||||
|
||||
builder.Services.AddTransient<IHashingAlgorithm, Pbkdf2>();
|
||||
|
||||
builder.Services.AddTransient<IGrantManager, GrantManager>();
|
||||
builder.Services.AddTransient<IUserManager, UserManager>(options =>
|
||||
{
|
||||
UserService userService = options.GetRequiredService<UserService>();
|
||||
IHashingFactory hashingFactory = options.GetRequiredService<IHashingFactory>();
|
||||
ILogger<UserManager> logger = options.GetRequiredService<ILogger<UserManager>>();
|
||||
|
||||
HashingType hashingType;
|
||||
if (!Enum.TryParse(builder.Configuration["preferredHashingType"], out hashingType))
|
||||
throw new InvalidOperationException($"preferredHashingType not one of {String.Join(", ", Enum.GetNames(typeof(HashingType)))}");
|
||||
|
||||
return new UserManager(userService, hashingFactory, logger, hashingType);
|
||||
});
|
||||
|
||||
|
||||
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
|
||||
{
|
||||
options.Events.OnRedirectToAccessDenied = context =>
|
||||
{
|
||||
context.Response.StatusCode = 403;
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
});
|
||||
// builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
|
||||
// {
|
||||
// options.Cookie.SameSite = SameSiteMode.None;
|
||||
// options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
|
||||
// });
|
||||
|
||||
builder.Services.AddLazyResolution();
|
||||
|
||||
WebApplication app = builder.Build();
|
||||
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
|
||||
app.UseCookiePolicy(new CookiePolicyOptions
|
||||
{
|
||||
MinimumSameSitePolicy = SameSiteMode.Strict
|
||||
});
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseCors(builder => {
|
||||
builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
|
||||
});
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
app.MapControllers();
|
||||
app.Run();
|
||||
}
|
||||
}
|
||||
}
|
@ -4,11 +4,31 @@
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:18853",
|
||||
"applicationUrl": "http://localhost:36321",
|
||||
"sslPort": 44359
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"applicationUrl": "http://localhost:5279",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"applicationUrl": "https://localhost:7089;http://localhost:5279",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
@ -16,16 +36,6 @@
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"sanAntonioSeniorGolf": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": "true",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "api/website/index.html",
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
API/Services/ColorService.cs
Normal file
15
API/Services/ColorService.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using DAL.Contexts;
|
||||
using DAL.Models;
|
||||
using DAL.Models.Audits;
|
||||
|
||||
namespace API.Services
|
||||
{
|
||||
public class ColorService : ServiceBase<ColorService, ColorDTO, Color, AuditColor, IColorAuthentication>
|
||||
{
|
||||
public ColorService(ILogger<ColorService> logger, SASGContext context, IColorAuthentication auth) : base(logger, context, auth)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
23
API/Services/EventService.cs
Normal file
23
API/Services/EventService.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using DAL.Contexts;
|
||||
using DAL.Models;
|
||||
using DAL.Models.Audits;
|
||||
|
||||
namespace API.Services
|
||||
{
|
||||
public class EventService : ServiceBase<EventService, EventDTO, Event, AuditEvent, IEventAuthentication>
|
||||
{
|
||||
public EventService(ILogger<EventService> logger, SASGContext context, IEventAuthentication auth) : base(logger, context, auth)
|
||||
{
|
||||
}
|
||||
|
||||
public bool? isSignedUp(User user, ulong eventId)
|
||||
{
|
||||
if (!_auth.canCheckSelfSignup(user))
|
||||
return null;
|
||||
|
||||
return Context.Set<Signup>().Any(x => x.userId == user.id && x.eventId == eventId);
|
||||
}
|
||||
}
|
||||
}
|
85
API/Services/GrantManager.cs
Normal file
85
API/Services/GrantManager.cs
Normal file
@ -0,0 +1,85 @@
|
||||
using API.Services.Interfaces;
|
||||
using DAL.Contexts;
|
||||
using DAL.Models;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace API.Services
|
||||
{
|
||||
public class GrantManager : IGrantManager
|
||||
{
|
||||
private readonly SASGContext _context;
|
||||
private ILogger<GrantManager> _logger;
|
||||
|
||||
public GrantManager(ILogger<GrantManager> logger, SASGContext context)
|
||||
{
|
||||
_logger = logger;
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public bool hasGrant(ulong permissionId, string grantName)
|
||||
{
|
||||
return getGrant(x => x.permissionId == permissionId && x.name.Equals(grantName)).Any();
|
||||
}
|
||||
|
||||
public List<string> getValues(ulong permissionId, string grantName)
|
||||
{
|
||||
List<Grant> grants = getGrant(x => x.permissionId == permissionId && x.name.StartsWith(grantName + ".")).ToList();
|
||||
|
||||
List<string> values = [];
|
||||
foreach (Grant grant in grants)
|
||||
{
|
||||
string value = grant.name.Substring(grantName.Length + 1);
|
||||
if (value.Contains('.'))
|
||||
// Were not looking at a value and instead another grant
|
||||
continue;
|
||||
|
||||
values.Add(value);
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
public List<string> getStringValues(ulong permissionId, string grantName)
|
||||
{
|
||||
List<string> values = getValues(permissionId, grantName);
|
||||
|
||||
// Get rid of numbers
|
||||
values = values.Where(x => !Int32.TryParse(x, out int _)).ToList();
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
public List<int> getIntValues(ulong permissionId, string grantName)
|
||||
{
|
||||
List<string> values = getValues(permissionId, grantName);
|
||||
List<int> intValues = [];
|
||||
|
||||
Parallel.ForEach(values, x =>
|
||||
{
|
||||
if (Int32.TryParse(x, out int parsed))
|
||||
intValues.Add(parsed);
|
||||
});
|
||||
|
||||
return intValues;
|
||||
}
|
||||
|
||||
public List<ulong> getULongValues(ulong permissionId, string grantName)
|
||||
{
|
||||
List<string> values = getValues(permissionId, grantName);
|
||||
List<ulong> uLongValues = [];
|
||||
|
||||
Parallel.ForEach(values, x =>
|
||||
{
|
||||
if (UInt64.TryParse(x, out ulong parsed))
|
||||
uLongValues.Add(parsed);
|
||||
});
|
||||
|
||||
return uLongValues;
|
||||
}
|
||||
|
||||
private IEnumerable<Grant> getGrant(Expression<Func<Grant, bool>> whereClause)
|
||||
{
|
||||
return _context.Set<Grant>().Where(whereClause);
|
||||
}
|
||||
}
|
||||
}
|
23
API/Services/GrantService.cs
Normal file
23
API/Services/GrantService.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using DAL.Contexts;
|
||||
using DAL.Models;
|
||||
using DAL.Models.Audits;
|
||||
|
||||
namespace API.Services
|
||||
{
|
||||
public class GrantService : ServiceBase<GrantService, GrantDTO, Grant, AuditGrant, IGrantAuthentication>
|
||||
{
|
||||
public GrantService(ILogger<GrantService> logger, SASGContext context, IGrantAuthentication auth) : base(logger, context, auth)
|
||||
{
|
||||
}
|
||||
|
||||
public IEnumerable<Grant>? getMine(User user)
|
||||
{
|
||||
if (!_auth.canGetMine(user))
|
||||
return null;
|
||||
|
||||
return Context.Set<Grant>().Where(x => x.permissionId == user.permissionId);
|
||||
}
|
||||
}
|
||||
}
|
15
API/Services/ImageService.cs
Normal file
15
API/Services/ImageService.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using DAL.Contexts;
|
||||
using DAL.Models;
|
||||
using DAL.Models.Audits;
|
||||
|
||||
namespace API.Services
|
||||
{
|
||||
public class ImageService : ServiceBase<ImageService, ImageDTO, Image, AuditImage, IImageAuthentication>
|
||||
{
|
||||
public ImageService(ILogger<ImageService> logger, SASGContext context, IImageAuthentication auth) : base(logger, context, auth)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
16
API/Services/Interfaces/IGenericService.cs
Normal file
16
API/Services/Interfaces/IGenericService.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using DAL.Models;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace API.Services.Interfaces
|
||||
{
|
||||
public interface IGenericService<in T, TModel, out TAudit>
|
||||
{
|
||||
TModel? get(ulong id, User user);
|
||||
IEnumerable<TModel>? get(User user, Expression<Func<TModel, bool>>? whereClause = null);
|
||||
TModel? getNoAuthentication(ulong id);
|
||||
IEnumerable<TModel> getNoAuthentication(Expression<Func<TModel, bool>>? whereClause = null);
|
||||
TModel? add(T item, User user);
|
||||
TModel? update(TModel model, User user);
|
||||
TAudit? delete(TModel model, User user);
|
||||
}
|
||||
}
|
11
API/Services/Interfaces/IGrantManager.cs
Normal file
11
API/Services/Interfaces/IGrantManager.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace API.Services.Interfaces
|
||||
{
|
||||
public interface IGrantManager
|
||||
{
|
||||
public bool hasGrant(ulong permissionId, string grantName);
|
||||
public List<string> getValues(ulong permissionId, string grantName);
|
||||
public List<string> getStringValues(ulong permissionId, string grantName);
|
||||
public List<int> getIntValues(ulong permissionId, string grantName);
|
||||
public List<ulong> getULongValues(ulong permissionId, string grantName);
|
||||
}
|
||||
}
|
16
API/Services/Interfaces/IUserManager.cs
Normal file
16
API/Services/Interfaces/IUserManager.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using API.DTO.Base;
|
||||
using API.DTO.Base.Update;
|
||||
using API.DTO.Login;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Services.Interfaces
|
||||
{
|
||||
public interface IUserManager
|
||||
{
|
||||
UserDTO? authenticateUser(UserLoginDTO loginDTO);
|
||||
|
||||
UserDTO? registerUser(UserRegisterDTO registerDTO, User? user = null, ulong? permissionId = null);
|
||||
|
||||
UserDTO? changePassword(UserPasswordUpdateDTO passwordUpdateDTO, User changingUser);
|
||||
}
|
||||
}
|
16
API/Services/PermissionService.cs
Normal file
16
API/Services/PermissionService.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using DAL.Contexts;
|
||||
using DAL.Models;
|
||||
using DAL.Models.Audits;
|
||||
|
||||
namespace API.Services
|
||||
{
|
||||
public class PermissionService : ServiceBase<PermissionService, PermissionDTO, Permission, AuditPermission, IPermissionAuthentication>
|
||||
{
|
||||
|
||||
public PermissionService(ILogger<PermissionService> logger, SASGContext context, IPermissionAuthentication auth) : base(logger, context, auth)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
16
API/Services/SavedEventService.cs
Normal file
16
API/Services/SavedEventService.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using DAL.Contexts;
|
||||
using DAL.Models;
|
||||
using DAL.Models.Audits;
|
||||
|
||||
namespace API.Services
|
||||
{
|
||||
public class SavedEventService : ServiceBase<SavedEventService, SavedEventDTO, SavedEvent, AuditSavedEvent, ISavedEventAuthentication>
|
||||
{
|
||||
|
||||
public SavedEventService(ILogger<SavedEventService> logger, SASGContext context, ISavedEventAuthentication auth) : base(logger, context, auth)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
108
API/Services/ServiceBase.cs
Normal file
108
API/Services/ServiceBase.cs
Normal file
@ -0,0 +1,108 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO;
|
||||
using API.Services.Interfaces;
|
||||
using DAL.Contexts;
|
||||
using DAL.Models;
|
||||
using DAL.Models.Audits;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace API.Services
|
||||
{
|
||||
public class ServiceBase<TLoggerCategory, TDTO, TModel, TAudit, TAuthentication> : IGenericService<TDTO, TModel, TAudit>
|
||||
where TAuthentication : IGenericAuthentication<TDTO, TModel>
|
||||
where TModel : Model<TModel, TAudit>
|
||||
where TAudit : AuditModel<TModel>
|
||||
where TDTO : IAdaptable<TModel>
|
||||
{
|
||||
public readonly TAuthentication _auth;
|
||||
private readonly ILogger<TLoggerCategory> _logger;
|
||||
public readonly SASGContext Context;
|
||||
|
||||
public ServiceBase(ILogger<TLoggerCategory> logger, SASGContext context, TAuthentication auth)
|
||||
{
|
||||
_logger = logger;
|
||||
Context = context;
|
||||
_auth = auth;
|
||||
}
|
||||
|
||||
public TModel? get(ulong id, User user)
|
||||
{
|
||||
TModel? result = Context.Set<TModel>().Find(id);
|
||||
if (result == null)
|
||||
return null;
|
||||
|
||||
return _auth.canGet(result, user) ? result : null;
|
||||
}
|
||||
|
||||
public IEnumerable<TModel>? get(User user, Expression<Func<TModel, bool>>? whereClause = null)
|
||||
{
|
||||
if (!_auth.canGetAll(user))
|
||||
return null;
|
||||
|
||||
return whereClause != null ? Context.Set<TModel>().Where(whereClause) : Context.Set<TModel>();
|
||||
}
|
||||
|
||||
public TModel? getNoAuthentication(ulong id)
|
||||
{
|
||||
return Context.Set<TModel>().Find(id);
|
||||
}
|
||||
|
||||
public IEnumerable<TModel> getNoAuthentication(Expression<Func<TModel, bool>>? whereClause = null)
|
||||
{
|
||||
return whereClause != null ? Context.Set<TModel>().Where(whereClause) : Context.Set<TModel>();
|
||||
}
|
||||
|
||||
public TModel? add(TDTO item, User user)
|
||||
{
|
||||
if (!_auth.canAdd(item, user))
|
||||
return null;
|
||||
|
||||
TModel model = item.adaptToModel();
|
||||
|
||||
model.updater = user.id;
|
||||
model.updated = DateTime.Now;
|
||||
Context.Add(model);
|
||||
Context.SaveChanges();
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
public TModel? update(TModel model, User user)
|
||||
{
|
||||
if (!_auth.canUpdate(model, user))
|
||||
return null;
|
||||
|
||||
TModel? origModel = Context.Set<TModel>().Find(model.id);
|
||||
if (origModel == null)
|
||||
return null;
|
||||
|
||||
model.updateModel(ref origModel);
|
||||
|
||||
origModel.updated = DateTime.Now;
|
||||
origModel.updater = user.id;
|
||||
|
||||
Context.SaveChanges();
|
||||
|
||||
return origModel;
|
||||
}
|
||||
|
||||
public TAudit? delete(TModel model, User user)
|
||||
{
|
||||
if (!_auth.canDelete(model, user))
|
||||
return null;
|
||||
|
||||
TModel? origModel = Context.Set<TModel>().Find(model.id);
|
||||
if (origModel == null)
|
||||
return null;
|
||||
|
||||
origModel.updated = DateTime.Now;
|
||||
origModel.updater = user.id;
|
||||
Context.SaveChanges();
|
||||
|
||||
Context.Remove(origModel);
|
||||
Context.SaveChanges();
|
||||
|
||||
return origModel.adaptToAudit();
|
||||
}
|
||||
}
|
||||
}
|
16
API/Services/SignupService.cs
Normal file
16
API/Services/SignupService.cs
Normal 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)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
133
API/Services/UserManager.cs
Normal file
133
API/Services/UserManager.cs
Normal file
@ -0,0 +1,133 @@
|
||||
using API.DTO.Base;
|
||||
using API.DTO.Base.Update;
|
||||
using API.DTO.Login;
|
||||
using API.Hashing.Interfaces;
|
||||
using API.Services.Interfaces;
|
||||
using DAL.Models;
|
||||
|
||||
namespace API.Services
|
||||
{
|
||||
public class UserManager : IUserManager
|
||||
{
|
||||
private readonly IHashingFactory _hashingFactory;
|
||||
private readonly ILogger<UserManager> _logger;
|
||||
private readonly HashingType _preferredHashingType;
|
||||
private readonly UserService _userService;
|
||||
|
||||
public UserManager(UserService userService, IHashingFactory hashingFactory, ILogger<UserManager> logger, HashingType preferredHashingType)
|
||||
{
|
||||
_userService = userService;
|
||||
_hashingFactory = hashingFactory;
|
||||
_logger = logger;
|
||||
_preferredHashingType = preferredHashingType;
|
||||
}
|
||||
|
||||
public UserDTO? authenticateUser(UserLoginDTO loginDTO)
|
||||
{
|
||||
User? user = _userService.getNoAuthentication(x => x.phoneNumber.Equals(loginDTO.phoneNumber)).FirstOrDefault();
|
||||
|
||||
if (user == null)
|
||||
return null;
|
||||
|
||||
IHashingAlgorithm? hashingAlgorithm = _hashingFactory.getAlgorithm(user.hashingType);
|
||||
if (hashingAlgorithm == null)
|
||||
{
|
||||
_logger.Log(LogLevel.Warning, "User id '{id}' has a hashing type '{hashingType}' that isn't recognized by factory '{factory}'. Not logging in.", user.id, user.hashingType, nameof(_hashingFactory));
|
||||
return null;
|
||||
}
|
||||
|
||||
string hashedPassword = hashingAlgorithm.hash(loginDTO.password, user.salt);
|
||||
|
||||
if (!hashedPassword.Equals(user.password))
|
||||
{
|
||||
_logger.Log(LogLevel.Information, "Failed login attempt for user id '{id}.", user.id);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (user.hashingType != _preferredHashingType)
|
||||
{
|
||||
// todo The user is logged in at this point. Their hashing type needs to be updated, we need to rehash & salt the password and save it now.
|
||||
}
|
||||
|
||||
UserDTO dto = new UserDTO();
|
||||
dto.adaptFromModel(user);
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
public UserDTO? registerUser(UserRegisterDTO registerDTO, User? user = null, ulong? permissionId = null)
|
||||
{
|
||||
if (_userService.getNoAuthentication(x =>
|
||||
x.phoneNumber.Equals(registerDTO.phoneNumber) ||
|
||||
x.firstName.Equals(registerDTO.firstName) && x.lastName.Equals(registerDTO.lastName))
|
||||
.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
IHashingAlgorithm? hashingAlgorithm = _hashingFactory.getAlgorithm(_preferredHashingType);
|
||||
if (hashingAlgorithm == null)
|
||||
{
|
||||
_logger.Log(LogLevel.Error, "Preferred hashing type '{hashingType}' that isn't recognized by factory '{factory}'.", _preferredHashingType, nameof(_hashingFactory));
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] salt;
|
||||
string hashedPassword = hashingAlgorithm.hash(registerDTO.password, out salt);
|
||||
|
||||
User? createdUser = _userService.add(registerDTO, hashedPassword, salt, user, permissionId);
|
||||
|
||||
if (createdUser == null)
|
||||
return null;
|
||||
|
||||
UserDTO dto = new UserDTO();
|
||||
dto.adaptFromModel(createdUser);
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
public UserDTO? changePassword(UserPasswordUpdateDTO userPasswordUpdateDTO, User changingUser)
|
||||
{
|
||||
User? destUser = _userService.getNoAuthentication(x => x.phoneNumber.Equals(userPasswordUpdateDTO.phoneNumber)).FirstOrDefault();
|
||||
if (destUser == null)
|
||||
return null;
|
||||
|
||||
IHashingAlgorithm? hashingAlgorithm = _hashingFactory.getAlgorithm(_preferredHashingType);
|
||||
if (hashingAlgorithm == null){
|
||||
_logger.Log(LogLevel.Error, "Preferred hashing type '{hashingType}' that isn't recognized by factory '{factory}'.", _preferredHashingType, nameof(_hashingFactory));
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] newSalt;
|
||||
string hashedNewPassword = hashingAlgorithm.hash(userPasswordUpdateDTO.newPassword, out newSalt);
|
||||
|
||||
bool oldPasswordMatchNew = false;
|
||||
if (userPasswordUpdateDTO.oldPassword != null)
|
||||
{
|
||||
IHashingAlgorithm? userHashingAlgorithm = _hashingFactory.getAlgorithm(destUser.hashingType);
|
||||
if (userHashingAlgorithm == null)
|
||||
{
|
||||
_logger.Log(LogLevel.Warning, "User id '{id}' has a hashing type '{hashingType}' that isn't recognized by factory '{factory}'. Not logging in.", destUser.id, destUser.hashingType, nameof(_hashingFactory));
|
||||
return null;
|
||||
}
|
||||
|
||||
string hashedOldPassword = userHashingAlgorithm.hash(userPasswordUpdateDTO.oldPassword, destUser.salt);
|
||||
|
||||
if (hashedOldPassword.Equals(destUser.password))
|
||||
{
|
||||
oldPasswordMatchNew = true;
|
||||
}
|
||||
}
|
||||
|
||||
User? updatedUser = _userService.changePassword(destUser, changingUser, hashedNewPassword, newSalt, oldPasswordMatchNew);
|
||||
|
||||
if (updatedUser == null)
|
||||
return null;
|
||||
|
||||
UserDTO dto = new UserDTO();
|
||||
dto.adaptFromModel(updatedUser);
|
||||
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
}
|
72
API/Services/UserService.cs
Normal file
72
API/Services/UserService.cs
Normal file
@ -0,0 +1,72 @@
|
||||
using API.Authentication.Interfaces;
|
||||
using API.DTO.Base;
|
||||
using API.DTO.Base.Update;
|
||||
using API.DTO.Login;
|
||||
using DAL.Contexts;
|
||||
using DAL.Models;
|
||||
using DAL.Models.Audits;
|
||||
|
||||
namespace API.Services
|
||||
{
|
||||
public class UserService : ServiceBase<UserService, UserDTO, User, AuditUser, IUserAuthentication>
|
||||
{
|
||||
private readonly ulong _defaultUserPermission;
|
||||
private readonly PermissionService _permissionService;
|
||||
public UserService(ILogger<UserService> logger, SASGContext context, IUserAuthentication auth, PermissionService permissionService, ulong defaultUserPermission) : base(logger, context, auth)
|
||||
{
|
||||
_permissionService = permissionService;
|
||||
_defaultUserPermission = defaultUserPermission;
|
||||
}
|
||||
|
||||
public User? add(UserRegisterDTO registerDTO, string hashedPassword, byte[] salt, User? user = null, ulong? permissionId = null)
|
||||
{
|
||||
Permission? defaultPermission = _permissionService.getNoAuthentication(_defaultUserPermission);
|
||||
if (defaultPermission == null)
|
||||
throw new InvalidOperationException("defaultUserPermission doesn't exist.");
|
||||
|
||||
User model = new User
|
||||
{
|
||||
firstName = registerDTO.firstName,
|
||||
lastName = registerDTO.lastName,
|
||||
phoneNumber = registerDTO.phoneNumber,
|
||||
|
||||
password = hashedPassword,
|
||||
salt = salt,
|
||||
|
||||
permissionId = permissionId ?? defaultPermission.id,
|
||||
|
||||
updated = DateTime.Now
|
||||
};
|
||||
|
||||
if (permissionId != null && user != null)
|
||||
{
|
||||
model.permissionId = permissionId.Value;
|
||||
model.updater = user.id;
|
||||
UserDTO userDTO = new UserDTO();
|
||||
userDTO.adaptFromModel(user);
|
||||
if (!_auth.canAdd(userDTO, user))
|
||||
return null;
|
||||
Context.Add(model);
|
||||
Context.SaveChanges();
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
Context.Add(model);
|
||||
Context.SaveChanges();
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
public User? changePassword(User destUser, User changingUser, string hashedNewPassword, byte[] newSalt, bool oldPasswordMatchNew)
|
||||
{
|
||||
if (!_auth.canChangePassword(destUser, changingUser, oldPasswordMatchNew))
|
||||
return null;
|
||||
|
||||
destUser.password = hashedNewPassword;
|
||||
destUser.salt = newSalt;
|
||||
|
||||
return update(destUser, changingUser);
|
||||
}
|
||||
}
|
||||
}
|
115
DAL/Contexts/SASGContext.cs
Normal file
115
DAL/Contexts/SASGContext.cs
Normal file
@ -0,0 +1,115 @@
|
||||
using DAL.Converters;
|
||||
using DAL.Models;
|
||||
using DAL.Models.Audits;
|
||||
using DAL.Values;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace DAL.Contexts
|
||||
{
|
||||
public class SASGContext : DbContext
|
||||
{
|
||||
public SASGContext()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public SASGContext(DbContextOptions<SASGContext> options) : base(options)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual DbSet<Color> colors { get; set; }
|
||||
public virtual DbSet<Event> events { get; set; }
|
||||
public virtual DbSet<Grant> grants { get; set; }
|
||||
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; }
|
||||
public virtual DbSet<AuditGrant> auditGrants { get; set; }
|
||||
public virtual DbSet<AuditImage> auditImages { get; set; }
|
||||
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)
|
||||
{
|
||||
configurationBuilder.Properties<PhoneNumber>().HaveConversion<PhoneNumberConverter>();
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
builder.Entity<Color>(entity =>
|
||||
{
|
||||
entity.HasOne(e => e.updaterRelation).WithMany()
|
||||
.HasForeignKey(e => e.updater).HasConstraintName("colors_users_id_fk");
|
||||
});
|
||||
|
||||
builder.Entity<Event>(entity =>
|
||||
{
|
||||
entity.HasOne(e => e.bgColorRelation).WithMany()
|
||||
.HasForeignKey(e => e.bgColorId).HasConstraintName("events_colors_id_fk");
|
||||
entity.HasOne(e => e.fgColorRelation).WithMany()
|
||||
.HasForeignKey(e => e.fgColorId).HasConstraintName("events_colors_id_fk_2");
|
||||
entity.HasOne(e => e.imageRelation).WithMany()
|
||||
.HasForeignKey(e => e.imageId).HasConstraintName("events_images_id_fk");
|
||||
entity.HasOne(e => e.savedEventRelation).WithMany()
|
||||
.HasForeignKey(e => e.savedEventId).HasConstraintName("events_savedEvent_id_fk");
|
||||
entity.HasOne(e => e.updaterRelation).WithMany()
|
||||
.HasForeignKey(e => e.updater).HasConstraintName("events_users_id_fk");
|
||||
});
|
||||
|
||||
builder.Entity<Grant>(entity =>
|
||||
{
|
||||
entity.HasOne(e => e.permissionRelation).WithMany()
|
||||
.HasForeignKey(e => e.permissionId).HasConstraintName("grants_permissions_id_fk");
|
||||
entity.HasOne(e => e.updaterRelation).WithMany()
|
||||
.HasForeignKey(e => e.updater).HasConstraintName("grants_users_id_fk");
|
||||
});
|
||||
|
||||
builder.Entity<Image>(entity =>
|
||||
{
|
||||
entity.HasOne(e => e.updaterRelation).WithMany()
|
||||
.HasForeignKey(e => e.updater).HasConstraintName("grants_users_id_fk");
|
||||
});
|
||||
|
||||
builder.Entity<Permission>(entity =>
|
||||
{
|
||||
entity.HasOne(e => e.updaterRelation).WithMany()
|
||||
.HasForeignKey(e => e.updater).HasConstraintName("grants_users_id_fk");
|
||||
});
|
||||
|
||||
builder.Entity<SavedEvent>(entity =>
|
||||
{
|
||||
entity.HasOne(e => e.bgColorRelation).WithMany()
|
||||
.HasForeignKey(e => e.bgColorId).HasConstraintName("events_colors_id_fk");
|
||||
entity.HasOne(e => e.fgColorRelation).WithMany()
|
||||
.HasForeignKey(e => e.fgColorId).HasConstraintName("events_colors_id_fk_2");
|
||||
entity.HasOne(e => e.imageRelation).WithMany()
|
||||
.HasForeignKey(e => e.imageId).HasConstraintName("events_images_id_fk");
|
||||
entity.HasOne(e => e.updaterRelation).WithMany()
|
||||
.HasForeignKey(e => e.updater).HasConstraintName("events_users_id_fk");
|
||||
});
|
||||
|
||||
builder.Entity<User>(entity =>
|
||||
{
|
||||
entity.HasOne(e => e.updaterRelation).WithMany()
|
||||
.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");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
19
DAL/Converters/PhoneNumberConverter.cs
Normal file
19
DAL/Converters/PhoneNumberConverter.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using DAL.Values;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace DAL.Converters
|
||||
{
|
||||
public class PhoneNumberConverter : ValueConverter<PhoneNumber, string>
|
||||
{
|
||||
public PhoneNumberConverter() : base(
|
||||
v => v.value,
|
||||
v => new PhoneNumber
|
||||
{
|
||||
value = v
|
||||
}
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
19
DAL/DAL.csproj
Normal file
19
DAL/DAL.csproj
Normal file
@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.7"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.7"/>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.7">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MySql.EntityFrameworkCore" Version="8.0.5"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
38
DAL/Models/Audits/AuditColor.cs
Normal file
38
DAL/Models/Audits/AuditColor.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DAL.Models.Audits
|
||||
{
|
||||
[Index("id", Name = "audit_colors_colors_id_fk")]
|
||||
[Table("audit_colors")]
|
||||
public class AuditColor : AuditModel<Color>
|
||||
{
|
||||
[Column("red")]
|
||||
public byte red { get; set; }
|
||||
|
||||
[Column("blue")]
|
||||
public byte blue { get; set; }
|
||||
|
||||
[Column("green")]
|
||||
public byte green { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
[MaxLength(64)]
|
||||
public string name { get; set; } = null!;
|
||||
|
||||
public override Color adaptToModel()
|
||||
{
|
||||
return new Color
|
||||
{
|
||||
id = originalId,
|
||||
red = red,
|
||||
blue = blue,
|
||||
green = green,
|
||||
name = name,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
49
DAL/Models/Audits/AuditEvent.cs
Normal file
49
DAL/Models/Audits/AuditEvent.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DAL.Models.Audits
|
||||
{
|
||||
[Table("audit_event")]
|
||||
[Index("id", Name = "audit_events_events_id_fk")]
|
||||
public class AuditEvent : AuditModel<Event>
|
||||
{
|
||||
[Column("savedEventId")]
|
||||
public ulong savedEventId { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
[MaxLength(64)]
|
||||
public string? name { get; set; }
|
||||
|
||||
[Column("bgColorId")]
|
||||
public ulong? bgColorId { get; set; }
|
||||
|
||||
[Column("fgColorId")]
|
||||
public ulong? fgColorId { get; set; }
|
||||
|
||||
[Column("imageId")]
|
||||
public ulong? imageId { get; set; }
|
||||
|
||||
[Column("when")]
|
||||
public DateTime when { get; set; }
|
||||
|
||||
[Column("hidden")]
|
||||
public bool hidden { get; set; }
|
||||
|
||||
public override Event adaptToModel()
|
||||
{
|
||||
return new Event
|
||||
{
|
||||
id = originalId,
|
||||
savedEventId = savedEventId,
|
||||
name = name,
|
||||
bgColorId = bgColorId,
|
||||
fgColorId = fgColorId,
|
||||
imageId = imageId,
|
||||
hidden = hidden,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
30
DAL/Models/Audits/AuditGrant.cs
Normal file
30
DAL/Models/Audits/AuditGrant.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DAL.Models.Audits
|
||||
{
|
||||
[Table("audit_grants")]
|
||||
[Index("id", Name = "audit_grants_grants_id_fk")]
|
||||
public class AuditGrant : AuditModel<Grant>
|
||||
{
|
||||
[Column("name")]
|
||||
[MaxLength(128)]
|
||||
public string name { get; set; } = null!;
|
||||
|
||||
[Column("permissionId")]
|
||||
public ulong permissionId { get; set; }
|
||||
|
||||
public override Grant adaptToModel()
|
||||
{
|
||||
return new Grant
|
||||
{
|
||||
id = originalId,
|
||||
name = name,
|
||||
permissionId = permissionId,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
31
DAL/Models/Audits/AuditImage.cs
Normal file
31
DAL/Models/Audits/AuditImage.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DAL.Models.Audits
|
||||
{
|
||||
[Table("audit_images")]
|
||||
[Index("id", Name = "audit_images_images_id_fk")]
|
||||
public class AuditImage : AuditModel<Image>
|
||||
{
|
||||
[Column("name")]
|
||||
[MaxLength(64)]
|
||||
public string name { get; set; } = null!;
|
||||
|
||||
[Column("filename")]
|
||||
[MaxLength(128)]
|
||||
public string filename { get; set; } = null!;
|
||||
|
||||
public override Image adaptToModel()
|
||||
{
|
||||
return new Image
|
||||
{
|
||||
id = originalId,
|
||||
name = name,
|
||||
filename = filename,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
24
DAL/Models/Audits/AuditModel.cs
Normal file
24
DAL/Models/Audits/AuditModel.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DAL.Models.Audits
|
||||
{
|
||||
public abstract class AuditModel<TModel>
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public ulong id { get; set; }
|
||||
|
||||
[Column("originalId")]
|
||||
public ulong originalId { get; set; }
|
||||
|
||||
[Column("updated")]
|
||||
[DataType("datetime")]
|
||||
public DateTime updated { get; set; }
|
||||
|
||||
[Column("updater")]
|
||||
public ulong updater { get; set; }
|
||||
|
||||
public abstract TModel adaptToModel();
|
||||
}
|
||||
}
|
26
DAL/Models/Audits/AuditPermission.cs
Normal file
26
DAL/Models/Audits/AuditPermission.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DAL.Models.Audits
|
||||
{
|
||||
[Table("audit_permissions")]
|
||||
[Index("id", Name = "audit_permissions_permissions_id_fk")]
|
||||
public class AuditPermission : AuditModel<Permission>
|
||||
{
|
||||
[Column("name")]
|
||||
[MaxLength(64)]
|
||||
public string name { get; set; } = null!;
|
||||
|
||||
public override Permission adaptToModel()
|
||||
{
|
||||
return new Permission
|
||||
{
|
||||
id = originalId,
|
||||
name = name,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
38
DAL/Models/Audits/AuditSavedEvent.cs
Normal file
38
DAL/Models/Audits/AuditSavedEvent.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DAL.Models.Audits
|
||||
{
|
||||
[Table("audit_savedEvents")]
|
||||
[Index("id", Name = "audit_savedEvents_savedEvents_id_fk")]
|
||||
public class AuditSavedEvent : AuditModel<SavedEvent>
|
||||
{
|
||||
[Column("name")]
|
||||
[MaxLength(64)]
|
||||
public string name { get; set; } = null!;
|
||||
|
||||
[Column("bgColorId")]
|
||||
public ulong bgColorId { get; set; }
|
||||
|
||||
[Column("fgColorId")]
|
||||
public ulong fgColorId { get; set; }
|
||||
|
||||
[Column("imageId")]
|
||||
public ulong? imageId { get; set; }
|
||||
|
||||
public override SavedEvent adaptToModel()
|
||||
{
|
||||
return new SavedEvent
|
||||
{
|
||||
id = originalId,
|
||||
name = name,
|
||||
bgColorId = bgColorId,
|
||||
fgColorId = fgColorId,
|
||||
imageId = imageId,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
28
DAL/Models/Audits/AuditSignup.cs
Normal file
28
DAL/Models/Audits/AuditSignup.cs
Normal 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
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
48
DAL/Models/Audits/AuditUser.cs
Normal file
48
DAL/Models/Audits/AuditUser.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using DAL.Values;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DAL.Models.Audits
|
||||
{
|
||||
[Table("audit_users")]
|
||||
[Index("id", Name = "audit_users_users_id_fk")]
|
||||
public class AuditUser : AuditModel<User>
|
||||
{
|
||||
[Column("firstName")]
|
||||
[MaxLength(64)]
|
||||
public string firstName { get; set; } = null!;
|
||||
|
||||
[Column("lastName")]
|
||||
[MaxLength(64)]
|
||||
public string lastName { get; set; } = null!;
|
||||
|
||||
[Column("phoneNumber")]
|
||||
public PhoneNumber phoneNumber { get; set; } = null!;
|
||||
|
||||
[Column("hashingType")]
|
||||
[MaxLength(64)]
|
||||
public HashingType hashingType { get; set; }
|
||||
|
||||
[Column("permissionId")]
|
||||
public ulong permissionId { get; set; }
|
||||
|
||||
[Column("updater")]
|
||||
public new ulong? updater { get; set; }
|
||||
|
||||
public override User adaptToModel()
|
||||
{
|
||||
return new User
|
||||
{
|
||||
id = originalId,
|
||||
firstName = firstName,
|
||||
lastName = lastName,
|
||||
phoneNumber = phoneNumber,
|
||||
hashingType = hashingType,
|
||||
permissionId = permissionId,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
46
DAL/Models/Color.cs
Normal file
46
DAL/Models/Color.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using DAL.Models.Audits;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DAL.Models
|
||||
{
|
||||
[Table("colors")]
|
||||
[Index("updater", Name = "colors_users_id_fk")]
|
||||
public class Color : Model<Color, AuditColor>
|
||||
{
|
||||
[Column("red")]
|
||||
public byte red { get; set; }
|
||||
|
||||
[Column("blue")]
|
||||
public byte blue { get; set; }
|
||||
|
||||
[Column("green")]
|
||||
public byte green { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
[MaxLength(64)]
|
||||
public string name { get; set; } = null!;
|
||||
|
||||
public override AuditColor adaptToAudit()
|
||||
{
|
||||
return new AuditColor
|
||||
{
|
||||
id = id,
|
||||
red = red,
|
||||
blue = blue,
|
||||
green = green,
|
||||
name = name,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
public override void updateModel(ref Color dest)
|
||||
{
|
||||
dest.red = red;
|
||||
dest.blue = blue;
|
||||
dest.green = green;
|
||||
dest.name = name;
|
||||
}
|
||||
}
|
||||
}
|
69
DAL/Models/Event.cs
Normal file
69
DAL/Models/Event.cs
Normal file
@ -0,0 +1,69 @@
|
||||
using DAL.Models.Audits;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DAL.Models
|
||||
{
|
||||
[Table("events")]
|
||||
[Index("updater", Name = "event_users_id_fk")]
|
||||
[Index("bgColorId", Name = "events_colors_id_fk")]
|
||||
[Index("fgColorId", Name = "events_colors_id_fk_2")]
|
||||
[Index("imageId", Name = "events_images_id_fk")]
|
||||
[Index("savedEventId", Name = "events_savedEvents_id_fk")]
|
||||
[Index("when", Name = "events_when_index")]
|
||||
public class Event : Model<Event, AuditEvent>
|
||||
{
|
||||
[Column("savedEventId")]
|
||||
public ulong savedEventId { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
[MaxLength(64)]
|
||||
public string? name { get; set; }
|
||||
|
||||
[Column("bgColorId")]
|
||||
public ulong? bgColorId { get; set; }
|
||||
|
||||
[Column("fgColorId")]
|
||||
public ulong? fgColorId { get; set; }
|
||||
|
||||
[Column("imageId")]
|
||||
public ulong? imageId { get; set; }
|
||||
|
||||
[Column("when")]
|
||||
public DateTime when { get; set; }
|
||||
|
||||
[Column("hidden")]
|
||||
public bool hidden { get; set; }
|
||||
|
||||
public SavedEvent savedEventRelation { get; set; } = null!;
|
||||
public Color? bgColorRelation { get; set; }
|
||||
public Color? fgColorRelation { get; set; }
|
||||
public Image? imageRelation { get; set; }
|
||||
|
||||
public override AuditEvent adaptToAudit()
|
||||
{
|
||||
return new AuditEvent
|
||||
{
|
||||
id = id,
|
||||
savedEventId = savedEventId,
|
||||
name = name,
|
||||
bgColorId = bgColorId,
|
||||
fgColorId = fgColorId,
|
||||
imageId = imageId,
|
||||
hidden = hidden,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
public override void updateModel(ref Event dest)
|
||||
{
|
||||
dest.savedEventId = savedEventId;
|
||||
dest.name = name;
|
||||
dest.bgColorId = bgColorId;
|
||||
dest.fgColorId = fgColorId;
|
||||
dest.imageId = imageId;
|
||||
dest.hidden = hidden;
|
||||
}
|
||||
}
|
||||
}
|
40
DAL/Models/Grant.cs
Normal file
40
DAL/Models/Grant.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using DAL.Models.Audits;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace DAL.Models
|
||||
{
|
||||
[Table("grants")]
|
||||
[Index("updater", Name = "grants_users_id_fk")]
|
||||
[Index("permissionId", Name = "grants_permissions_id_fk")]
|
||||
[Index("updater", Name = "grants_users_id_fk")]
|
||||
public class Grant : Model<Grant, AuditGrant>
|
||||
{
|
||||
[Column("name")]
|
||||
[MaxLength(128)]
|
||||
public string name { get; set; } = null!;
|
||||
|
||||
[Column("permissionId")]
|
||||
public ulong permissionId { get; set; }
|
||||
|
||||
public virtual Permission permissionRelation { get; set; } = null!;
|
||||
|
||||
public override AuditGrant adaptToAudit()
|
||||
{
|
||||
return new AuditGrant
|
||||
{
|
||||
id = id,
|
||||
name = name,
|
||||
permissionId = permissionId,
|
||||
updated = updated,
|
||||
updater = updater
|
||||
};
|
||||
}
|
||||
public override void updateModel(ref Grant dest)
|
||||
{
|
||||
dest.name = name;
|
||||
dest.permissionId = permissionId;
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user