Hi
I tried using https://docs.abp.io/en/abp/latest/Object-Extensions#setproperty for "PropertyAdded" i.e. IsActive
By using below code
public async Task<bool> MakeUserInactive(string userId)
{
var user = await _identityUserManager.FindByIdAsync(userId);
var context = await _userRepository.GetDbContextAsync();
context.Entry<Volo.Abp.Identity.IdentityUser>(user).Property("IsActive").CurrentValue = false;
await CurrentUnitOfWork.SaveChangesAsync();
return true;
}
Getting error : The property 'IdentityUser.IsActive' could not be found. Ensure that the property exists and has been included in the model.
And By using below code :
public async Task<bool> MakeUserInactive(string userId)
{
var user = await _identityUserManager.FindByIdAsync(userId);
user.SetProperty("IsActive", false);
return true;
}
IsActive is set in ExtraProperties but the column value of IsActive remains true.
#2 My Validator class :
public class LitmusUserValidator<TUser> : IUserValidator<TUser> where TUser : Volo.Abp.Identity.IdentityUser
{
private readonly IIdentityUserRepository _userRepository;
public LitmusUserValidator(IIdentityUserRepository userRepository)
{
_userRepository = userRepository;
}
public async Task<IdentityResult> ValidateAsync(UserManager<TUser> manager, TUser user)
{
var errors = new List<IdentityError>();
var users = (await _userRepository.GetDbSetAsync())
.Where(x => EF.Property<bool>(x, "IsActive") == false
&& EF.Property<Guid>(x, "Id") == user.Id)
.ToListAsync();
//Used list in above code because I am not able to access "IsActive" i.e. Custom property added on single object.
if(users.Result.Count != 0)
{
errors.Add(new IdentityError
{
Description = "User with InActive status cannot login"
});
}
return errors.Any()
? IdentityResult.Failed(errors.ToArray())
: IdentityResult.Success;
}
}
LitmusIdentityServerModule : My debugger didn't even hit this LitmusUserValidator ValidateAsync method while logging in I was able to login with user having "IsActive" == false;
public override void ConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<IdentityBuilder>(options => {
options.AddUserValidator<LitmusUserValidator<Volo.Abp.Identity.IdentityUser>>();
});
}
- Use EF Core API
see : https://docs.abp.io/en/abp/latest/Entity-Framework-Core#access-to-the-ef-core-api
var users = (await _userRepository.GetDbSetAsync()).Where(x => EF.Property<int>(x, "PropertyAdded") == 1).ToListAsync();
Is there a way where I find one item of this list and want to update its "PropertyAdded" column. How do I do this ?
You can use the
IUserValidator
See https://github.com/abpframework/abp/issues/3990
Is there any abp.io document where implementation of UserValidator class is provided ? Can you provide me sample of this class ? And how can I find my custom column here ?
In the below code there is one option called options.SignIn.RequireConfirmedEmail
If I would able to find my added column here I think it will resolve my issue.
IdentityServerModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
Configure<IdentityOptions>(options =>
{
options.User.AllowedUserNameCharacters = null;
//options.SignIn.RequireConfirmedEmail <-- talking about this above
});
}
I have one more requirement but It depends on the above case to work. Post successfull implementation of above usecase , I need to check while logging in to the application If the user is having some StatusId I dont want to generate token or you can say I dont want that user to login to the application and give some custom message saying you are in this status you can login once administrator change your status etc. etc.
How can I achieve this and where to do respective changes. Please do revert on this requirement.
Hi liangshiwei,
I can do this but the problem with this approach is I need to do changes in many files I have done alot of custom logic implementation in IdentityUserAppService and IdentityRoleAppServcice.
This is abp's method IdentityUserAppService :-
[Authorize(IdentityPermissions.Users.Default)]
public virtual async Task<PagedResultDto<IdentityUserDto>> GetListAsync(GetIdentityUsersInput input)
{
//What I want is as below
//Want to fetch all the users with StatusId == 1 (StatusId i.e. Column added to IdentityUser) -- I am stuck in this part
//Then apply paging logic
var count = await UserRepository.GetCountAsync(input.Filter);
var list = await UserRepository.GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount, input.Filter);
return new PagedResultDto<IdentityUserDto>(
count,
ObjectMapper.Map<List<IdentityUser>, List<IdentityUserDto>>(list)
);
}
Or else is there a way where I can override UserRepository.GetListAsync() where I can pass StatusId value
and get all the user only with those StatusId.
Similarly for roles I have two module for which I need to categorize my Roles
| RoleName | Category | | --- | --- | | AnchorAdmin | CatA | | ProgramAdmin | CatB |
And while fetching roles via. RoleRepository.GetListAsync()
suppose I want roles only specific for CatA
.
How do I do this ?
Basically what I need is how to get the added extra column via. RoleRepository.GetListAsync()
or UserRepository.GetListAsync()
on which I can apply where clause or something as per my requirement.
Or else Is there a way where I can use IRepository<AbpUser,Guid>
or IRepository<AbpUserRole,Guid>
like this to directly query it from AppService or say from overridden MyIdentityUserAppService
?
If yes please provide some sample code if possible.
I hope you got my requirement now ?
Hi liangshiwei,
I'm sorry but I was not able to implement this : https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.ef.property?view=efcore-5.0#examples in my project. Can you provide me some sample code how to implement it in abp.io project. It will be really appreciable
Hi,
I refered https://docs.abp.io/en/abp/4.4/Authorization#iauthorizationservice document.
throw new AbpAuthorizationException("...");
this line of code should throw Authorization Failed error, but instead it is throwing Interval Server Error
I want to throw Authorization Failed error on certain permission check (custom logic).
I need to add one column to AbpUsers table which I can use while querying abpUsers table I followed this https://docs.abp.io/en/abp/4.4/Customizing-Application-Modules-Extending-Entities#entity-extensions-ef-core
I was able to do migration and update-database. Column was created in database but I was not able to find the column while querying.
var allUsers = await UserRepository.GetListAsync();
var myConditionalUsers = allUsers.Where(x => x.PropertyAdded == 1).ToList();
Not able to find PropertyAdded
Can you provide quick solution?
Hi maliming,
public async Task<List<string>> GetAdminUsernames(CancellationToken cancellationToken = default)
{
await EnsureConnectionOpenAsync(cancellationToken);
using (var command = CreateCommand("SELECT * FROM dbo.UserAdminView", CommandType.Text))
{
using (var dataReader = await command.ExecuteReaderAsync(cancellationToken))
{
var result = new List<string>();
while (await dataReader.ReadAsync(cancellationToken))
{
result.Add(dataReader["UserName"].ToString());
}
return result;
}
}
}
Is this the only way to query view ? Can't we access it like normal query i.e.
_someViewRepository.Where(x=> x.SomeValue == SomeValue).GroupBy(..)...
Hi,
I am using PostgreSQL and I have created few views in my database. How do I query those views in my AppService ?
DbSet<ViewName>/DbQuery<ViewName>
Can you please provide step by step Implementation guide? I will be very helpful.
Thanks
Hi cotur,
I was partially achieve your solution. But I have hit a dead end while seeding Roles
My Code :
public class IdentityRolesDataSeedContributor : IDataSeedContributor, ITransientDependency
{
private readonly IRepository<IdentityRole> _identityRoleRepository;
public IdentityRolesDataSeedContributor(IRepository<IdentityRole> identityRoleRepository)
{
_identityRoleRepository = identityRoleRepository;
}
public async Task SeedAsync(DataSeedContext context)
{
await _identityRoleRepository.InsertAsync(new IdentityRole(
id: Guid.Parse("60353FF7-0F81-4DD5-AC1F-6F9559037720"),
name: "RoleAbc",
tenantId: Guid.Parse("d1be844b-d3a2-031a-f036-39f5d4380239")));
}
}
Error while unit testing :
---------- Starting test run ----------
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.2+2d84eb3141 (64-bit .NET Core 3.1.13)
[xUnit.net 00:00:02.63] Starting: SCV.Litmus.Application.Tests
[xUnit.net 00:00:15.39] SCV.Litmus.LitmusIdentity.LitmusIdentityUserApplicationTests.CreateAsync [FAIL]
[xUnit.net 00:00:15.39] System.InvalidOperationException : Role ROLEABC does not exist!
[xUnit.net 00:00:15.39] Stack Trace:
[xUnit.net 00:00:15.39] at Volo.Abp.Identity.IdentityUserStore.AddToRoleAsync(IdentityUser user, String normalizedRoleName, CancellationToken cancellationToken)
[xUnit.net 00:00:15.39] at Microsoft.AspNetCore.Identity.UserManager`1.AddToRolesAsync(TUser user, IEnumerable`1 roles)
[xUnit.net 00:00:15.39] at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
[xUnit.net 00:00:15.39] at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
[xUnit.net 00:00:15.39] at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
[xUnit.net 00:00:15.39] at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
[xUnit.net 00:00:15.39] at Volo.Abp.Identity.IdentityUserManager.SetRolesAsync(IdentityUser user, IEnumerable`1 roleNames)
[xUnit.net 00:00:15.39] at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
[xUnit.net 00:00:15.39] at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
[xUnit.net 00:00:15.39] at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
[xUnit.net 00:00:15.39] at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
[xUnit.net 00:00:15.39] at Volo.Abp.Identity.IdentityUserAppService.UpdateUserByInput(IdentityUser user, IdentityUserCreateOrUpdateDtoBase input)
[xUnit.net 00:00:15.40] D:\Litmus\Projects\ap-ar-dashboard\SCV.Litmus\aspnet-core\modules\litmus-core\src\SCV.Litmus.Application\LitmusIdentity\LitmusIdentityUserAppService.cs(106,0): at SCV.Litmus.LitmusIdentity.LitmusIdentityUserAppService.CreateAsync(IdentityUserCreateDto input)
[xUnit.net 00:00:15.40] at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
[xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
[xUnit.net 00:00:15.40] at Volo.Abp.Authorization.AuthorizationInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
[xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
[xUnit.net 00:00:15.40] at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
[xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
[xUnit.net 00:00:15.40] at Volo.Abp.Auditing.AuditingInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
[xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
[xUnit.net 00:00:15.40] at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
[xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
[xUnit.net 00:00:15.40] at Volo.Abp.Validation.ValidationInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
[xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
[xUnit.net 00:00:15.40] at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
[xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
[xUnit.net 00:00:15.40] at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
[xUnit.net 00:00:15.40] at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
[xUnit.net 00:00:15.40] D:\Litmus\Projects\ap-ar-dashboard\SCV.Litmus\aspnet-core\modules\litmus-core\test\SCV.Litmus.Application.Tests\LitmusIdentity\LitmusIdentityUserApplicationTests.cs(89,0): at SCV.Litmus.LitmusIdentity.LitmusIdentityUserApplicationTests.CreateAsync()
[xUnit.net 00:00:15.40] --- End of stack trace from previous location where exception was thrown ---
[xUnit.net 00:00:15.42] Finished: SCV.Litmus.Application.Tests
========== Test run finished: 1 Tests run in 17.2 sec (0 Passed, 1 Failed, 0 Skipped) ==========
Can you tell me what I am doing wrong here ?