Skip to content

Commit

Permalink
User provisioning updates
Browse files Browse the repository at this point in the history
  • Loading branch information
leewrigh committed Oct 30, 2024
1 parent 26fb6dc commit 062ed4e
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 91 deletions.
2 changes: 1 addition & 1 deletion backend/CommonModels/CommonModels.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>1.1.8.5</Version>
<Version>1.1.8.7</Version>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Title>DIAM-Common-Models</Title>
<Description>Common models for DIAM services</Description>
Expand Down
4 changes: 2 additions & 2 deletions backend/common/Kafka/IKafkaHandler.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
namespace Common.Kafka;
using System.Threading.Tasks;

public interface IKafkaHandler<Tk, Tv>
public interface IKafkaHandler<TK, TV>
{
/// <summary>
/// Provide mechanism to handle the consumer message from Kafka
/// </summary>
/// <param name="key">Indicates the message's key for Kafka Topic</param>
/// <param name="value">Indicates the message's value for Kafka Topic</param>
/// <returns></returns>
Task<Task> HandleAsync(string consumerName, Tk key, Tv value);
Task<Task> HandleAsync(string consumerName, TK key, TV value);
}
62 changes: 28 additions & 34 deletions backend/jumwebapi/Extensions/AuthenticationException.cs
Original file line number Diff line number Diff line change
@@ -1,41 +1,35 @@
using System.Runtime.Serialization;

namespace jumwebapi.Extensions;


/// <summary>
/// AuthenticationException class, provides a way to handle exceptions that occur when validating authentication.
/// </summary>
[Serializable]
public class AuthenticationException : Exception
{
#region Constructors
/// <summary>
/// AuthenticationException class, provides a way to handle exceptions that occur when validating authentication.
/// Creates a new instance of a AuthenticationException object.
/// </summary>
[Serializable]
public class AuthenticationException : Exception
{
#region Constructors
/// <summary>
/// Creates a new instance of a AuthenticationException object.
/// </summary>
/// <returns></returns>
public AuthenticationException() { }
/// <returns></returns>
public AuthenticationException() { }

/// <summary>
/// Creates a new instance of a AuthenticationException object, initializes it with the specified arguments.
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public AuthenticationException(string message) : base(message) { }
/// <summary>
/// Creates a new instance of a AuthenticationException object, initializes it with the specified arguments.
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public AuthenticationException(string message) : base(message) { }

/// <summary>
/// Creates a new instance of a AuthenticationException object, initializes it with the specified arguments.
/// /// </summary>
/// <param name="message"></param>
/// <param name="innerException"></param>
/// <returns></returns>
public AuthenticationException(string message, Exception innerException) : base(message, innerException) { }

/// <summary>
/// Creates a new instance of a AuthenticationException object, initializes it with the specified arguments.
/// /// </summary>
/// <param name="message"></param>
/// <param name="innerException"></param>
/// <returns></returns>
public AuthenticationException(string message, Exception innerException) : base(message, innerException) { }

/// <summary>
/// Creates a new instance of a AuthenticationException object, initializes it with the specified arguments.
/// /// </summary>
/// <param name="info"></param>
/// <param name="context"></param>
/// <returns></returns>
protected AuthenticationException(SerializationInfo info, StreamingContext context) : base(info, context) { }
#endregion
}
#endregion
}

65 changes: 49 additions & 16 deletions backend/jumwebapi/Extensions/IdentityExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using jumwebapi.Core.Extension;
using System.Security.Claims;
using jumwebapi.Core.Extension;
using jumwebapi.Data.Exceptions;
using jumwebapi.Data.Security;
using jumwebapi.Infrastructure;
using System.Linq;
using System.Security.Claims;

namespace jumwebapi.Extensions;

Expand All @@ -20,8 +19,11 @@ public static class IdentityExtensions
/// <returns>True if the user has any of the permission.</returns>
public static bool HasPermission(this ClaimsPrincipal user, params Permissions[] permission)
{
if (permission == null) throw new ArgumentNullException(nameof(permission));
if (permission.Length == 0) throw new ArgumentOutOfRangeException(nameof(permission));
ArgumentNullException.ThrowIfNull(permission);
if (permission.Length == 0)
{
throw new ArgumentOutOfRangeException(nameof(permission));
}

var roles = permission.Select(r => r.GetName()).ToArray();
return user.Claims.Any(c => c.Type == ClaimTypes.Role && roles.Contains(c.Value));
Expand All @@ -35,8 +37,11 @@ public static bool HasPermission(this ClaimsPrincipal user, params Permissions[]
/// <returns>True if the user has all of the permissions.</returns>
public static bool HasPermissions(this ClaimsPrincipal user, params Permissions[] permission)
{
if (permission == null) throw new ArgumentNullException(nameof(permission));
if (permission.Length == 0) throw new ArgumentOutOfRangeException(nameof(permission));
ArgumentNullException.ThrowIfNull(permission);
if (permission.Length == 0)
{
throw new ArgumentOutOfRangeException(nameof(permission));
}

var roles = permission.Select(r => r.GetName()).ToArray();
var claims = user.Claims.Where(c => c.Type == ClaimTypes.Role);
Expand All @@ -52,7 +57,11 @@ public static bool HasPermissions(this ClaimsPrincipal user, params Permissions[
/// <returns></returns>
public static ClaimsPrincipal ThrowIfNotAuthorized(this ClaimsPrincipal user, string message = null)
{
if (user == null || !user.Identity.IsAuthenticated) throw new NotAuthorizedException(message);
if (user == null || !user.Identity.IsAuthenticated)
{
throw new NotAuthorizedException(message);
}

return user;
}

Expand All @@ -61,12 +70,16 @@ public static ClaimsPrincipal ThrowIfNotAuthorized(this ClaimsPrincipal user, st
/// </summary>
/// <param name="user"></param>
/// <param name="role"></param>
/// <param name="message"></param>
/// <param name="message"></param>a
/// <exception type="NotAuthorizedException">User does not have the specified 'role'.</exception>
/// <returns></returns>
public static ClaimsPrincipal ThrowIfNotAuthorized(this ClaimsPrincipal user, string role, string message)
{
if (user == null || !user.HasRole(role)) throw new NotAuthorizedException(message);
if (user == null || !user.HasRole(role))
{
throw new NotAuthorizedException(message);
}

return user;
}

Expand All @@ -80,7 +93,11 @@ public static ClaimsPrincipal ThrowIfNotAuthorized(this ClaimsPrincipal user, st
/// <returns></returns>
public static ClaimsPrincipal ThrowIfNotAuthorized(this ClaimsPrincipal user, Permissions permission, string message = null)
{
if (user == null || !user.HasPermission(permission)) throw new NotAuthorizedException(message);
if (user == null || !user.HasPermission(permission))
{
throw new NotAuthorizedException(message);
}

return user;
}

Expand All @@ -93,7 +110,11 @@ public static ClaimsPrincipal ThrowIfNotAuthorized(this ClaimsPrincipal user, Pe
/// <returns></returns>
public static ClaimsPrincipal ThrowIfNotAuthorized(this ClaimsPrincipal user, params Permissions[] permission)
{
if (user == null || !user.HasPermission(permission)) throw new NotAuthorizedException();
if (user == null || !user.HasPermission(permission))
{
throw new NotAuthorizedException();
}

return user;
}

Expand All @@ -107,7 +128,11 @@ public static ClaimsPrincipal ThrowIfNotAuthorized(this ClaimsPrincipal user, pa
/// <returns></returns>
public static ClaimsPrincipal ThrowIfNotAllAuthorized(this ClaimsPrincipal user, Permissions permission, string message = null)
{
if (user == null || !user.HasPermissions(permission)) throw new NotAuthorizedException(message);
if (user == null || !user.HasPermissions(permission))
{
throw new NotAuthorizedException(message);
}

return user;
}

Expand All @@ -120,7 +145,11 @@ public static ClaimsPrincipal ThrowIfNotAllAuthorized(this ClaimsPrincipal user,
/// <returns></returns>
public static ClaimsPrincipal ThrowIfNotAllAuthorized(this ClaimsPrincipal user, params Permissions[] permission)
{
if (user == null || !user.HasPermissions(permission)) throw new NotAuthorizedException();
if (user == null || !user.HasPermissions(permission))
{
throw new NotAuthorizedException();
}

return user;
}

Expand All @@ -134,7 +163,11 @@ public static ClaimsPrincipal ThrowIfNotAllAuthorized(this ClaimsPrincipal user,
/// <returns></returns>
public static ClaimsPrincipal ThrowIfNotAuthorized(this ClaimsPrincipal user, Permissions[] permission, string message = null)
{
if (user == null || !user.HasPermission(permission)) throw new NotAuthorizedException(message);
if (user == null || !user.HasPermission(permission))
{
throw new NotAuthorizedException(message);
}

return user;
}

Expand Down Expand Up @@ -179,4 +212,4 @@ public static T ThrowIfNotAllowedToEdit<T>(this ClaimsPrincipal user, string par

return entity;
}
}
}
46 changes: 37 additions & 9 deletions backend/service.edt/HttpClients/Services/EdtCore/EdtClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,27 @@ public async Task<UserModificationEvent> CreateUser(EdtUserProvisioningModel acc

if (!result.IsSuccess)
{
Log.Logger.Error("Failed to create EDT user {0}", string.Join(",", result.Errors));
userModificationResponse.successful = false;
if (result.Errors != null && result.Errors.Count > 0 && result.Errors.FirstOrDefault().Contains("username or key already exists"))
{
// confirm user key is also set
var edtUser = await this.GetUser(accessRequest.Key!);
if (edtUser == null)
{
Log.Logger.Error($"User {accessRequest.UserName} already exists but key is not set {accessRequest.Key}");
userModificationResponse.successful = false;

}
else
{
Log.Logger.Information("User {0} already exists", accessRequest.Key);
return userModificationResponse;
}
}
else
{
Log.Logger.Error("Failed to create EDT user {0}", string.Join(",", result.Errors));
userModificationResponse.successful = false;
}
}

//add user to group
Expand Down Expand Up @@ -113,19 +132,28 @@ public async Task<bool> UpdateUserAssignedGroups(string userIdOrKey, List<Assign
Log.Information($"User {userIdOrKey} is assigned to {currentlyAssignedGroups.Count} groups");
foreach (var currentAssignedGroup in currentlyAssignedGroups)
{
var assignedRegion = assignedRegions.Find(region => region.RegionName.Equals(currentAssignedGroup.Name))!;
if (assignedRegion == null && !additionalGroupConfig.Contains(assignedRegion.RegionName))
var assignedRegion = assignedRegions.Find(region => region.RegionName.Equals(currentAssignedGroup.Name));
if (assignedRegion == null)
{
Log.Logger.Information("User {0} is in group {1} that is no longer valid", userIdOrKey, currentAssignedGroup.Name);
var result = await this.RemoveUserFromGroup(userIdOrKey, currentAssignedGroup);
if (!result)
if (additionalGroupConfig.Contains(currentAssignedGroup.Name))
{
Log.Logger.Information($"User {userIdOrKey} is in group {currentAssignedGroup.Name} that is part of additional groups");
}
else
{
Log.Warning($"Failed to remove user {userIdOrKey} from group {currentAssignedGroup.Name}");
return false;
Log.Logger.Information("User {0} is in group {1} that is no longer valid", userIdOrKey, currentAssignedGroup.Name);
var result = await this.RemoveUserFromGroup(userIdOrKey, currentAssignedGroup);
if (!result)
{
Log.Warning($"Failed to remove user {userIdOrKey} from group {currentAssignedGroup.Name}");
return false;
}
}
}
}



if (assignedRegions.Count == 0)
{
Log.Warning($"User {userIdOrKey} is not assigned to any regions");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ public async Task<Task> HandleAsync(string consumerName, string key, EdtUserProv
{
{ "FirstName", accessRequestModel.FullName!.Split(' ').FirstOrDefault("NAME_NOT_SET") },
{ "PartyId", accessRequestModel.Key! },
{ "AccessRequestId", "" + accessRequestModel.AccessRequestId },
{ "Tag", msgId! }
};

Expand Down
Loading

0 comments on commit 062ed4e

Please sign in to comment.