Skip to content

Commit

Permalink
Merge pull request #348 from SaintAngeLs/organizations_service
Browse files Browse the repository at this point in the history
#342 Blazor application layout update
  • Loading branch information
SaintAngeLs authored Aug 4, 2024
2 parents 44d37ee + a1d2a13 commit ce25f38
Show file tree
Hide file tree
Showing 44 changed files with 1,686 additions and 299 deletions.
7 changes: 7 additions & 0 deletions MiniSpace.APIGateway/src/MiniSpace.APIGateway/ntrada.yml
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,13 @@ modules:
bind:
- organizationId: {organizationId}

- upstream: /{organizationId}/roles
method: GET
use: downstream
downstream: organizations-service/organizations/{organizationId}/roles
auth: true
bind:
- organizationId: {organizationId}

- upstream: /{organizationId}
method: DELETE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public static async Task Main(string[] args)
.Get<GetAllChildrenOrganizations, IEnumerable<Guid>>("organizations/{organizationId}/children/all")
.Get<GetUserOrganizations, IEnumerable<OrganizationDto>>("users/{userId}/organizations")
.Get<GetOrganizationWithGalleryAndUsers, OrganizationGalleryUsersDto>("organizations/{organizationId}/details/gallery-users")
.Get<GetOrganizationRoles, IEnumerable<RoleDto>>("organizations/{organizationId}/roles")

.Post<CreateOrganization>("organizations",
afterDispatch: (cmd, ctx) => ctx.Response.Created($"organizations/{cmd.OrganizationId}"))
.Post<CreateSubOrganization>("organizations/{organizationId}/children",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ public class CreateOrganizationRole : ICommand
{
public Guid OrganizationId { get; }
public string RoleName { get; }
public string Description { get; }
public Dictionary<string, bool> Permissions { get; }

public CreateOrganizationRole(Guid organizationId, string roleName, Dictionary<string, bool> permissions)
public CreateOrganizationRole(Guid organizationId, string roleName, string description, Dictionary<string, bool> permissions)
{
OrganizationId = organizationId;
RoleName = roleName;
Description = description;
Permissions = permissions;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,19 @@ public async Task HandleAsync(CreateOrganization command, CancellationToken canc
var creatorMember = new User(identity.Id, creatorRole);
await _organizationMembersRepository.AddMemberAsync(organization.Id, creatorMember);

var userRole = defaultRoles.SingleOrDefault(r => r.Name == "User");
if (userRole == null)
{
throw new RoleNotFoundException("User");
}
organization.UpdateDefaultRole(userRole.Name);


await _messageBroker.PublishAsync(new OrganizationCreated(
organization.Id,
organization.Name,
organization.Description,
command.RootId ?? organization.Id, // Root ID is the organization's own ID or the provided root ID
command.RootId ?? organization.Id,
command.ParentId,
command.OwnerId,
DateTime.UtcNow));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using MiniSpace.Services.Organizations.Core.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -24,6 +25,13 @@ public CreateOrganizationRoleHandler(IOrganizationRepository organizationReposit

public async Task HandleAsync(CreateOrganizationRole command, CancellationToken cancellationToken)
{
// Log the entire command to the console
Console.WriteLine($"Handling CreateOrganizationRole Command:\n" +
$"OrganizationId: {command.OrganizationId}\n" +
$"RoleName: {command.RoleName}\n" +
$"Description: {command.Description}\n" +
$"Permissions: {string.Join(", ", command.Permissions.Select(p => $"{p.Key}: {p.Value}"))}");

var identity = _appContext.Identity;
if (!identity.IsAuthenticated)
{
Expand Down Expand Up @@ -53,7 +61,7 @@ public async Task HandleAsync(CreateOrganizationRole command, CancellationToken
var permissions = new Dictionary<Permission, bool>();
foreach (var permission in command.Permissions)
{
if (Enum.TryParse<Permission>(permission.Key, out var parsedPermission))
if (Enum.TryParse<Permission>(permission.Key, true, out var parsedPermission)) // Case-insensitive parsing
{
permissions[parsedPermission] = permission.Value;
}
Expand All @@ -63,7 +71,7 @@ public async Task HandleAsync(CreateOrganizationRole command, CancellationToken
}
}

var newRole = new Role(command.RoleName, "Default role description", permissions);
var newRole = new Role(command.RoleName, command.Description, permissions);
organization.AddRole(newRole);

await _organizationRolesRepository.AddRoleAsync(command.OrganizationId, newRole);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ public async Task HandleAsync(UpdateOrganization command, CancellationToken canc
var existingOrganization = await _organizationRepository.GetAsync(command.OrganizationId);
if (existingOrganization == null)
{
// If the organization does not exist, it is a create operation,
// so we skip the permission check in this case and validate other constraints.
var root = await _organizationRepository.GetAsync(command.RootId);
if (root == null)
{
Expand All @@ -66,31 +64,31 @@ public async Task HandleAsync(UpdateOrganization command, CancellationToken canc
command.Settings,
command.OwnerId,
command.BannerUrl,
command.ImageUrl);
command.ImageUrl,
command.ParentId,
null,
command.DefaultRoleName
);

parent.AddSubOrganization(newOrganization);
await _organizationRepository.UpdateAsync(root);
}
else
{
// Check permissions before updating the existing organization
var user = await _organizationRepository.GetMemberAsync(existingOrganization.Id, identity.Id);
if (user == null)
{
throw new UnauthorizedAccessException("User does not have permission to update the organization.");
}

// Retrieve the role with permissions from the roles repository
var role = await _organizationRolesRepository.GetRoleByNameAsync(existingOrganization.Id, user.Role.Name);

// Check if the role has the necessary permission
if (role == null || !role.Permissions.ContainsKey(Permission.EditOrganizationDetails) || !role.Permissions[Permission.EditOrganizationDetails])
{
throw new UnauthorizedAccessException("User does not have permission to update the organization.");
}

// Update existing organization
existingOrganization.UpdateDetails(command.Name, command.Description, command.Settings, command.BannerUrl, command.ImageUrl);
existingOrganization.UpdateDefaultRole(command.DefaultRoleName);
await _organizationRepository.UpdateAsync(existingOrganization);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using System;
using System.Threading.Tasks;
using MiniSpace.Services.Organizations.Application.Exceptions;
using System.Threading;
using System.Collections.Generic;

namespace MiniSpace.Services.Organizations.Application.Commands.Handlers
{
Expand All @@ -20,25 +22,26 @@ public UpdateRolePermissionsHandler(IOrganizationRolesRepository rolesRepository

public async Task HandleAsync(UpdateRolePermissions command, CancellationToken cancellationToken)
{
// Retrieve the organization
var organization = await _organizationRepository.GetAsync(command.OrganizationId);
if (organization == null)
{
throw new OrganizationNotFoundException(command.OrganizationId);
}

// Retrieve the role
var role = await _rolesRepository.GetRoleAsync(command.OrganizationId, command.RoleId);
var role = await _rolesRepository.GetRoleByNameAsync(command.OrganizationId, command.RoleName);
if (role == null)
{
throw new RoleNotFoundException(command.RoleId);
throw new RoleNotFoundException(command.RoleName);
}

// Update role permissions
role.UpdateName(command.RoleName);
role.UpdateDescription(command.Description);

var permissions = new Dictionary<Permission, bool>();
foreach (var permission in command.Permissions)
{
if (Enum.TryParse<Permission>(permission.Key, out var parsedPermission))
// Convert the string key to match enum case sensitivity
if (Enum.TryParse<Permission>(permission.Key, true, out var parsedPermission))
{
permissions[parsedPermission] = permission.Value;
}
Expand All @@ -47,9 +50,8 @@ public async Task HandleAsync(UpdateRolePermissions command, CancellationToken c
throw new InvalidPermissionException(permission.Key);
}
}
organization.UpdateRolePermissions(role.Id, permissions);
role.UpdatePermissions(permissions);

// Save changes
await _rolesRepository.UpdateRoleAsync(role);
await _organizationRepository.UpdateAsync(organization);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ public class UpdateOrganization : ICommand
public OrganizationSettings Settings { get; }
public string BannerUrl { get; }
public string ImageUrl { get; }
public string DefaultRoleName { get; }

public UpdateOrganization(Guid organizationId, string name, string description, Guid rootId, Guid parentId, Guid ownerId, OrganizationSettings settings, string bannerUrl, string imageUrl)
public UpdateOrganization(Guid organizationId, string name, string description,
Guid rootId, Guid parentId, Guid ownerId, OrganizationSettings settings,
string bannerUrl, string imageUrl, string defaultRoleName)
{
OrganizationId = organizationId == Guid.Empty ? Guid.NewGuid() : organizationId;
Name = name;
Expand All @@ -26,6 +29,7 @@ public UpdateOrganization(Guid organizationId, string name, string description,
Settings = settings;
BannerUrl = bannerUrl;
ImageUrl = imageUrl;
DefaultRoleName = defaultRoleName;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ public class UpdateRolePermissions : ICommand
{
public Guid OrganizationId { get; }
public Guid RoleId { get; }
public string RoleName { get; set; }
public string Description { get; set; }
public Dictionary<string, bool> Permissions { get; }

public UpdateRolePermissions(Guid organizationId, Guid roleId, Dictionary<string, bool> permissions)
public UpdateRolePermissions(Guid organizationId, Guid roleId, string roleName,
string description, Dictionary<string, bool> permissions)
{
OrganizationId = organizationId;
RoleId = roleId;
RoleName = roleName;
Description = description;
Permissions = permissions;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ namespace MiniSpace.Services.Organizations.Application.DTO
[ExcludeFromCodeCoverage]
public class GalleryImageDto
{
public Guid Id { get; set; }
public string Url { get; set; }
public string Description { get; set; }
public DateTime CreatedAt { get; set; }
public Guid ImageId { get; set; }
public string ImageUrl { get; set; }
public DateTime DateAdded { get; set; }

public GalleryImageDto()
{
Expand All @@ -19,10 +18,16 @@ public GalleryImageDto()

public GalleryImageDto(GalleryImage galleryImage)
{
Id = galleryImage.Id;
Url = galleryImage.Url;
Description = galleryImage.Description;
CreatedAt = galleryImage.CreatedAt;
ImageId = galleryImage.ImageId;
ImageUrl = galleryImage.ImageUrl;
DateAdded = galleryImage.DateAdded;
}

public GalleryImageDto(Guid imageId, string imageUrl, DateTime dateAdded)
{
ImageId = imageId;
ImageUrl = imageUrl;
DateAdded = dateAdded;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class OrganizationDetailsDto
public IEnumerable<RoleDto> Roles { get; set; }
public IEnumerable<GalleryImageDto> Gallery { get; set; }
public OrganizationSettingsDto Settings { get; set; }
public string DefaultRoleName { get; set; }

public OrganizationDetailsDto()
{
Expand All @@ -42,6 +43,7 @@ public OrganizationDetailsDto(Organization organization)
Roles = organization.Roles?.Select(r => new RoleDto(r)).ToList();
Gallery = organization.Gallery?.Select(g => new GalleryImageDto(g)).ToList();
Settings = organization.Settings != null ? new OrganizationSettingsDto(organization.Settings) : null;
DefaultRoleName = organization.DefaultRoleName;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class OrganizationDto
public string BannerUrl { get; set; }
public string ImageUrl { get; set; }
public Guid OwnerId { get; set; }
public string DefaultRoleName { get; set; }

public OrganizationDto()
{
Expand All @@ -26,6 +27,7 @@ public OrganizationDto(Organization organization)
BannerUrl = organization.BannerUrl;
ImageUrl = organization.ImageUrl;
OwnerId = organization.OwnerId;
DefaultRoleName = organization.DefaultRoleName;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class OrganizationGalleryUsersDto
public OrganizationDetailsDto OrganizationDetails { get; set; }
public IEnumerable<GalleryImageDto> Gallery { get; set; }
public IEnumerable<UserDto> Users { get; set; }

public OrganizationGalleryUsersDto() {}
public OrganizationGalleryUsersDto(Organization organization, IEnumerable<GalleryImage> gallery, IEnumerable<User> users)
{
OrganizationDetails = new OrganizationDetailsDto(organization);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Convey.CQRS.Queries;
using MiniSpace.Services.Organizations.Application.DTO;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

namespace MiniSpace.Services.Organizations.Application.Queries
{
[ExcludeFromCodeCoverage]
public class GetOrganizationRoles : IQuery<IEnumerable<RoleDto>>
{
public Guid OrganizationId { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,15 @@ namespace MiniSpace.Services.Organizations.Core.Entities
{
public class GalleryImage
{
public Guid Id { get; private set; }
public string Url { get; private set; }
public string Description { get; private set; }
public DateTime CreatedAt { get; private set; }
public Guid ImageId { get; private set; }
public string ImageUrl { get; private set; }
public DateTime DateAdded { get; private set; }

public GalleryImage(Guid id, string url, DateTime createdAt, string description = null)
public GalleryImage(Guid imageId, string imageUrl, DateTime dateAdded)
{
Id = id;
Url = url;
CreatedAt = createdAt;
Description = description;
}

public void UpdateDescription(string description)
{
Description = description;
ImageId = imageId;
ImageUrl = imageUrl ?? throw new ArgumentNullException(nameof(imageUrl));
DateAdded = dateAdded;
}
}
}
Loading

0 comments on commit ce25f38

Please sign in to comment.