Skip to content

Commit

Permalink
fix: account delegation & login
Browse files Browse the repository at this point in the history
  • Loading branch information
jxnkwlp committed Apr 2, 2024
1 parent b76e633 commit ffcc5e8
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 46 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace Passingwind.Abp.Account;

public class AccountUserDelegationCreateDto
public class AccountUserDelegationCreateDto : IValidatableObject
{
public Guid UserId { get; set; }

[Required]
public DateTime StartTime { get; set; }
[Required]
public DateTime EndTime { get; set; }

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (StartTime > EndTime)
{
yield return new ValidationResult(
"The start time cannot be greater than the end time",
new[] { nameof(StartTime), nameof(EndTime) });
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ public interface IAccountImpersonationAppService : IApplicationService
Task LinkLoginAsync(Guid userId);

/// <summary>
/// delegation login
/// Delegation login
/// </summary>
/// <param name="userId"></param>
Task DelegationLoginAsync(Guid userId);
/// <param name="id"></param>
Task DelegationLoginAsync(Guid id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,31 @@ namespace Passingwind.Abp.Account;

public interface IAccountUserDelegationAppService : IApplicationService
{
Task<ListResultDto<AccountUserDelegationDto>> GetMyDelegationListAsync();
/// <summary>
/// Get delegated users
/// </summary>
Task<ListResultDto<AccountUserDelegationDto>> GetMyDelegatedListAsync();

/// <summary>
/// Get my delegated users
/// </summary>
Task<ListResultDto<AccountUserDelegationDto>> GetDelegatedListAsync();

/// <summary>
/// Create new delegation
/// </summary>
/// <param name="input"></param>
Task CreateAsync(AccountUserDelegationCreateDto input);

/// <summary>
/// Delete delegation by id
/// </summary>
/// <param name="id"></param>
Task DeleteAsync(Guid id);

/// <summary>
/// Search user
/// </summary>
/// <param name="filter"></param>
Task<ListResultDto<UserBasicDto>> UserLookupAsync(string? filter = null);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ public class UserBasicDto : EntityDto<Guid>
public string? Name { get; set; }
public string? SurName { get; set; }
public string? Email { get; set; }
public bool IsActive { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
Expand Down Expand Up @@ -65,9 +64,9 @@ public virtual async Task LogoutAsync()

await IdentityOptions.SetAsync();

var user = await UserManager.FindByIdAsync(userId.Value.ToString());
var user = await UserManager.FindByIdAsync(userId.Value.ToString()) ?? throw new UserNotFoundException();

await SignInManager.SignInAsync(user!, false);
await SignInManager.SignInAsync(user, false);
}

[Authorize(IdentityPermissionNamesV2.Users.Impersonation)]
Expand Down Expand Up @@ -101,10 +100,10 @@ public virtual async Task LinkLoginAsync(Guid userId)

if (await LinkUserManager.IsLinkedAsync(source, target, true))
{
await ImpersonateLoginAsync(user);

Logger.LogInformation("User with id '{0}' has been link login by user id '{1}'", user.Id, source.UserId);

await ImpersonateLoginAsync(user);

await SecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Expand All @@ -119,21 +118,23 @@ await SecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
}
}

public virtual async Task DelegationLoginAsync(Guid userId)
public virtual async Task DelegationLoginAsync(Guid id)
{
var delegations = await UserDelegationManager.GetActiveDelegationsAsync(CurrentUser.GetId());
var delegation = await UserDelegationManager.FindActiveDelegationByIdAsync(id);

if (!delegations.Any(x => x.SourceUserId == userId))
// check the delegated is for me.
if (delegation == null || delegation.TargetUserId != CurrentUser.GetId())
{
throw new BusinessException(AccountErrorCodes.UserNotDelegated);
}

var user = await UserManager.GetByIdAsync(userId);

await ImpersonateLoginAsync(user);
// Get the delegation source user
var user = await UserManager.GetByIdAsync(delegation.SourceUserId);

Logger.LogInformation("User with id '{0}' has been delegation login by user id '{1}'", user.Id, CurrentUser.GetId());

await ImpersonateLoginAsync(user);

await SecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,8 @@ public AccountUserDelegationAppService(IIdentityUserRepository userRepository, I
UserDelegationManager = userDelegationManager;
}

public virtual async Task CreateAsync(AccountUserDelegationCreateDto input)
{
if (CurrentUser.FindImpersonatorUserId().HasValue)
{
throw new BusinessException(AccountErrorCodes.UserActionDisabledInDelegatedMode);
}

var user = await UserRepository.FindAsync(input.UserId);

if (user == null)
{
throw new BusinessException(AccountErrorCodes.UserNotFound);
}

await UserDelegationManager.DelegateNewUserAsync(
sourceUserId: CurrentUser.GetId(),
targetUserId: input.UserId,
startTime: input.StartTime,
endTime: input.EndTime);
}

public virtual async Task<ListResultDto<AccountUserDelegationDto>> GetDelegatedListAsync()
/// <inheritdoc/>
public virtual async Task<ListResultDto<AccountUserDelegationDto>> GetMyDelegatedListAsync()
{
var list = await UserDelegationManager.GetListAsync(targetUserId: CurrentUser.GetId());

Expand All @@ -60,7 +40,8 @@ public virtual async Task<ListResultDto<AccountUserDelegationDto>> GetDelegatedL
}));
}

public virtual async Task<ListResultDto<AccountUserDelegationDto>> GetMyDelegationListAsync()
/// <inheritdoc/>
public virtual async Task<ListResultDto<AccountUserDelegationDto>> GetDelegatedListAsync()
{
var list = await UserDelegationManager.GetListAsync(sourceUserId: CurrentUser.GetId());

Expand All @@ -77,6 +58,34 @@ public virtual async Task<ListResultDto<AccountUserDelegationDto>> GetMyDelegati
}));
}

/// <inheritdoc/>
public virtual async Task CreateAsync(AccountUserDelegationCreateDto input)
{
if (CurrentUser.FindImpersonatorUserId().HasValue)
{
throw new BusinessException(AccountErrorCodes.UserActionDisabledInDelegatedMode);
}

if (CurrentUser.Id == input.UserId)
{
throw new BusinessException(AccountErrorCodes.UserNotFound);
}

var user = await UserRepository.FindAsync(input.UserId);

if (user == null)
{
throw new BusinessException(AccountErrorCodes.UserNotFound);
}

await UserDelegationManager.DelegateNewUserAsync(
sourceUserId: CurrentUser.GetId(),
targetUserId: input.UserId,
startTime: input.StartTime,
endTime: input.EndTime);
}

/// <inheritdoc/>
public virtual async Task DeleteAsync(Guid id)
{
if (CurrentUser.FindImpersonatorUserId().HasValue)
Expand All @@ -87,6 +96,7 @@ public virtual async Task DeleteAsync(Guid id)
await UserDelegationManager.DeleteDelegationAsync(id, CurrentUser.GetId());
}

/// <inheritdoc/>
public virtual async Task<ListResultDto<UserBasicDto>> UserLookupAsync(string? filter = null)
{
var list = await UserRepository.GetListAsync(sorting: nameof(IdentityUser.UserName), maxResultCount: 10, filter: filter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public virtual Task LoginAsync(Guid userId)
}

/// <inheritdoc/>
[HttpPost("{userId}/link-login")]
[HttpPost("link/users/{userId}/login")]
public virtual Task LinkLoginAsync(Guid userId)
{
return _service.LinkLoginAsync(userId);
Expand All @@ -39,9 +39,9 @@ public virtual Task LogoutAsync()
}

/// <inheritdoc/>
[HttpPost("{userId}/delegation-login")]
public virtual Task DelegationLoginAsync(Guid userId)
[HttpPost("delegations/{id}/login")]
public virtual Task DelegationLoginAsync(Guid id)
{
return _service.DelegationLoginAsync(userId);
return _service.DelegationLoginAsync(id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ public AccountUserDelegationController(IAccountUserDelegationAppService service)
}

/// <inheritdoc/>
[HttpGet("my-delegations")]
public virtual Task<ListResultDto<AccountUserDelegationDto>> GetMyDelegationListAsync()
[HttpGet("my-delegateds")]
public virtual Task<ListResultDto<AccountUserDelegationDto>> GetMyDelegatedListAsync()
{
return _service.GetMyDelegationListAsync();
return _service.GetMyDelegatedListAsync();
}

/// <inheritdoc/>
Expand Down

0 comments on commit ffcc5e8

Please sign in to comment.