Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RBAC - REST APIs #2773

Merged
merged 44 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
73e1ed1
GetAllRoles and GetRoleDetails(byID) with detailed correspondant acti…
Jan 8, 2024
52fdda5
GetAllGroups and GetGroupByID fonctionnal APIs
Jan 8, 2024
5cdd36b
GetAllUsers and GetUserByID fonctionnal APIs
Jan 8, 2024
7d0218a
GetGroupDetails API (list of members)
Jan 8, 2024
3a0bb2f
some changes about the review
Jan 9, 2024
4c241c4
New migrations and some changes in entities class of RBAC Model
Jan 9, 2024
33a5ada
New migrations and some changes in entities class of RBAC Model (fixes)
Jan 9, 2024
c2d6721
Add AccessControls gestion
Jan 9, 2024
be176e0
API Roles are functional
Jan 12, 2024
fcf467b
RoleServices Changes
Jan 15, 2024
be2d3e0
delete useless comments
Jan 15, 2024
6c2c439
document RoleController methods
Jan 16, 2024
f1de5c6
forgot dependencies
Jan 16, 2024
da989f9
save before resolve cache problems
Apr 11, 2024
5d1b9e1
save
Apr 12, 2024
9e1872c
Refact and upgrade quality of Roles API traitment
Apr 12, 2024
f4ccd88
add the actions role gesture
Apr 12, 2024
f708da5
Add AccessControl Get logic
Apr 15, 2024
5ccdc7c
add Get,Create,Delete Routes for the APIs
Apr 16, 2024
0be1ec3
some change about EF dbContext and entities, Role, AccessControl and …
Apr 18, 2024
10aa2a2
Migration (add Principal and his logic in EF DbContext and DB
Apr 22, 2024
8e2cdab
Migration + refactor the namespace of RBAC Services & move PredicateB…
Apr 22, 2024
3ea3c3d
functionnal service for Users
Apr 23, 2024
d773989
functionnal basic routes for group controller
Apr 23, 2024
528c648
accessControl API Routes are functionnals (with Principal changes)
Apr 24, 2024
54a6ffa
fix mistake on delete AccessControl
Apr 24, 2024
819bc40
Improve quality of the Role service implementation (Exceptions, remov…
Apr 24, 2024
a29e721
fix some mistakes + add logger for Roles
Apr 25, 2024
279d60f
User logger
Apr 25, 2024
661a5b9
logger AccessControl & group + fix somes bugs
Apr 25, 2024
a0c0131
add accessControl in group and user details routes
Apr 26, 2024
f0b5b9b
Add GetByName for User and group + some exceptions if name already ex…
Apr 26, 2024
1b39293
Tests for all RBAC repositories + RoleController
May 13, 2024
513f288
Add tests of Groups & Users controllers
May 13, 2024
a2c057c
Tests the AccessControl's Controller
May 13, 2024
09ed998
Fix some conflicts
May 27, 2024
f1c5b60
Review fixes
Jun 4, 2024
1fd33a0
Improving the robustness of tests (rbac)
Jun 6, 2024
a2d4780
Testing RBAC Controller & Services + some modification in the corresp…
Jun 14, 2024
9f8e90f
Refactor a mistake in namespace v10
Jun 14, 2024
a530219
Some changes
Jun 18, 2024
155f6dc
use autoFixture in all unitTest instead of creating some ressource ma…
Jul 2, 2024
251a2f1
Add tests of limits in methods
Jul 15, 2024
76b069d
remove forgotten comment
TLeoDev Jul 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions src/IoTHub.Portal.Application/Mappers/GroupProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace IoTHub.Portal.Application.Mappers
{
using AutoMapper;
using IoTHub.Portal.Domain.Entities;
using IoTHub.Portal.Shared.Models.v10;

public class GroupProfile : Profile
{
public GroupProfile()
{
_ = CreateMap<Group, GroupModel>()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.Id))
.ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.Name));

_ = CreateMap<Group, GroupDetailsModel>()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.Id))
.ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.Name))
.ForMember(dest => dest.Users, opts => opts.MapFrom(src =>
src.Members.Select(u => new UserModel
{
Id = u.User.Id,
GivenName = u.User.GivenName
})))
.ForMember(dest => dest.AccessControls, opts => opts.MapFrom(src =>
src.AccessControls.Select(ac => new AccessControlModel
{
Id = ac.Id,
Scope = ac.Scope,
Role = new RoleModel { Name = ac.Role.Name }
})));

_ = CreateMap<GroupModel, Group>()
.ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.Name));
}
}
}
32 changes: 32 additions & 0 deletions src/IoTHub.Portal.Application/Mappers/RoleProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace IoTHub.Portal.Application.Mappers
{
using AutoMapper;
using IoTHub.Portal.Domain.Entities;
using IoTHub.Portal.Shared.Models.v10;

public class RoleProfile : Profile
{
public RoleProfile()
{
_ = CreateMap<Role, RoleModel>()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.Id))
.ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.Name));

_ = CreateMap<Role, RoleDetailsModel>()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.Id))
.ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.Name))
.ForMember(dest => dest.Description, opts => opts.MapFrom(src => src.Description))
.ForMember(dest => dest.Actions, opts => opts.MapFrom(src =>
src.Actions.Select(a => a.Name)));

_ = CreateMap<RoleDetailsModel, Role>()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.Id))
.ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.Name))
.ForMember(dest => dest.Description, opts => opts.MapFrom(src => src.Description))
.ForMember(dest => dest.Actions, opts => opts.Ignore());
}
}
}
33 changes: 33 additions & 0 deletions src/IoTHub.Portal.Application/Mappers/UserProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace IoTHub.Portal.Application.Mappers
{
using AutoMapper;
using IoTHub.Portal.Domain.Entities;
using IoTHub.Portal.Shared.Models.v10;

public class UserProfile : Profile
{
public UserProfile()
{
_ = CreateMap<User, UserModel>()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.Id))
.ForMember(dest => dest.GivenName, opts => opts.MapFrom(src => src.GivenName));

_ = CreateMap<User, UserDetailsModel>()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.Id))
.ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.Name))
.ForMember(dest => dest.Email, opts => opts.MapFrom(src => src.Email))
.ForMember(dest => dest.GivenName, opts => opts.MapFrom(src => src.GivenName))
.ForMember(dest => dest.FamilyName, opts => opts.MapFrom(src => src.FamilyName))
.ForMember(dest => dest.AccessControls, opts => opts.MapFrom(src =>
src.AccessControls.Select(ac => new AccessControlModel
{
Id = ac.Id,
Scope = ac.Scope,
Role = new RoleModel { Name = ac.Role.Name }
})));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace IoTHub.Portal.Application.Services
{
using IoTHub.Portal.Shared.Models.v10;

public interface IGroupManagementService
{
Task<IEnumerable<GroupModel>> GetAllGroupsAsync();
Task<GroupDetailsModel> GetGroupDetailsAsync(string groupId);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace IoTHub.Portal.Application.Services
{
using IoTHub.Portal.Shared.Models.v10;

public interface IRoleManagementService
{
Task<IEnumerable<RoleModel>> GetAllRolesAsync();
Task<RoleDetailsModel> GetRoleDetailsAsync(string roleName);
Task<RoleDetailsModel> CreateRole(RoleDetailsModel roleDetails);
Task<RoleDetailsModel> UpdateRole(string roleName, RoleDetailsModel roleDetails);
Task<bool> DeleteRole(string roleName);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace IoTHub.Portal.Application.Services
{
using IoTHub.Portal.Shared.Models.v10;

public interface IUserManagementService
{
Task<IEnumerable<UserModel>> GetAllUsersAsync();
Task<UserDetailsModel> GetUserDetailsAsync(string userId);

}
}
4 changes: 4 additions & 0 deletions src/IoTHub.Portal.Domain/Entities/AccessControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@ public class AccessControl : EntityBase
public string Scope { get; set; } = default!;
public string RoleId { get; set; } = default!;
public Role Role { get; set; } = new Role();
public User User { get; set; } = new User();
public Group Group { get; set; } = new Group();
public string? GroupId { get; set; } = default!;
public string? UserId { get; set; } = default!;
}
}
2 changes: 1 addition & 1 deletion src/IoTHub.Portal.Domain/Entities/Group.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace IoTHub.Portal.Domain.Entities
public class Group : EntityBase
{
public string Name { get; set; } = default!;
public string Avatar { get; set; } = default!;
public string Description { get; set; } = default!;
public virtual ICollection<UserMemberShip> Members { get; set; } = new Collection<UserMemberShip>();
public virtual ICollection<AccessControl> AccessControls { get; set; } = new Collection<AccessControl>();

Expand Down
1 change: 1 addition & 0 deletions src/IoTHub.Portal.Domain/Entities/Role.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace IoTHub.Portal.Domain.Entities
public class Role : EntityBase
{
public string Name { get; set; } = default!;
public string Description { get; set; } = default!;
public virtual ICollection<Action> Actions { get; set; } = new Collection<Action>();
}
}
3 changes: 2 additions & 1 deletion src/IoTHub.Portal.Domain/Entities/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ public class User : EntityBase
{
public string Email { get; set; } = default!;
public string Name { get; set; } = default!;
public string Forename { get; set; } = default!;
public string GivenName { get; set; } = default!;
public string FamilyName { get; set; } = default!;
public virtual ICollection<UserMemberShip> Groups { get; set; } = new Collection<UserMemberShip>();
public virtual ICollection<AccessControl> AccessControls { get; set; } = new Collection<AccessControl>();
}
Expand Down
4 changes: 1 addition & 3 deletions src/IoTHub.Portal.Domain/Entities/UserMemberShip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@

namespace IoTHub.Portal.Domain.Entities
{
using IoTHub.Portal.Domain.Base;

public class UserMemberShip : EntityBase
public class UserMemberShip
{
public string UserId { get; set; } = default!;
public virtual User? User { get; set; }
Expand Down
14 changes: 14 additions & 0 deletions src/IoTHub.Portal.Domain/Repositories/IGroupRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace IoTHub.Portal.Domain.Repositories
{
using IoTHub.Portal.Domain.Entities;
using System.Threading.Tasks;

public interface IGroupRepository
{
Task<Group[]> GetAllAsync();
Task<Group?> GetByIdAsync(string groupId);
}
}
13 changes: 13 additions & 0 deletions src/IoTHub.Portal.Domain/Repositories/IRoleRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace IoTHub.Portal.Domain.Repositories
{
using System.Linq.Expressions;
using IoTHub.Portal.Domain.Entities;

public interface IRoleRepository : IRepository<Role>
{
Task<Role?> GetByNameAsync(string roleName, params Expression<Func<Role, object>>[] includeProperties);
}
}
14 changes: 14 additions & 0 deletions src/IoTHub.Portal.Domain/Repositories/IUserRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace IoTHub.Portal.Domain.Repositories
{
using IoTHub.Portal.Domain.Entities;
using System.Threading.Tasks;

public interface IUserRepository
{
Task<User[]> GetAllAsync();
Task<User?> GetByIdAsync(string userId);
}
}
13 changes: 13 additions & 0 deletions src/IoTHub.Portal.Infrastructure/PortalDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
_ = modelBuilder.Entity<Group>()
.HasMany(a => a.AccessControls);


_ = modelBuilder.Entity<User>()
.HasMany(a => a.AccessControls);

Expand All @@ -88,6 +89,18 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)

_ = modelBuilder.Entity<AccessControl>()
.HasOne(r => r.Role);

_ = modelBuilder.Entity<AccessControl>()
.HasOne(ac => ac.User)
.WithMany(u => u.AccessControls)
.HasForeignKey(ac => ac.UserId)
.IsRequired(false);

_ = modelBuilder.Entity<AccessControl>()
.HasOne(ac => ac.Group)
.WithMany(g => g.AccessControls)
.HasForeignKey(ac => ac.GroupId)
.IsRequired(false);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace IoTHub.Portal.Infrastructure.Repositories
{
using IoTHub.Portal.Domain.Entities;
using IoTHub.Portal.Domain.Repositories;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;

public class GroupRepository : IGroupRepository
{
private readonly PortalDbContext context;

public GroupRepository(PortalDbContext context)
{
this.context = context;
}

public Task<Group[]> GetAllAsync()
{
return context.Groups
.ToArrayAsync();
}

public Task<Group?> GetByIdAsync(string groupId)
{
return context.Groups
.Include(g => g.Members)
.ThenInclude(m => m.User)
.Include(g => g.AccessControls)
.ThenInclude(ac => ac.Role)
.FirstOrDefaultAsync(g => g.Id == groupId);
}
}
}
26 changes: 26 additions & 0 deletions src/IoTHub.Portal.Infrastructure/Repositories/RoleRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace IoTHub.Portal.Infrastructure.Repositories
{
using System.Linq.Expressions;
using IoTHub.Portal.Domain.Entities;
using IoTHub.Portal.Domain.Repositories;
using Microsoft.EntityFrameworkCore;

public class RoleRepository : GenericRepository<Role>, IRoleRepository
{
public RoleRepository(PortalDbContext context) : base(context)
{
}
public async Task<Role?> GetByNameAsync(string roleName, params Expression<Func<Role, object>>[] includeProperties)
{
IQueryable<Role> query = context.Roles;
foreach (var includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
return await query.FirstOrDefaultAsync(r => r.Name == roleName);
}
}
}
34 changes: 34 additions & 0 deletions src/IoTHub.Portal.Infrastructure/Repositories/UserRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace IoTHub.Portal.Infrastructure.Repositories
{
using IoTHub.Portal.Domain.Entities;
using IoTHub.Portal.Domain.Repositories;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;

public class UserRepository : IUserRepository
{
private readonly PortalDbContext context;

public UserRepository(PortalDbContext context)
{
this.context = context;
}

public Task<User[]> GetAllAsync()
{
return context.Users
.ToArrayAsync();
}

public Task<User?> GetByIdAsync(string userId)
{
return context.Users
.Include(r => r.AccessControls)
.ThenInclude(ac => ac.Role)
.FirstOrDefaultAsync(r => r.Id == userId);
}
}
}
Loading