Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 42187ba088 | |||
| cc90904228 | |||
| 47cf23d740 |
@@ -0,0 +1,2 @@
|
|||||||
|
/.idea/.idea.Knots/.idea/.name
|
||||||
|
/Knots/obj/rider.project.model.nuget.info
|
||||||
Generated
-17
@@ -1,17 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
|
||||||
<data-source source="LOCAL" name="@romaric-thibault.fr" uuid="821fc51f-62ea-4fa2-99b3-cb667f09e32a">
|
|
||||||
<driver-ref>sqlserver.jb</driver-ref>
|
|
||||||
<synchronize>true</synchronize>
|
|
||||||
<jdbc-driver>com.jetbrains.jdbc.sqlserver.SqlServerDriver</jdbc-driver>
|
|
||||||
<jdbc-url>Server=romaric-thibault.fr,1433</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.container.port" />
|
|
||||||
</jdbc-additional-properties>
|
|
||||||
<working-dir>$ProjectFileDir$</working-dir>
|
|
||||||
</data-source>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Knots.DTO.Discussion;
|
|
||||||
|
|
||||||
public class CreateDiscussionDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Knots.DTO.Discussion;
|
|
||||||
|
|
||||||
public class DeleteDiscussionDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
namespace Knots.DTO.Discussion;
|
|
||||||
|
|
||||||
public class GetDiscussionDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string Name { get; set; } = string.Empty;
|
|
||||||
public bool IsGroup { get; set; }
|
|
||||||
public int? MembersCount { get; set; }
|
|
||||||
|
|
||||||
public int? GroupId { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
namespace Knots.DTO.Group;
|
|
||||||
|
|
||||||
public class CreateGroupDto
|
|
||||||
{
|
|
||||||
public string? Nom { get; set; }
|
|
||||||
public int NombreMembres { get; set; }
|
|
||||||
public string? ProfilePicture { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Knots.DTO.Group;
|
|
||||||
|
|
||||||
public class DeleteGroupDto
|
|
||||||
{
|
|
||||||
public int? Id { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
namespace Knots.DTO.Group;
|
|
||||||
|
|
||||||
public class GetGroupDetailsDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string? Nom { get; set; }
|
|
||||||
public int NombreMembres { get; set; }
|
|
||||||
public string? ProfilePicture { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Knots.DTO.Group;
|
|
||||||
|
|
||||||
public class GetGroupDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
namespace Knots.DTO.Group;
|
|
||||||
|
|
||||||
public class UpdateGroupDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string? Nom { get; set; }
|
|
||||||
public int NombreMembres { get; set; }
|
|
||||||
public string? ProfilePicture { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace Knots.DTO.Group;
|
|
||||||
|
|
||||||
public class UpdateGroupMembersAmountDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public int MembersAmount { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace Knots.DTO.Group;
|
|
||||||
|
|
||||||
public class UpdateGroupNameDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string? Name { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace Knots.DTO.Group;
|
|
||||||
|
|
||||||
public class UpdateGroupProfilePictureDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string? ProfilePicture { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Knots.DTO.Key;
|
|
||||||
|
|
||||||
public class CreateKeyDto
|
|
||||||
{
|
|
||||||
public string? EnKey { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Knots.DTO.Key;
|
|
||||||
|
|
||||||
public class DeleteKeyDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace Knots.DTO.Key;
|
|
||||||
|
|
||||||
public class GetKeyDetailsDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string? EnKey { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Knots.DTO.Key;
|
|
||||||
|
|
||||||
public class GetKeyDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
namespace Knots.DTO.Message;
|
|
||||||
|
|
||||||
public class CreateMessageDto
|
|
||||||
{
|
|
||||||
public string? Contenu { get; set; }
|
|
||||||
public DateTime Date { get; set; }
|
|
||||||
public Boolean Type { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Knots.DTO.Message;
|
|
||||||
|
|
||||||
public class DeleteMessageDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
namespace Knots.DTO.Message;
|
|
||||||
|
|
||||||
public class GetMessageDetailsDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string? Contenu { get; set; }
|
|
||||||
public DateTime Date { get; set; }
|
|
||||||
public Boolean Type { get; set; }
|
|
||||||
|
|
||||||
public int UserId { get; set; }
|
|
||||||
public string AuthorName { get; set; } = "";
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Knots.DTO.Message;
|
|
||||||
|
|
||||||
public class GetMessageDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Knots.DTO.Role;
|
|
||||||
|
|
||||||
public class CreateRoleDto
|
|
||||||
{
|
|
||||||
public string? Libelle { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Knots.DTO.Role;
|
|
||||||
|
|
||||||
public class DeleteRoleDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Knots.DTO.Role;
|
|
||||||
|
|
||||||
public class GetRoleDto
|
|
||||||
{
|
|
||||||
public string? Libelle { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
namespace Knots.DTO.User;
|
|
||||||
|
|
||||||
public class CreateUserDto
|
|
||||||
{
|
|
||||||
public string? Username { get; set; }
|
|
||||||
public string? Description {get; set;}
|
|
||||||
public string? Password { get; set; }
|
|
||||||
public string? Email { get; set; }
|
|
||||||
public string? Tel { get; set; }
|
|
||||||
public string? ProfilePicture { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Knots.DTO.User;
|
|
||||||
|
|
||||||
public class DeleteUserDto
|
|
||||||
{
|
|
||||||
public string? Username { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
namespace Knots.DTO.User;
|
|
||||||
|
|
||||||
public class GetUserDetailsDto
|
|
||||||
{
|
|
||||||
public string? Username { get; set; }
|
|
||||||
public string? Description {get; set;}
|
|
||||||
public string? Password { get; set; }
|
|
||||||
public string? Email { get; set; }
|
|
||||||
public string? Tel { get; set; }
|
|
||||||
public string? ProfilePicture { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Knots.DTO.User;
|
|
||||||
|
|
||||||
public class GetUserDto
|
|
||||||
{
|
|
||||||
public string? Username { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
namespace Knots.DTO.User;
|
|
||||||
|
|
||||||
public class LoginResponseDto
|
|
||||||
{
|
|
||||||
public string? Token { get; set; }
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string? Username { get; set; }
|
|
||||||
public string? Email { get; set; }
|
|
||||||
public string? Tel { get; set; }
|
|
||||||
public string? ProfilePicture { get; set; }
|
|
||||||
public string? Description { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace Knots.DTO.User;
|
|
||||||
|
|
||||||
public class LoginUserDto
|
|
||||||
{
|
|
||||||
public string? Username { get; set; }
|
|
||||||
public string? Password { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
namespace Knots.DTO.User;
|
|
||||||
|
|
||||||
public class UpdateUserContactDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string? Email { get; set; }
|
|
||||||
public string? Tel { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace Knots.DTO.User;
|
|
||||||
|
|
||||||
public class UpdateUserDescriptionDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string? Description {get; set;}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
namespace Knots.DTO.User;
|
|
||||||
|
|
||||||
public class UpdateUserDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace Knots.DTO.User;
|
|
||||||
|
|
||||||
public class UpdateUserPasswordDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string? Password { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace Knots.DTO.User;
|
|
||||||
|
|
||||||
public class UpdateUserProfilePictureDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string? ProfilePicture { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace Knots.DTO.User;
|
|
||||||
|
|
||||||
public class UpdateUsernameDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string? Username { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Discussion;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Discussion;
|
|
||||||
|
|
||||||
public class CreateDiscussionEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<CreateDiscussionDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Post("/discussions");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(CreateDiscussionDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Discussion? discussion = mapper.Map<Models.Discussion>(req);
|
|
||||||
db.Discussions.Add(discussion);
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Discussion;
|
|
||||||
using Knots.Models;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using Knots.Services;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Discussion;
|
|
||||||
|
|
||||||
public class CreateGroupDiscussionEndpoint(KnotsDbContext db, EncryptionService encryption) : Endpoint<CreateGroupDiscussionRequest, GetDiscussionDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Post("/discussions/group");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(CreateGroupDiscussionRequest req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
int currentUserId = int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
|
|
||||||
|
|
||||||
if (req.Usernames == null || req.Usernames.Count == 0)
|
|
||||||
{
|
|
||||||
await SendErrorsAsync(400, ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Models.User> targets = await db.Users
|
|
||||||
.Where(u => req.Usernames.Contains(u.Username!))
|
|
||||||
.ToListAsync(ct);
|
|
||||||
|
|
||||||
if (targets.Count != req.Usernames.Count)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targets.Any(t => t.Id == currentUserId))
|
|
||||||
{
|
|
||||||
await SendErrorsAsync(400, ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int totalMembers = targets.Count + 1;
|
|
||||||
|
|
||||||
Models.Discussion discussion = new()
|
|
||||||
{
|
|
||||||
IsGroup = true,
|
|
||||||
Key = new Models.Key { EnKey = encryption.GenerateKey() },
|
|
||||||
UserDiscussions = targets
|
|
||||||
.Select(t => new UserDiscussion { UserId = t.Id })
|
|
||||||
.Append(new UserDiscussion { UserId = currentUserId })
|
|
||||||
.ToList()
|
|
||||||
};
|
|
||||||
|
|
||||||
db.Discussions.Add(discussion);
|
|
||||||
await db.SaveChangesAsync(ct); // discussion.Id disponible
|
|
||||||
|
|
||||||
|
|
||||||
Models.Group group = new()
|
|
||||||
{
|
|
||||||
Name = req.GroupName,
|
|
||||||
MembersAmount = totalMembers,
|
|
||||||
DiscussionId = discussion.Id,
|
|
||||||
GroupUsers = targets
|
|
||||||
.Select(t => new GroupUser { UserId = t.Id })
|
|
||||||
.Append(new GroupUser { UserId = currentUserId })
|
|
||||||
.ToList()
|
|
||||||
};
|
|
||||||
|
|
||||||
db.Groups.Add(group);
|
|
||||||
await db.SaveChangesAsync(ct); // group.Id disponible
|
|
||||||
|
|
||||||
|
|
||||||
discussion.GroupId = group.Id;
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
|
|
||||||
await SendOkAsync(new GetDiscussionDto
|
|
||||||
{
|
|
||||||
Id = discussion.Id,
|
|
||||||
IsGroup = true,
|
|
||||||
Name = group.Name,
|
|
||||||
MembersCount = totalMembers
|
|
||||||
}, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CreateGroupDiscussionRequest
|
|
||||||
{
|
|
||||||
public string GroupName { get; set; } = "";
|
|
||||||
public List<string> Usernames { get; set; } = [];
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Discussion;
|
|
||||||
using Knots.Models;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using Knots.Services;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Discussion;
|
|
||||||
|
|
||||||
public class CreatePrivateDiscussionEndpoint(KnotsDbContext db, EncryptionService encryption)
|
|
||||||
: Endpoint<CreatePrivateDiscussionRequest, GetDiscussionDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Post("/discussions/private");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(CreatePrivateDiscussionRequest req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
int currentUserId = int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
|
|
||||||
|
|
||||||
// 1. retrouver l'utilisateur cible par son nom
|
|
||||||
Models.User? target = await db.Users
|
|
||||||
.SingleOrDefaultAsync(u => u.Username == req.Username, ct);
|
|
||||||
|
|
||||||
if (target is null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct); // utilisateur introuvable
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target.Id == currentUserId)
|
|
||||||
{
|
|
||||||
await SendErrorsAsync(400, ct); // pas de discussion avec soi-même
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. vérifier qu'une discussion privée entre les deux n'existe pas déjà
|
|
||||||
Models.Discussion? existing = await db.Discussions
|
|
||||||
.Where(d => d.GroupId == null
|
|
||||||
&& d.UserDiscussions.Any(ud => ud.UserId == currentUserId)
|
|
||||||
&& d.UserDiscussions.Any(ud => ud.UserId == target.Id))
|
|
||||||
.FirstOrDefaultAsync(ct);
|
|
||||||
|
|
||||||
if (existing is not null)
|
|
||||||
{
|
|
||||||
await SendOkAsync(new GetDiscussionDto
|
|
||||||
{
|
|
||||||
Id = existing.Id,
|
|
||||||
IsGroup = false,
|
|
||||||
Name = target.Username!,
|
|
||||||
MembersCount = null
|
|
||||||
}, ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. créer la discussion + les deux participants
|
|
||||||
Models.Discussion discussion = new()
|
|
||||||
{
|
|
||||||
IsGroup = false,
|
|
||||||
Key = new Models.Key { EnKey = encryption.GenerateKey() },
|
|
||||||
UserDiscussions =
|
|
||||||
[
|
|
||||||
new UserDiscussion { UserId = currentUserId },
|
|
||||||
new UserDiscussion { UserId = target.Id }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
db.Discussions.Add(discussion);
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
|
|
||||||
await SendOkAsync(new GetDiscussionDto
|
|
||||||
{
|
|
||||||
Id = discussion.Id,
|
|
||||||
IsGroup = false,
|
|
||||||
Name = target.Username!,
|
|
||||||
MembersCount = null
|
|
||||||
}, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CreatePrivateDiscussionRequest
|
|
||||||
{
|
|
||||||
public string Username { get; set; } = "";
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Discussion;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Discussion;
|
|
||||||
|
|
||||||
public class DeleteDiscussionEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<DeleteDiscussionDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Delete("/discussions");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(DeleteDiscussionDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Discussion? discussion = mapper.Map<Models.Discussion>(req);
|
|
||||||
db.Discussions.Remove(discussion);
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using Knots.DTO.Discussion;
|
|
||||||
using Knots.DTO.Key;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using FastEndpoints;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Discussion;
|
|
||||||
|
|
||||||
public class GetDiscussionEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<GetDiscussionDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Get("/discussions");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(GetDiscussionDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Discussion? databaseDiscussion = await db.Discussions.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (databaseDiscussion == null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var keyDto = mapper.Map<GetKeyDetailsDto>(databaseDiscussion);
|
|
||||||
await SendOkAsync(keyDto, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
using System.Security.Claims;
|
|
||||||
using FastEndpoints;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Discussion;
|
|
||||||
|
|
||||||
public class GetDiscussionMembersEndpoint(KnotsDbContext db) : EndpointWithoutRequest<List<string>>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Get("/discussions/{discussionId}/members");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(CancellationToken ct)
|
|
||||||
{
|
|
||||||
int discussionId = Route<int>("discussionId");
|
|
||||||
|
|
||||||
Models.Discussion? discussion = await db.Discussions
|
|
||||||
.Include(d => d.UserDiscussions)
|
|
||||||
.ThenInclude(ud => ud.User)
|
|
||||||
.SingleOrDefaultAsync(d => d.Id == discussionId, ct);
|
|
||||||
|
|
||||||
if (discussion is null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<string> members = discussion.UserDiscussions
|
|
||||||
.Select(ud => ud.User.Username!)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
await SendOkAsync(members, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Discussion;
|
|
||||||
|
|
||||||
public class GetDiscussionMembersWithRolesEndpoint(KnotsDbContext db) : EndpointWithoutRequest<List<MemberWithRoleDto>>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Get("/discussions/{discussionId}/members/roles");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(CancellationToken ct)
|
|
||||||
{
|
|
||||||
int discussionId = Route<int>("discussionId");
|
|
||||||
|
|
||||||
Models.Discussion? discussion = await db.Discussions
|
|
||||||
.Include(d => d.Group)
|
|
||||||
.ThenInclude(g => g!.GroupUsers)
|
|
||||||
.ThenInclude(gu => gu.User)
|
|
||||||
.Include(d => d.Group)
|
|
||||||
.ThenInclude(g => g!.GroupUsers)
|
|
||||||
.ThenInclude(gu => gu.Role)
|
|
||||||
.SingleOrDefaultAsync(d => d.Id == discussionId, ct);
|
|
||||||
|
|
||||||
if (discussion?.Group is null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<MemberWithRoleDto> members = discussion.Group.GroupUsers
|
|
||||||
.Select(gu => new MemberWithRoleDto
|
|
||||||
{
|
|
||||||
UserId = gu.UserId,
|
|
||||||
Username = gu.User.Username!,
|
|
||||||
RoleId = gu.RoleId,
|
|
||||||
RoleLibelle = gu.Role?.Libelle
|
|
||||||
})
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
await SendOkAsync(members, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MemberWithRoleDto
|
|
||||||
{
|
|
||||||
public int UserId { get; set; }
|
|
||||||
public string Username { get; set; } = "";
|
|
||||||
public int? RoleId { get; set; }
|
|
||||||
public string? RoleLibelle { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
using System.Security.Claims;
|
|
||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Discussion;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Discussion;
|
|
||||||
|
|
||||||
public class GetMyDiscussionEndpoint(KnotsDbContext db) : EndpointWithoutRequest<List<GetDiscussionDto>>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Get("/discussions/my");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(CancellationToken ct)
|
|
||||||
{
|
|
||||||
int userId = int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
|
|
||||||
|
|
||||||
// Discussions privées : l'utilisateur est l'un des participants
|
|
||||||
IQueryable<GetDiscussionDto> privees = db.Discussions
|
|
||||||
.Where(d => d.GroupId == null && d.UserDiscussions.Any(ud => ud.UserId == userId))
|
|
||||||
.Select(d => new GetDiscussionDto
|
|
||||||
{
|
|
||||||
Id = d.Id,
|
|
||||||
IsGroup = false,
|
|
||||||
Name = d.UserDiscussions
|
|
||||||
.Where(ud => ud.UserId != userId)
|
|
||||||
.Select(ud => ud.User.Username)
|
|
||||||
.FirstOrDefault() ?? "",
|
|
||||||
MembersCount = null,
|
|
||||||
GroupId = null
|
|
||||||
});
|
|
||||||
|
|
||||||
// Discussions de groupe : l'utilisateur est membre du groupe
|
|
||||||
IQueryable<GetDiscussionDto> groupes = db.Discussions
|
|
||||||
.Where(d => d.Group != null && d.Group.GroupUsers.Any(gu => gu.UserId == userId))
|
|
||||||
.Select(d => new GetDiscussionDto
|
|
||||||
{
|
|
||||||
Id = d.Id,
|
|
||||||
IsGroup = true,
|
|
||||||
Name = d.Group!.Name!,
|
|
||||||
MembersCount = d.Group.MembersAmount,
|
|
||||||
GroupId = d.Group.Id
|
|
||||||
});
|
|
||||||
|
|
||||||
List<GetDiscussionDto> discussions = await privees.Concat(groupes).ToListAsync(ct);
|
|
||||||
|
|
||||||
await SendOkAsync(discussions, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using Knots.DTO.Group;
|
|
||||||
using FastEndpoints;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Group;
|
|
||||||
|
|
||||||
public class CreateGroupEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<CreateGroupDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Post("/groups");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(CreateGroupDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Group? group = mapper.Map<Models.Group>(req);
|
|
||||||
db.Groups.Add(group);
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Group;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Group;
|
|
||||||
|
|
||||||
public class DeleteGroupEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<DeleteGroupDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Delete("/groups");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(DeleteGroupDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Group? group = mapper.Map<Models.Group>(req);
|
|
||||||
db.Groups.Remove(group);
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Group;
|
|
||||||
using Knots.DTO.Key;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Group;
|
|
||||||
|
|
||||||
public class GetGroupEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<GetGroupDetailsDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Get("/groups");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(GetGroupDetailsDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Group? databaseGroup = await db.Groups.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (databaseGroup == null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var keyDto = mapper.Map<GetKeyDetailsDto>(databaseGroup);
|
|
||||||
await SendOkAsync(keyDto, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Group;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Group;
|
|
||||||
|
|
||||||
public class PatchGroupMembersAmountEndpoint(KnotsDbContext knotsDbContext) : Endpoint<UpdateGroupMembersAmountDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Patch("/groups/{@Id}/membersAmount/", x => new {x.Id});
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(UpdateGroupMembersAmountDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Group? databaseGroup = await knotsDbContext.Groups.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (databaseGroup is null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
databaseGroup.MembersAmount = req.MembersAmount;
|
|
||||||
await knotsDbContext.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Group;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Group;
|
|
||||||
|
|
||||||
public class PatchGroupNameEndpoint(KnotsDbContext knotsDbContext) : Endpoint<UpdateGroupNameDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Patch("/groups/{@Id}/name/", x => new {x.Id});
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(UpdateGroupNameDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Group? databaseGroup = await knotsDbContext.Groups.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (databaseGroup is null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
databaseGroup.Name = req.Name;
|
|
||||||
await knotsDbContext.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Group;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Group;
|
|
||||||
|
|
||||||
public class PatchGroupProfilePictureEndpoint(KnotsDbContext knotsDbContext) : Endpoint<UpdateGroupProfilePictureDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Patch("/groups/{@Id}/profilePicture/", x => new {x.Id});
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(UpdateGroupProfilePictureDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Group? databaseGroup = await knotsDbContext.Groups.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (databaseGroup is null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
databaseGroup.ProfilePicture = req.ProfilePicture;
|
|
||||||
await knotsDbContext.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using Knots.DTO.Key;
|
|
||||||
using FastEndpoints;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Key;
|
|
||||||
|
|
||||||
public class CreateKeyEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<CreateKeyDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Post("/keys");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(CreateKeyDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Key? key = mapper.Map<Models.Key>(req);
|
|
||||||
db.Keys.Add(key);
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Key;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Key;
|
|
||||||
|
|
||||||
public class DeleteKeyEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<DeleteKeyDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Delete("/keys");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(DeleteKeyDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Key? key = mapper.Map<Models.Key>(req);
|
|
||||||
db.Keys.Remove(key);
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Key;
|
|
||||||
using Knots.DTO.User;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Key;
|
|
||||||
|
|
||||||
public class GetKeyEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint <GetKeyDetailsDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Get("/keys/{@Id}");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(GetKeyDetailsDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Key? databaseKey = await db.Keys.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (databaseKey == null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var keyDto = mapper.Map<GetKeyDetailsDto>(databaseKey);
|
|
||||||
await SendOkAsync(keyDto, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Message;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Message;
|
|
||||||
|
|
||||||
public class CreateMessageEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<CreateMessageDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Post("/messages");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(CreateMessageDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Message? message = mapper.Map<Models.Message>(req);
|
|
||||||
db.Messages.Add(message);
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Message;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Message;
|
|
||||||
|
|
||||||
public class DeleteMessageEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<DeleteMessageDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Delete("/messages");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(DeleteMessageDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Message? message = mapper.Map<Models.Message>(req);
|
|
||||||
db.Messages.Remove(message);
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
using System.Security.Claims;
|
|
||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Message;
|
|
||||||
using Knots.DTO.User;
|
|
||||||
using Knots.Services;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Message;
|
|
||||||
|
|
||||||
public class GetMessageEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper, EncryptionService encryption) : Endpoint<GetDiscussionMessagesRequest, List<GetMessageDetailsDto>>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Get("/discussions/{DiscussionId}/messages");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(GetDiscussionMessagesRequest req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
int userId = int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
|
|
||||||
|
|
||||||
// l'utilisateur participe-t-il à cette discussion (privée ou via le groupe) ?
|
|
||||||
bool autorise = await db.Discussions
|
|
||||||
.Where(d => d.Id == req.DiscussionId)
|
|
||||||
.AnyAsync(d =>
|
|
||||||
d.UserDiscussions.Any(ud => ud.UserId == userId) ||
|
|
||||||
(d.Group != null && d.Group.GroupUsers.Any(gu => gu.UserId == userId)), ct);
|
|
||||||
|
|
||||||
if (!autorise)
|
|
||||||
{
|
|
||||||
await SendForbiddenAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string? key = await db.Discussions
|
|
||||||
.Where(d => d.Id == req.DiscussionId)
|
|
||||||
.Select(d => d.Key!.EnKey)
|
|
||||||
.SingleAsync(ct);
|
|
||||||
|
|
||||||
var rows = await db.Messages
|
|
||||||
.Where(m => m.DiscussionId == req.DiscussionId)
|
|
||||||
.OrderBy(m => m.Date)
|
|
||||||
.Select(m => new { m.Id, m.Contenu, m.Date, m.UserId, AuthorName = m.User.Username! })
|
|
||||||
.ToListAsync(ct);
|
|
||||||
|
|
||||||
List<GetMessageDetailsDto> messages = rows.Select(m => new GetMessageDetailsDto
|
|
||||||
{
|
|
||||||
Id = m.Id,
|
|
||||||
Contenu = encryption.Decrypt(m.Contenu!, key!),
|
|
||||||
Date = m.Date,
|
|
||||||
UserId = m.UserId,
|
|
||||||
AuthorName = m.AuthorName
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
await SendOkAsync(messages, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GetDiscussionMessagesRequest
|
|
||||||
{
|
|
||||||
public int DiscussionId { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.Models;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Role;
|
|
||||||
|
|
||||||
public class AssignRoleEndpoint(KnotsDbContext db) : Endpoint<AssignRoleRequest>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Post("/groups/{groupId}/members/{userId}/role");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(AssignRoleRequest req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
int groupId = Route<int>("groupId");
|
|
||||||
int userId = Route<int>("userId");
|
|
||||||
|
|
||||||
GroupUser? groupUser = await db.GroupUsers
|
|
||||||
.SingleOrDefaultAsync(gu => gu.GroupId == groupId && gu.UserId == userId, ct);
|
|
||||||
|
|
||||||
if (groupUser is null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool roleExists = await db.Roles.AnyAsync(r => r.Id == req.RoleId, ct);
|
|
||||||
if (!roleExists)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
groupUser.RoleId = req.RoleId;
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
|
|
||||||
await SendOkAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AssignRoleRequest
|
|
||||||
{
|
|
||||||
public int RoleId { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.Models;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Role;
|
|
||||||
|
|
||||||
public class CreateRoleEndpoint(KnotsDbContext db) : Endpoint<CreateRoleRequest, RoleDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Post("/roles");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(CreateRoleRequest req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Role role = new() { Libelle = req.Libelle };
|
|
||||||
db.Roles.Add(role);
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
|
|
||||||
await SendOkAsync(new RoleDto { Id = role.Id, Libelle = role.Libelle! }, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CreateRoleRequest
|
|
||||||
{
|
|
||||||
public string Libelle { get; set; } = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RoleDto
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public string Libelle { get; set; } = "";
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Role;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Role;
|
|
||||||
|
|
||||||
public class DeleteRoleEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<DeleteRoleDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Delete("/roles");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(DeleteRoleDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Role? role = mapper.Map<Models.Role>(req);
|
|
||||||
db.Roles.Remove(role);
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.Role;
|
|
||||||
using Knots.DTO.User;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.Role;
|
|
||||||
|
|
||||||
public class GetRoleEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint <GetRoleDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Get ("/roles/{@Id}", x => new { x.Libelle });
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(GetRoleDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.Role? databaseRole = await db.Roles.SingleOrDefaultAsync(x => x.Libelle == req.Libelle, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (databaseRole == null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var roleDto = mapper.Map<GetRoleDto>(databaseRole);
|
|
||||||
await SendOkAsync(roleDto, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.User;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.User;
|
|
||||||
|
|
||||||
public class CreateUserEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<CreateUserDto, GetUserDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Post("/users");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(CreateUserDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
bool usernameExists = await db.Users
|
|
||||||
.AnyAsync(x => x.Username == req.Username, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (usernameExists)
|
|
||||||
{
|
|
||||||
AddError(x => x.Username, "Ce nom d'utilisateur est déjà pris.");
|
|
||||||
await SendErrorsAsync(cancellation: ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Password = BCrypt.Net.BCrypt.HashPassword(req.Password);
|
|
||||||
Models.User? user = mapper.Map<Models.User>(req);
|
|
||||||
db.Users.Add(user);
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.User;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.User;
|
|
||||||
|
|
||||||
public class DeleteUserEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint <DeleteUserDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Delete ("/users/{@Id}");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(DeleteUserDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.User? user = mapper.Map<Models.User>(req);
|
|
||||||
db.Users.Add(user);
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
using AutoMapper.QueryableExtensions;
|
|
||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.User;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.User;
|
|
||||||
|
|
||||||
public class GetAllUsersEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : EndpointWithoutRequest<List<GetUserDetailsDto>>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Get ("/users");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(CancellationToken ct)
|
|
||||||
{
|
|
||||||
var users = await db.Users
|
|
||||||
.ProjectTo<GetUserDetailsDto>(mapper.ConfigurationProvider)
|
|
||||||
.ToListAsync(ct);
|
|
||||||
|
|
||||||
await SendOkAsync(users, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.User;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.User;
|
|
||||||
|
|
||||||
public class GetUserEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint <GetUserDetailsDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Get ("/users/{@Id}", x => new { x.Username });
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(GetUserDetailsDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.User? databaseUser = await db.Users.SingleOrDefaultAsync(x => x.Username == req.Username, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (databaseUser == null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var userDto = mapper.Map<GetUserDetailsDto>(databaseUser);
|
|
||||||
await SendOkAsync(userDto, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.User;
|
|
||||||
using Knots.Services;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.User;
|
|
||||||
|
|
||||||
public class LoginEndpoint(KnotsDbContext db, JwtService jwtService) : Endpoint<LoginUserDto, LoginResponseDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Post("/users/login");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(LoginUserDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.User? user = await db.Users
|
|
||||||
.SingleOrDefaultAsync(x => x.Username == req.Username, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (user is null || !BCrypt.Net.BCrypt.Verify(req.Password, user.Password)) // hash à ajouter plus tard
|
|
||||||
{
|
|
||||||
await SendUnauthorizedAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string token = jwtService.GenerateToken(user);
|
|
||||||
|
|
||||||
await SendOkAsync(new LoginResponseDto
|
|
||||||
{
|
|
||||||
Token = token,
|
|
||||||
Id = user.Id,
|
|
||||||
Username = user.Username!,
|
|
||||||
Email = user.Email,
|
|
||||||
Tel = user.Tel,
|
|
||||||
ProfilePicture = user.ProfilePicture,
|
|
||||||
Description = user.Description
|
|
||||||
}, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.User;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.User;
|
|
||||||
|
|
||||||
public class PatchUserContactEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<UpdateUserContactDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Patch("/users/{@Id}/contact/", x => new {x.Id});
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(UpdateUserContactDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.User? databaseUser = await db.Users.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (databaseUser is null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (databaseUser.Email != req.Email)
|
|
||||||
{
|
|
||||||
databaseUser.Email = req.Email;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
databaseUser.Email = databaseUser.Email;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (databaseUser.Tel != req.Tel)
|
|
||||||
{
|
|
||||||
databaseUser.Tel = req.Tel;
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
databaseUser.Tel = databaseUser.Tel;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapper.Map(req, databaseUser);
|
|
||||||
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.User;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.User;
|
|
||||||
|
|
||||||
public class PatchUserDescriptionEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<UpdateUserDescriptionDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Patch("/users/{@Id}/description/");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(UpdateUserDescriptionDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.User? databaseUser = await db.Users.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (databaseUser is null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapper.Map(req, databaseUser);
|
|
||||||
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.User;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.User;
|
|
||||||
|
|
||||||
public class PatchUserPasswordEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<UpdateUserPasswordDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Patch("/users/{@Id}/password/", x => new {x.Id});
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(UpdateUserPasswordDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.User? databaseUser = await db.Users.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (databaseUser is null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapper.Map(req, databaseUser);
|
|
||||||
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.User;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.User;
|
|
||||||
|
|
||||||
public class PatchUserProfilePictureEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<UpdateUserProfilePictureDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Patch("/users/{@Id}/profilepicture/");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(UpdateUserProfilePictureDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.User? databaseUser = await db.Users.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (databaseUser is null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapper.Map(req, databaseUser);
|
|
||||||
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using Knots.DTO.User;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Endpoints.User;
|
|
||||||
|
|
||||||
|
|
||||||
public class PatchUsernameEndpoint(KnotsDbContext db, AutoMapper.IMapper mapper) : Endpoint<UpdateUsernameDto>
|
|
||||||
{
|
|
||||||
public override void Configure()
|
|
||||||
{
|
|
||||||
Patch("/users/{@Id}/username/");
|
|
||||||
AllowAnonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task HandleAsync(UpdateUsernameDto req, CancellationToken ct)
|
|
||||||
{
|
|
||||||
Models.User? databaseUser = await db.Users.SingleOrDefaultAsync(x => x.Id == req.Id, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (databaseUser is null)
|
|
||||||
{
|
|
||||||
await SendNotFoundAsync(ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool usernameExists = await db.Users
|
|
||||||
.AnyAsync(x => x.Username == req.Username && x.Id != req.Id, cancellationToken: ct);
|
|
||||||
|
|
||||||
if (usernameExists)
|
|
||||||
{
|
|
||||||
AddError(x => x.Username, "Ce nom d'utilisateur est déjà pris.");
|
|
||||||
await SendErrorsAsync(cancellation: ct);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapper.Map(req, databaseUser);
|
|
||||||
|
|
||||||
await db.SaveChangesAsync(ct);
|
|
||||||
await SendNoContentAsync(ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
using Knots.Services;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.SignalR;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots.Hubs;
|
|
||||||
|
|
||||||
[Authorize]
|
|
||||||
public class ChatHub(KnotsDbContext db, AutoMapper.IMapper mapper, EncryptionService encryption) : Hub
|
|
||||||
{
|
|
||||||
// Rejoindre une conversation (room)
|
|
||||||
public async Task JoinConversation(string discussionId)
|
|
||||||
{
|
|
||||||
await Groups.AddToGroupAsync(Context.ConnectionId, discussionId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quitter une conversation
|
|
||||||
public async Task LeaveConversation(string discussionId)
|
|
||||||
{
|
|
||||||
await Groups.RemoveFromGroupAsync(Context.ConnectionId, discussionId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Envoyer un message à une conversation
|
|
||||||
public async Task SendMessage(string discussionId, string content)
|
|
||||||
{
|
|
||||||
int id = int.Parse(discussionId);
|
|
||||||
|
|
||||||
Models.Discussion discussion = await db.Discussions
|
|
||||||
.Include(d => d.Key)
|
|
||||||
.SingleAsync(d => d.Id == id);
|
|
||||||
|
|
||||||
var message = new Models.Message
|
|
||||||
{
|
|
||||||
Contenu = encryption.Encrypt(content, discussion.Key!.EnKey!), // chiffré en base
|
|
||||||
Date = DateTime.UtcNow,
|
|
||||||
Type = false,
|
|
||||||
UserId = int.Parse(Context.UserIdentifier!),
|
|
||||||
DiscussionId = id
|
|
||||||
};
|
|
||||||
|
|
||||||
db.Messages.Add(message);
|
|
||||||
await db.SaveChangesAsync();
|
|
||||||
|
|
||||||
// diffusion en clair, avec les noms de champs attendus par le front
|
|
||||||
await Clients.Group(discussionId).SendAsync("ReceiveMessage", new
|
|
||||||
{
|
|
||||||
id = message.Id,
|
|
||||||
contenu = content,
|
|
||||||
date = message.Date,
|
|
||||||
userId = message.UserId
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notifier que l'utilisateur est en train d'écrire
|
|
||||||
public async Task Typing(string discussionId)
|
|
||||||
{
|
|
||||||
await Clients.OthersInGroup(discussionId)
|
|
||||||
.SendAsync("UserTyping", Context.UserIdentifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+4
-17
@@ -1,32 +1,19 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AutoMapper" Version="16.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.8"/>
|
||||||
<PackageReference Include="BCrypt.Net-Next" Version="4.2.0" />
|
|
||||||
<PackageReference Include="FastEndpoints" Version="5.33.0" />
|
|
||||||
<PackageReference Include="FastEndpoints.Swagger" Version="5.33.0" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.3.11" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.28" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.25" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.2.11" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.25" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.25">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.25" />
|
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.7" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Folder Include="DTO\" />
|
||||||
<Folder Include="Endpoints\" />
|
<Folder Include="Endpoints\" />
|
||||||
<Folder Include="Migrations\" />
|
<Folder Include="Validators\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
using Knots.Models;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace Knots;
|
|
||||||
|
|
||||||
public class KnotsDbContext : DbContext
|
|
||||||
{
|
|
||||||
public DbSet<User> Users => Set<User>();
|
|
||||||
public DbSet<Discussion> Discussions => Set<Discussion>();
|
|
||||||
public DbSet<Group> Groups => Set<Group>();
|
|
||||||
public DbSet<Message> Messages => Set<Message>();
|
|
||||||
public DbSet<Role> Roles => Set<Role>();
|
|
||||||
public DbSet<Key> Keys => Set<Key>();
|
|
||||||
public DbSet<UserDiscussion> UserDiscussions => Set<UserDiscussion>();
|
|
||||||
public DbSet<GroupUser> GroupUsers => Set<GroupUser>();
|
|
||||||
|
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
|
||||||
{
|
|
||||||
//Infos de connexion à la base de données
|
|
||||||
string connectionString =
|
|
||||||
"Server=romaric-thibault.fr;" +
|
|
||||||
"Database=knots;" +
|
|
||||||
"User Id=knots;" +
|
|
||||||
"Password=knots;" +
|
|
||||||
"TrustServerCertificate=true;";
|
|
||||||
|
|
||||||
optionsBuilder.UseSqlServer(connectionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
modelBuilder.Entity<GroupUser>()
|
|
||||||
.HasKey(gu => new { gu.GroupId, gu.UserId });
|
|
||||||
|
|
||||||
modelBuilder.Entity<GroupUser>()
|
|
||||||
.HasOne(gu => gu.Group)
|
|
||||||
.WithMany(g => g.GroupUsers)
|
|
||||||
.HasForeignKey(gu => gu.GroupId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.Entity<GroupUser>()
|
|
||||||
.HasOne(gu => gu.User)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(gu => gu.UserId)
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
modelBuilder.Entity<GroupUser>()
|
|
||||||
.HasOne(gu => gu.Role)
|
|
||||||
.WithMany(r => r.GroupUsers)
|
|
||||||
.HasForeignKey(gu => gu.RoleId);
|
|
||||||
|
|
||||||
modelBuilder.Entity<Discussion>()
|
|
||||||
.HasOne(d => d.Group)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(d => d.GroupId)
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
modelBuilder.Entity<Group>()
|
|
||||||
.HasOne(g => g.Discussion)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(g => g.DiscussionId)
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
modelBuilder.Entity<UserDiscussion>()
|
|
||||||
.HasKey(ud => new { ud.UserId, ud.DiscussionId });
|
|
||||||
|
|
||||||
modelBuilder.Entity<UserDiscussion>()
|
|
||||||
.HasOne(ud => ud.Discussion)
|
|
||||||
.WithMany(d => d.UserDiscussions)
|
|
||||||
.HasForeignKey(ud => ud.DiscussionId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.Entity<UserDiscussion>()
|
|
||||||
.HasOne(ud => ud.User)
|
|
||||||
.WithMany(u => u.UserDiscussions)
|
|
||||||
.HasForeignKey(ud => ud.UserId)
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,232 +0,0 @@
|
|||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using Knots;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace Knots.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(KnotsDbContext))]
|
|
||||||
[Migration("20260505083044_InitialDatabase")]
|
|
||||||
partial class InitialDatabase
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "8.0.25")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Discussion", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("KeyId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Discussions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Group", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("KeyId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("MembersAmount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.Property<string>("ProfilePicture")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Groups");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Key", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("EnKey")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Keys");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Message", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Contenu")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1000)
|
|
||||||
.HasColumnType("nvarchar(1000)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("Date")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<int?>("DiscussionId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("GroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("KeyId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<bool>("Type")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int>("UserId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DiscussionId");
|
|
||||||
|
|
||||||
b.HasIndex("GroupId");
|
|
||||||
|
|
||||||
b.HasIndex("KeyId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("Messages");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Role", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Libelle")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Roles");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.User", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasMaxLength(200)
|
|
||||||
.HasColumnType("nvarchar(200)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(70)
|
|
||||||
.HasColumnType("nvarchar(70)");
|
|
||||||
|
|
||||||
b.Property<string>("Password")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ProfilePicture")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Tel")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Username")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Users");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Message", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Discussion", null)
|
|
||||||
.WithMany("Messages")
|
|
||||||
.HasForeignKey("DiscussionId");
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.Group", "Group")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("GroupId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.Key", "Key")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("KeyId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.User", "User")
|
|
||||||
.WithMany("Messages")
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Group");
|
|
||||||
|
|
||||||
b.Navigation("Key");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Discussion", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Messages");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.User", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Messages");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,172 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace Knots.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class InitialDatabase : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "Discussions",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
|
||||||
.Annotation("SqlServer:Identity", "1, 1"),
|
|
||||||
KeyId = table.Column<int>(type: "int", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_Discussions", x => x.Id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "Groups",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
|
||||||
.Annotation("SqlServer:Identity", "1, 1"),
|
|
||||||
Name = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
|
|
||||||
MembersAmount = table.Column<int>(type: "int", nullable: false),
|
|
||||||
ProfilePicture = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
|
||||||
KeyId = table.Column<int>(type: "int", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_Groups", x => x.Id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "Keys",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
|
||||||
.Annotation("SqlServer:Identity", "1, 1"),
|
|
||||||
EnKey = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_Keys", x => x.Id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "Roles",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
|
||||||
.Annotation("SqlServer:Identity", "1, 1"),
|
|
||||||
Libelle = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_Roles", x => x.Id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "Users",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
|
||||||
.Annotation("SqlServer:Identity", "1, 1"),
|
|
||||||
Username = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
|
|
||||||
Description = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: true),
|
|
||||||
Password = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
|
||||||
Email = table.Column<string>(type: "nvarchar(70)", maxLength: 70, nullable: false),
|
|
||||||
Tel = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
|
||||||
ProfilePicture = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_Users", x => x.Id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "Messages",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
|
||||||
.Annotation("SqlServer:Identity", "1, 1"),
|
|
||||||
Contenu = table.Column<string>(type: "nvarchar(1000)", maxLength: 1000, nullable: false),
|
|
||||||
Date = table.Column<DateTime>(type: "datetime2", nullable: false),
|
|
||||||
Type = table.Column<bool>(type: "bit", nullable: false),
|
|
||||||
GroupId = table.Column<int>(type: "int", nullable: false),
|
|
||||||
KeyId = table.Column<int>(type: "int", nullable: false),
|
|
||||||
UserId = table.Column<int>(type: "int", nullable: false),
|
|
||||||
DiscussionId = table.Column<int>(type: "int", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_Messages", x => x.Id);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "FK_Messages_Discussions_DiscussionId",
|
|
||||||
column: x => x.DiscussionId,
|
|
||||||
principalTable: "Discussions",
|
|
||||||
principalColumn: "Id");
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "FK_Messages_Groups_GroupId",
|
|
||||||
column: x => x.GroupId,
|
|
||||||
principalTable: "Groups",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "FK_Messages_Keys_KeyId",
|
|
||||||
column: x => x.KeyId,
|
|
||||||
principalTable: "Keys",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "FK_Messages_Users_UserId",
|
|
||||||
column: x => x.UserId,
|
|
||||||
principalTable: "Users",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_Messages_DiscussionId",
|
|
||||||
table: "Messages",
|
|
||||||
column: "DiscussionId");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_Messages_GroupId",
|
|
||||||
table: "Messages",
|
|
||||||
column: "GroupId");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_Messages_KeyId",
|
|
||||||
table: "Messages",
|
|
||||||
column: "KeyId");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_Messages_UserId",
|
|
||||||
table: "Messages",
|
|
||||||
column: "UserId");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "Messages");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "Roles");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "Discussions");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "Groups");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "Keys");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "Users");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,316 +0,0 @@
|
|||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using Knots;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace Knots.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(KnotsDbContext))]
|
|
||||||
[Migration("20260610135459_AddRoleIdToUser")]
|
|
||||||
partial class AddRoleIdToUser
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "8.0.25")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Discussion", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<bool>("IsGroup")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Discussions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Group", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("DiscussionId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("KeyId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("MembersAmount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.Property<string>("ProfilePicture")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DiscussionId")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("Groups");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Key", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("EnKey")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Keys");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Message", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Contenu")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1000)
|
|
||||||
.HasColumnType("nvarchar(1000)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("Date")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<int>("DiscussionId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("GroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("KeyId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<bool>("Type")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int>("UserId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DiscussionId");
|
|
||||||
|
|
||||||
b.HasIndex("GroupId");
|
|
||||||
|
|
||||||
b.HasIndex("KeyId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("Messages");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Role", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Libelle")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Roles");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.User", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasMaxLength(200)
|
|
||||||
.HasColumnType("nvarchar(200)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(70)
|
|
||||||
.HasColumnType("nvarchar(70)");
|
|
||||||
|
|
||||||
b.Property<string>("Password")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ProfilePicture")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int?>("RoleId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Tel")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Username")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("Users");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.UserDiscussion", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("UserId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("DiscussionId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "DiscussionId");
|
|
||||||
|
|
||||||
b.HasIndex("DiscussionId");
|
|
||||||
|
|
||||||
b.ToTable("UserDiscussions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Group", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Discussion", "Discussion")
|
|
||||||
.WithOne("Group")
|
|
||||||
.HasForeignKey("Knots.Models.Group", "DiscussionId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Discussion");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Message", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Discussion", "Discussion")
|
|
||||||
.WithMany("Messages")
|
|
||||||
.HasForeignKey("DiscussionId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.Group", "Group")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("GroupId");
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.Key", "Key")
|
|
||||||
.WithMany("Messages")
|
|
||||||
.HasForeignKey("KeyId");
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.User", "User")
|
|
||||||
.WithMany("Messages")
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Discussion");
|
|
||||||
|
|
||||||
b.Navigation("Group");
|
|
||||||
|
|
||||||
b.Navigation("Key");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.User", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Role", "Role")
|
|
||||||
.WithMany("Users")
|
|
||||||
.HasForeignKey("RoleId");
|
|
||||||
|
|
||||||
b.Navigation("Role");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.UserDiscussion", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Discussion", "Discussion")
|
|
||||||
.WithMany("UserDiscussions")
|
|
||||||
.HasForeignKey("DiscussionId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.User", "User")
|
|
||||||
.WithMany("UserDiscussions")
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Discussion");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Discussion", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Group");
|
|
||||||
|
|
||||||
b.Navigation("Messages");
|
|
||||||
|
|
||||||
b.Navigation("UserDiscussions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Key", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Messages");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Role", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Users");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.User", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Messages");
|
|
||||||
|
|
||||||
b.Navigation("UserDiscussions");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,270 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace Knots.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class AddRoleIdToUser : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_Messages_Discussions_DiscussionId",
|
|
||||||
table: "Messages");
|
|
||||||
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_Messages_Groups_GroupId",
|
|
||||||
table: "Messages");
|
|
||||||
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_Messages_Keys_KeyId",
|
|
||||||
table: "Messages");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "KeyId",
|
|
||||||
table: "Discussions");
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "RoleId",
|
|
||||||
table: "Users",
|
|
||||||
type: "int",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<int>(
|
|
||||||
name: "KeyId",
|
|
||||||
table: "Messages",
|
|
||||||
type: "int",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(int),
|
|
||||||
oldType: "int");
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<int>(
|
|
||||||
name: "GroupId",
|
|
||||||
table: "Messages",
|
|
||||||
type: "int",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(int),
|
|
||||||
oldType: "int");
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<int>(
|
|
||||||
name: "DiscussionId",
|
|
||||||
table: "Messages",
|
|
||||||
type: "int",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0,
|
|
||||||
oldClrType: typeof(int),
|
|
||||||
oldType: "int",
|
|
||||||
oldNullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "DiscussionId",
|
|
||||||
table: "Groups",
|
|
||||||
type: "int",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<DateTime>(
|
|
||||||
name: "CreatedAt",
|
|
||||||
table: "Discussions",
|
|
||||||
type: "datetime2",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "IsGroup",
|
|
||||||
table: "Discussions",
|
|
||||||
type: "bit",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "UserDiscussions",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
UserId = table.Column<int>(type: "int", nullable: false),
|
|
||||||
DiscussionId = table.Column<int>(type: "int", nullable: false)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_UserDiscussions", x => new { x.UserId, x.DiscussionId });
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "FK_UserDiscussions_Discussions_DiscussionId",
|
|
||||||
column: x => x.DiscussionId,
|
|
||||||
principalTable: "Discussions",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
table.ForeignKey(
|
|
||||||
name: "FK_UserDiscussions_Users_UserId",
|
|
||||||
column: x => x.UserId,
|
|
||||||
principalTable: "Users",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_Users_RoleId",
|
|
||||||
table: "Users",
|
|
||||||
column: "RoleId");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_Groups_DiscussionId",
|
|
||||||
table: "Groups",
|
|
||||||
column: "DiscussionId",
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_UserDiscussions_DiscussionId",
|
|
||||||
table: "UserDiscussions",
|
|
||||||
column: "DiscussionId");
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_Groups_Discussions_DiscussionId",
|
|
||||||
table: "Groups",
|
|
||||||
column: "DiscussionId",
|
|
||||||
principalTable: "Discussions",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_Messages_Discussions_DiscussionId",
|
|
||||||
table: "Messages",
|
|
||||||
column: "DiscussionId",
|
|
||||||
principalTable: "Discussions",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_Messages_Groups_GroupId",
|
|
||||||
table: "Messages",
|
|
||||||
column: "GroupId",
|
|
||||||
principalTable: "Groups",
|
|
||||||
principalColumn: "Id");
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_Messages_Keys_KeyId",
|
|
||||||
table: "Messages",
|
|
||||||
column: "KeyId",
|
|
||||||
principalTable: "Keys",
|
|
||||||
principalColumn: "Id");
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_Users_Roles_RoleId",
|
|
||||||
table: "Users",
|
|
||||||
column: "RoleId",
|
|
||||||
principalTable: "Roles",
|
|
||||||
principalColumn: "Id");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_Groups_Discussions_DiscussionId",
|
|
||||||
table: "Groups");
|
|
||||||
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_Messages_Discussions_DiscussionId",
|
|
||||||
table: "Messages");
|
|
||||||
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_Messages_Groups_GroupId",
|
|
||||||
table: "Messages");
|
|
||||||
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_Messages_Keys_KeyId",
|
|
||||||
table: "Messages");
|
|
||||||
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_Users_Roles_RoleId",
|
|
||||||
table: "Users");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "UserDiscussions");
|
|
||||||
|
|
||||||
migrationBuilder.DropIndex(
|
|
||||||
name: "IX_Users_RoleId",
|
|
||||||
table: "Users");
|
|
||||||
|
|
||||||
migrationBuilder.DropIndex(
|
|
||||||
name: "IX_Groups_DiscussionId",
|
|
||||||
table: "Groups");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "RoleId",
|
|
||||||
table: "Users");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "DiscussionId",
|
|
||||||
table: "Groups");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "CreatedAt",
|
|
||||||
table: "Discussions");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "IsGroup",
|
|
||||||
table: "Discussions");
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<int>(
|
|
||||||
name: "KeyId",
|
|
||||||
table: "Messages",
|
|
||||||
type: "int",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0,
|
|
||||||
oldClrType: typeof(int),
|
|
||||||
oldType: "int",
|
|
||||||
oldNullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<int>(
|
|
||||||
name: "GroupId",
|
|
||||||
table: "Messages",
|
|
||||||
type: "int",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0,
|
|
||||||
oldClrType: typeof(int),
|
|
||||||
oldType: "int",
|
|
||||||
oldNullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AlterColumn<int>(
|
|
||||||
name: "DiscussionId",
|
|
||||||
table: "Messages",
|
|
||||||
type: "int",
|
|
||||||
nullable: true,
|
|
||||||
oldClrType: typeof(int),
|
|
||||||
oldType: "int");
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "KeyId",
|
|
||||||
table: "Discussions",
|
|
||||||
type: "int",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0);
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_Messages_Discussions_DiscussionId",
|
|
||||||
table: "Messages",
|
|
||||||
column: "DiscussionId",
|
|
||||||
principalTable: "Discussions",
|
|
||||||
principalColumn: "Id");
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_Messages_Groups_GroupId",
|
|
||||||
table: "Messages",
|
|
||||||
column: "GroupId",
|
|
||||||
principalTable: "Groups",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_Messages_Keys_KeyId",
|
|
||||||
table: "Messages",
|
|
||||||
column: "KeyId",
|
|
||||||
principalTable: "Keys",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,380 +0,0 @@
|
|||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using Knots;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace Knots.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(KnotsDbContext))]
|
|
||||||
[Migration("20260610224937_FixGroupDiscussion")]
|
|
||||||
partial class FixGroupDiscussion
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "8.0.25")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Discussion", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<int?>("GroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<bool>("IsGroup")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("GroupId");
|
|
||||||
|
|
||||||
b.ToTable("Discussions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Group", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("DiscussionId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("MembersAmount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.Property<string>("ProfilePicture")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DiscussionId");
|
|
||||||
|
|
||||||
b.ToTable("Groups");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.GroupUser", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("GroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("UserId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("RoleId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("GroupId", "UserId");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("GroupUsers");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Key", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("EnKey")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Keys");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Message", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("AuthorId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Contenu")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1000)
|
|
||||||
.HasColumnType("nvarchar(1000)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("Date")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<int>("DiscussionId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("GroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("KeyId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<bool>("Type")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int>("UserId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DiscussionId");
|
|
||||||
|
|
||||||
b.HasIndex("GroupId");
|
|
||||||
|
|
||||||
b.HasIndex("KeyId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("Messages");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Role", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Libelle")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Roles");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.User", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasMaxLength(200)
|
|
||||||
.HasColumnType("nvarchar(200)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(70)
|
|
||||||
.HasColumnType("nvarchar(70)");
|
|
||||||
|
|
||||||
b.Property<string>("Password")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ProfilePicture")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int?>("RoleId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Tel")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Username")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("Users");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.UserDiscussion", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("UserId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("DiscussionId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "DiscussionId");
|
|
||||||
|
|
||||||
b.HasIndex("DiscussionId");
|
|
||||||
|
|
||||||
b.ToTable("UserDiscussions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Discussion", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Group", "Group")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("GroupId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.Navigation("Group");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Group", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Discussion", "Discussion")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("DiscussionId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Discussion");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.GroupUser", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Group", "Group")
|
|
||||||
.WithMany("GroupUsers")
|
|
||||||
.HasForeignKey("GroupId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.Role", "Role")
|
|
||||||
.WithMany("GroupUsers")
|
|
||||||
.HasForeignKey("RoleId");
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.User", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Group");
|
|
||||||
|
|
||||||
b.Navigation("Role");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Message", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Discussion", "Discussion")
|
|
||||||
.WithMany("Messages")
|
|
||||||
.HasForeignKey("DiscussionId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.Group", "Group")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("GroupId");
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.Key", "Key")
|
|
||||||
.WithMany("Messages")
|
|
||||||
.HasForeignKey("KeyId");
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.User", "User")
|
|
||||||
.WithMany("Messages")
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Discussion");
|
|
||||||
|
|
||||||
b.Navigation("Group");
|
|
||||||
|
|
||||||
b.Navigation("Key");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.User", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Role", "Role")
|
|
||||||
.WithMany("Users")
|
|
||||||
.HasForeignKey("RoleId");
|
|
||||||
|
|
||||||
b.Navigation("Role");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.UserDiscussion", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Discussion", "Discussion")
|
|
||||||
.WithMany("UserDiscussions")
|
|
||||||
.HasForeignKey("DiscussionId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.User", "User")
|
|
||||||
.WithMany("UserDiscussions")
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Discussion");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Discussion", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Messages");
|
|
||||||
|
|
||||||
b.Navigation("UserDiscussions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Group", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("GroupUsers");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Key", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Messages");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Role", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("GroupUsers");
|
|
||||||
|
|
||||||
b.Navigation("Users");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.User", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Messages");
|
|
||||||
|
|
||||||
b.Navigation("UserDiscussions");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace Knots.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class FixGroupDiscussion : Migration
|
|
||||||
{
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "AuthorId",
|
|
||||||
table: "Messages",
|
|
||||||
type: "int",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,377 +0,0 @@
|
|||||||
// <auto-generated />
|
|
||||||
using System;
|
|
||||||
using Knots;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace Knots.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(KnotsDbContext))]
|
|
||||||
partial class KnotsDbContextModelSnapshot : ModelSnapshot
|
|
||||||
{
|
|
||||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
#pragma warning disable 612, 618
|
|
||||||
modelBuilder
|
|
||||||
.HasAnnotation("ProductVersion", "8.0.25")
|
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
|
||||||
|
|
||||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Discussion", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedAt")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<int?>("GroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<bool>("IsGroup")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("GroupId");
|
|
||||||
|
|
||||||
b.ToTable("Discussions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Group", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("DiscussionId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("MembersAmount")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Name")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.Property<string>("ProfilePicture")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DiscussionId");
|
|
||||||
|
|
||||||
b.ToTable("Groups");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.GroupUser", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("GroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("UserId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("RoleId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("GroupId", "UserId");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("GroupUsers");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Key", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("EnKey")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Keys");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Message", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("AuthorId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Contenu")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(1000)
|
|
||||||
.HasColumnType("nvarchar(1000)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("Date")
|
|
||||||
.HasColumnType("datetime2");
|
|
||||||
|
|
||||||
b.Property<int>("DiscussionId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("GroupId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int?>("KeyId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<bool>("Type")
|
|
||||||
.HasColumnType("bit");
|
|
||||||
|
|
||||||
b.Property<int>("UserId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("DiscussionId");
|
|
||||||
|
|
||||||
b.HasIndex("GroupId");
|
|
||||||
|
|
||||||
b.HasIndex("KeyId");
|
|
||||||
|
|
||||||
b.HasIndex("UserId");
|
|
||||||
|
|
||||||
b.ToTable("Messages");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Role", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Libelle")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.ToTable("Roles");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.User", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<string>("Description")
|
|
||||||
.HasMaxLength(200)
|
|
||||||
.HasColumnType("nvarchar(200)");
|
|
||||||
|
|
||||||
b.Property<string>("Email")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(70)
|
|
||||||
.HasColumnType("nvarchar(70)");
|
|
||||||
|
|
||||||
b.Property<string>("Password")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("ProfilePicture")
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<int?>("RoleId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<string>("Tel")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("nvarchar(max)");
|
|
||||||
|
|
||||||
b.Property<string>("Username")
|
|
||||||
.IsRequired()
|
|
||||||
.HasMaxLength(50)
|
|
||||||
.HasColumnType("nvarchar(50)");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("RoleId");
|
|
||||||
|
|
||||||
b.ToTable("Users");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.UserDiscussion", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("UserId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.Property<int>("DiscussionId")
|
|
||||||
.HasColumnType("int");
|
|
||||||
|
|
||||||
b.HasKey("UserId", "DiscussionId");
|
|
||||||
|
|
||||||
b.HasIndex("DiscussionId");
|
|
||||||
|
|
||||||
b.ToTable("UserDiscussions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Discussion", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Group", "Group")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("GroupId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
b.Navigation("Group");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Group", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Discussion", "Discussion")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("DiscussionId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Discussion");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.GroupUser", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Group", "Group")
|
|
||||||
.WithMany("GroupUsers")
|
|
||||||
.HasForeignKey("GroupId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.Role", "Role")
|
|
||||||
.WithMany("GroupUsers")
|
|
||||||
.HasForeignKey("RoleId");
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.User", "User")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Group");
|
|
||||||
|
|
||||||
b.Navigation("Role");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Message", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Discussion", "Discussion")
|
|
||||||
.WithMany("Messages")
|
|
||||||
.HasForeignKey("DiscussionId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.Group", "Group")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("GroupId");
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.Key", "Key")
|
|
||||||
.WithMany("Messages")
|
|
||||||
.HasForeignKey("KeyId");
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.User", "User")
|
|
||||||
.WithMany("Messages")
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Discussion");
|
|
||||||
|
|
||||||
b.Navigation("Group");
|
|
||||||
|
|
||||||
b.Navigation("Key");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.User", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Role", "Role")
|
|
||||||
.WithMany("Users")
|
|
||||||
.HasForeignKey("RoleId");
|
|
||||||
|
|
||||||
b.Navigation("Role");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.UserDiscussion", b =>
|
|
||||||
{
|
|
||||||
b.HasOne("Knots.Models.Discussion", "Discussion")
|
|
||||||
.WithMany("UserDiscussions")
|
|
||||||
.HasForeignKey("DiscussionId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Knots.Models.User", "User")
|
|
||||||
.WithMany("UserDiscussions")
|
|
||||||
.HasForeignKey("UserId")
|
|
||||||
.OnDelete(DeleteBehavior.Restrict)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.Navigation("Discussion");
|
|
||||||
|
|
||||||
b.Navigation("User");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Discussion", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Messages");
|
|
||||||
|
|
||||||
b.Navigation("UserDiscussions");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Group", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("GroupUsers");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Key", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Messages");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.Role", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("GroupUsers");
|
|
||||||
|
|
||||||
b.Navigation("Users");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("Knots.Models.User", b =>
|
|
||||||
{
|
|
||||||
b.Navigation("Messages");
|
|
||||||
|
|
||||||
b.Navigation("UserDiscussions");
|
|
||||||
});
|
|
||||||
#pragma warning restore 612, 618
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace Knots.Models;
|
|
||||||
|
|
||||||
public class Discussion
|
|
||||||
{
|
|
||||||
[Key] public int Id { get; set; }
|
|
||||||
public bool IsGroup { get; set; } = false;
|
|
||||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
|
||||||
|
|
||||||
public int? GroupId { get; set; }
|
|
||||||
public Group? Group { get; set; }
|
|
||||||
|
|
||||||
public int? KeyId { get; set; }
|
|
||||||
public Key? Key { get; set; }
|
|
||||||
|
|
||||||
public List<Message> Messages { get; set; } = [];
|
|
||||||
public List<UserDiscussion> UserDiscussions { get; set; } = [];
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace Knots.Models;
|
|
||||||
|
|
||||||
public class Group
|
|
||||||
{
|
|
||||||
[Key] public int Id { get; set; }
|
|
||||||
[Required, MaxLength(50)] public string? Name { get; set; }
|
|
||||||
[Required] public int MembersAmount { get; set; }
|
|
||||||
public string? ProfilePicture { get; set; }
|
|
||||||
|
|
||||||
public List<GroupUser> GroupUsers { get; set; } = [];
|
|
||||||
|
|
||||||
public int DiscussionId { get; set; }
|
|
||||||
public Discussion Discussion { get; set; } = null!;
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
namespace Knots.Models;
|
|
||||||
|
|
||||||
public class GroupUser
|
|
||||||
{
|
|
||||||
public int GroupId { get; set; }
|
|
||||||
public Group Group { get; set; } = null!;
|
|
||||||
|
|
||||||
public int UserId { get; set; }
|
|
||||||
public User User { get; set; } = null!;
|
|
||||||
|
|
||||||
public int? RoleId { get; set; }
|
|
||||||
public Role? Role { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace Knots.Models;
|
|
||||||
|
|
||||||
public class Key
|
|
||||||
{
|
|
||||||
[Key] public int Id { get; set; }
|
|
||||||
[Required, MaxLength(50)] public string? EnKey { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace Knots.Models;
|
|
||||||
|
|
||||||
public class Message
|
|
||||||
{
|
|
||||||
[Key] public int Id { get; set; }
|
|
||||||
[Required, MaxLength(1000)] public string? Contenu { get; set; }
|
|
||||||
[Required] public DateTime Date { get; set; }
|
|
||||||
[Required] public Boolean Type { get; set; }
|
|
||||||
|
|
||||||
public int UserId { get; set; }
|
|
||||||
public User User { get; set; } = null!;
|
|
||||||
|
|
||||||
public int DiscussionId { get; set; }
|
|
||||||
public Discussion Discussion { get; set; } = null!;
|
|
||||||
|
|
||||||
public Group? Group { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace Knots.Models;
|
|
||||||
|
|
||||||
public class Role
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
[Required, MaxLength(50)] public string? Libelle { get; set; }
|
|
||||||
public List<User> Users { get; set; } = [];
|
|
||||||
public List<GroupUser> GroupUsers { get; set; } = [];
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace Knots.Models;
|
|
||||||
|
|
||||||
public class User
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
[Required, MaxLength(50)] public string? Username { get; set; }
|
|
||||||
[MaxLength(200)] public string? Description { get; set; }
|
|
||||||
[Required, Length(12, 50)] public string? Password { get; set; }
|
|
||||||
[Required, MaxLength(70)] public string? Email { get; set; }
|
|
||||||
[Required, Length(10, 10)] public string? Tel { get; set; }
|
|
||||||
public string? ProfilePicture { get; set; }
|
|
||||||
public List<Message> Messages { get; set; } = [];
|
|
||||||
public int? RoleId { get; set; }
|
|
||||||
public Role? Role { get; set; }
|
|
||||||
public List<UserDiscussion> UserDiscussions { get; set; } = [];
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
namespace Knots.Models;
|
|
||||||
|
|
||||||
public class UserDiscussion
|
|
||||||
{
|
|
||||||
public int UserId { get; set; }
|
|
||||||
public User User { get; set; } = null!;
|
|
||||||
|
|
||||||
public int DiscussionId { get; set; }
|
|
||||||
public Discussion Discussion { get; set; } = null!;
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
using AutoMapper;
|
|
||||||
using Knots.DTO.Discussion;
|
|
||||||
using Knots.Models;
|
|
||||||
|
|
||||||
namespace Knots.Profiles;
|
|
||||||
|
|
||||||
public class DiscussionProfile : Profile
|
|
||||||
{
|
|
||||||
public DiscussionProfile()
|
|
||||||
{
|
|
||||||
CreateMap<Discussion, GetDiscussionDto>();
|
|
||||||
CreateMap<Discussion, CreateDiscussionDto>();
|
|
||||||
|
|
||||||
CreateMap<CreateDiscussionDto, Discussion>();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
using AutoMapper;
|
|
||||||
using Knots.DTO.Group;
|
|
||||||
using Knots.Models;
|
|
||||||
|
|
||||||
namespace Knots.Profiles;
|
|
||||||
|
|
||||||
public class GroupProfile : Profile
|
|
||||||
{
|
|
||||||
public GroupProfile()
|
|
||||||
{
|
|
||||||
CreateMap<Group, GetGroupDto>();
|
|
||||||
CreateMap<Group, GetGroupDetailsDto>();
|
|
||||||
CreateMap<CreateGroupDto, Group>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using AutoMapper;
|
|
||||||
using Knots.DTO.Discussion;
|
|
||||||
using Knots.DTO.Key;
|
|
||||||
using Knots.Models;
|
|
||||||
|
|
||||||
namespace Knots.Profiles;
|
|
||||||
|
|
||||||
public class KeyProfile : Profile
|
|
||||||
{
|
|
||||||
public KeyProfile()
|
|
||||||
{
|
|
||||||
CreateMap<Key, GetKeyDetailsDto>();
|
|
||||||
CreateMap<Key, CreateKeyDto>();
|
|
||||||
CreateMap<CreateKeyDto, Key>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using AutoMapper;
|
|
||||||
using Knots.DTO.Discussion;
|
|
||||||
using Knots.DTO.Message;
|
|
||||||
using Knots.Models;
|
|
||||||
|
|
||||||
namespace Knots.Profiles;
|
|
||||||
|
|
||||||
public class MessageProfile : Profile
|
|
||||||
{
|
|
||||||
public MessageProfile()
|
|
||||||
{
|
|
||||||
CreateMap<Message, GetMessageDetailsDto>();
|
|
||||||
CreateMap<Message, CreateMessageDto>();
|
|
||||||
CreateMap<CreateMessageDto, Message>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using AutoMapper;
|
|
||||||
using Knots.DTO.Discussion;
|
|
||||||
using Knots.DTO.Role;
|
|
||||||
using Knots.Models;
|
|
||||||
|
|
||||||
namespace Knots.Profiles;
|
|
||||||
|
|
||||||
public class RoleProfile : Profile
|
|
||||||
{
|
|
||||||
public RoleProfile()
|
|
||||||
{
|
|
||||||
CreateMap<Role, GetRoleDto>();
|
|
||||||
CreateMap<Role, CreateRoleDto>();
|
|
||||||
CreateMap<CreateRoleDto, Role>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using AutoMapper;
|
|
||||||
using Knots.DTO.Discussion;
|
|
||||||
using Knots.DTO.User;
|
|
||||||
using Knots.Models;
|
|
||||||
|
|
||||||
namespace Knots.Profiles;
|
|
||||||
|
|
||||||
public class UserProfile : Profile
|
|
||||||
{
|
|
||||||
public UserProfile()
|
|
||||||
{
|
|
||||||
CreateMap<User, GetUserDetailsDto>();
|
|
||||||
CreateMap<User, GetUserDto>();
|
|
||||||
CreateMap<CreateUserDto, User>();
|
|
||||||
CreateMap<UpdateUserDto, User>();
|
|
||||||
CreateMap<UpdateUserContactDto, User>();
|
|
||||||
CreateMap<UpdateUserDescriptionDto, User>();
|
|
||||||
CreateMap<UpdateUsernameDto, User>();
|
|
||||||
CreateMap<UpdateUserProfilePictureDto, User>();
|
|
||||||
CreateMap<UpdateUserPasswordDto, User>();
|
|
||||||
|
|
||||||
CreateMap<User, UpdateUserContactDto>();
|
|
||||||
CreateMap<User, UpdateUserDto>();
|
|
||||||
CreateMap<User, UpdateUserDescriptionDto>();
|
|
||||||
CreateMap<User, UpdateUserProfilePictureDto>();
|
|
||||||
CreateMap<User, UpdateUserPasswordDto>();
|
|
||||||
CreateMap<User, CreateUserDto>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+12
-85
@@ -1,96 +1,23 @@
|
|||||||
using System.Text;
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
using Knots;
|
|
||||||
using FastEndpoints;
|
|
||||||
using FastEndpoints.Swagger;
|
|
||||||
using Knots.Hubs;
|
|
||||||
using Knots.Services;
|
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
||||||
using Microsoft.AspNetCore.Http.Json;
|
|
||||||
using Microsoft.IdentityModel.Tokens;
|
|
||||||
using Microsoft.OpenApi;
|
|
||||||
|
|
||||||
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
|
// Add services to the container.
|
||||||
|
|
||||||
// On ajoute ici la configuration de la base de données
|
builder.Services.AddControllers();
|
||||||
builder.Services.AddDbContext<KnotsDbContext>();
|
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
|
||||||
|
builder.Services.AddOpenApi();
|
||||||
|
|
||||||
//On ajoute le CORS au code
|
var app = builder.Build();
|
||||||
builder.Services.AddCors(options =>
|
|
||||||
{ options.AddDefaultPolicy(policyBuilder =>
|
|
||||||
{
|
|
||||||
policyBuilder
|
|
||||||
.WithOrigins("http://localhost:5250", "http://localhost:4200")
|
|
||||||
.WithMethods("GET", "POST", "PUT", "PATCH", "DELETE")
|
|
||||||
.AllowAnyHeader()
|
|
||||||
.AllowCredentials();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.Services.AddFastEndpoints(o =>
|
// Configure the HTTP request pipeline.
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
{
|
{
|
||||||
o.DisableAutoDiscovery = false;
|
app.MapOpenApi();
|
||||||
});
|
}
|
||||||
|
|
||||||
builder.Services.SwaggerDocument();
|
|
||||||
|
|
||||||
builder.Services.AddScoped<JwtService>();
|
|
||||||
|
|
||||||
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
|
||||||
.AddJwtBearer(options =>
|
|
||||||
{
|
|
||||||
options.TokenValidationParameters = new TokenValidationParameters
|
|
||||||
{
|
|
||||||
ValidateIssuer = true,
|
|
||||||
ValidateAudience = true,
|
|
||||||
ValidateLifetime = true,
|
|
||||||
ValidateIssuerSigningKey = true,
|
|
||||||
ValidIssuer = builder.Configuration["Jwt:Issuer"],
|
|
||||||
ValidAudience = builder.Configuration["Jwt:Audience"],
|
|
||||||
IssuerSigningKey = new SymmetricSecurityKey(
|
|
||||||
Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]!))
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
options.Events = new JwtBearerEvents
|
|
||||||
{
|
|
||||||
OnMessageReceived = context =>
|
|
||||||
{
|
|
||||||
var accessToken = context.Request.Query["access_token"];
|
|
||||||
var path = context.HttpContext.Request.Path;
|
|
||||||
if (!string.IsNullOrEmpty(accessToken) &&
|
|
||||||
path.StartsWithSegments("/hubs"))
|
|
||||||
{
|
|
||||||
context.Token = accessToken;
|
|
||||||
}
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
|
||||||
builder.Services.AddAuthorization();
|
|
||||||
|
|
||||||
builder.Services.AddSignalR();
|
|
||||||
|
|
||||||
builder.Services.AddAutoMapper(cfg => { }, typeof(Program).Assembly);
|
|
||||||
|
|
||||||
builder.Services.AddSingleton<EncryptionService>();
|
|
||||||
|
|
||||||
// On construit l'application en lui donnant vie
|
|
||||||
WebApplication app = builder.Build();
|
|
||||||
|
|
||||||
app.UseCors();
|
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
app.UseAuthentication()
|
app.UseAuthorization();
|
||||||
.UseAuthorization()
|
|
||||||
.UseFastEndpoints(options =>
|
|
||||||
{
|
|
||||||
options.Endpoints.RoutePrefix = "API";
|
|
||||||
options.Endpoints.ShortNames = true;
|
|
||||||
}
|
|
||||||
).UseSwaggerGen();
|
|
||||||
|
|
||||||
app.MapHub<ChatHub>("hubs/chat");
|
app.MapControllers();
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Knots.Services;
|
|
||||||
|
|
||||||
public class EncryptionService
|
|
||||||
{
|
|
||||||
private const int NonceSize = 12; // AesGcm.NonceByteSizes.MaxSize
|
|
||||||
private const int TagSize = 16; // AesGcm.TagByteSizes.MaxSize
|
|
||||||
|
|
||||||
// Génère une clé AES-256 (32 octets) encodée en Base64
|
|
||||||
public string GenerateKey()
|
|
||||||
=> Convert.ToBase64String(RandomNumberGenerator.GetBytes(32));
|
|
||||||
|
|
||||||
// Chiffre → renvoie Base64(nonce + tag + ciphertext)
|
|
||||||
public string Encrypt(string plainText, string base64Key)
|
|
||||||
{
|
|
||||||
byte[] key = Convert.FromBase64String(base64Key);
|
|
||||||
byte[] plain = Encoding.UTF8.GetBytes(plainText);
|
|
||||||
|
|
||||||
byte[] nonce = RandomNumberGenerator.GetBytes(NonceSize);
|
|
||||||
byte[] cipher = new byte[plain.Length];
|
|
||||||
byte[] tag = new byte[TagSize];
|
|
||||||
|
|
||||||
using AesGcm aes = new(key, TagSize);
|
|
||||||
aes.Encrypt(nonce, plain, cipher, tag);
|
|
||||||
|
|
||||||
byte[] result = new byte[NonceSize + TagSize + cipher.Length];
|
|
||||||
Buffer.BlockCopy(nonce, 0, result, 0, NonceSize);
|
|
||||||
Buffer.BlockCopy(tag, 0, result, NonceSize, TagSize);
|
|
||||||
Buffer.BlockCopy(cipher, 0, result, NonceSize + TagSize, cipher.Length);
|
|
||||||
|
|
||||||
return Convert.ToBase64String(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Déchiffre Base64(nonce + tag + ciphertext)
|
|
||||||
public string Decrypt(string base64Cipher, string base64Key)
|
|
||||||
{
|
|
||||||
byte[] key = Convert.FromBase64String(base64Key);
|
|
||||||
byte[] data = Convert.FromBase64String(base64Cipher);
|
|
||||||
|
|
||||||
byte[] nonce = new byte[NonceSize];
|
|
||||||
byte[] tag = new byte[TagSize];
|
|
||||||
byte[] cipher = new byte[data.Length - NonceSize - TagSize];
|
|
||||||
|
|
||||||
Buffer.BlockCopy(data, 0, nonce, 0, NonceSize);
|
|
||||||
Buffer.BlockCopy(data, NonceSize, tag, 0, TagSize);
|
|
||||||
Buffer.BlockCopy(data, NonceSize + TagSize, cipher, 0, cipher.Length);
|
|
||||||
|
|
||||||
byte[] plain = new byte[cipher.Length];
|
|
||||||
using AesGcm aes = new(key, TagSize);
|
|
||||||
aes.Decrypt(nonce, cipher, tag, plain);
|
|
||||||
|
|
||||||
return Encoding.UTF8.GetString(plain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
using System.IdentityModel.Tokens.Jwt;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using System.Text;
|
|
||||||
using Microsoft.IdentityModel.Tokens;
|
|
||||||
|
|
||||||
namespace Knots.Services;
|
|
||||||
|
|
||||||
public class JwtService(IConfiguration configuration)
|
|
||||||
{
|
|
||||||
public string GenerateToken(Models.User user)
|
|
||||||
{
|
|
||||||
List<Claim> claims =
|
|
||||||
[
|
|
||||||
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
|
|
||||||
new Claim(ClaimTypes.Name, user.Username!)
|
|
||||||
];
|
|
||||||
|
|
||||||
SymmetricSecurityKey key = new(Encoding.UTF8.GetBytes(configuration["Jwt:Key"]!));
|
|
||||||
SigningCredentials creds = new(key, SecurityAlgorithms.HmacSha256);
|
|
||||||
|
|
||||||
JwtSecurityToken token = new(
|
|
||||||
issuer: configuration["Jwt:Issuer"],
|
|
||||||
audience: configuration["Jwt:Audience"],
|
|
||||||
claims: claims,
|
|
||||||
expires: DateTime.UtcNow.AddDays(7),
|
|
||||||
signingCredentials: creds
|
|
||||||
);
|
|
||||||
|
|
||||||
return new JwtSecurityTokenHandler().WriteToken(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using FluentValidation;
|
|
||||||
using Knots.DTO.Discussion;
|
|
||||||
|
|
||||||
namespace Knots.Validators.Discussion;
|
|
||||||
|
|
||||||
public class CreateDiscussionDtoValidator : Validator<CreateDiscussionDto>
|
|
||||||
{
|
|
||||||
public CreateDiscussionDtoValidator()
|
|
||||||
{
|
|
||||||
RuleFor(x => x.Id)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Id is required");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using FluentValidation;
|
|
||||||
using Knots.DTO.Discussion;
|
|
||||||
|
|
||||||
namespace Knots.Validators.Discussion;
|
|
||||||
|
|
||||||
public class DeleteDiscussionDtoValidator : Validator<DeleteDiscussionDto>
|
|
||||||
{
|
|
||||||
public DeleteDiscussionDtoValidator()
|
|
||||||
{
|
|
||||||
RuleFor(x => x.Id)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Id is required");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using FastEndpoints;
|
|
||||||
using FluentValidation;
|
|
||||||
using Knots.DTO.Group;
|
|
||||||
|
|
||||||
namespace Knots.Validators.Group;
|
|
||||||
|
|
||||||
public class CreateGroupDtoValidator : Validator<CreateGroupDto>
|
|
||||||
{
|
|
||||||
public CreateGroupDtoValidator()
|
|
||||||
{
|
|
||||||
RuleFor(x => x.Nom)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("You must enter a name for the group")
|
|
||||||
.MaximumLength(50)
|
|
||||||
.WithMessage("Maximum 50 character are required");
|
|
||||||
|
|
||||||
RuleFor(x => x.NombreMembres)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Members cannot be empty");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user