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 ?
Hi,
I was trying to mock IdentityUserManager
Error :
Can not instantiate proxy of class: Volo.Abp.Identity.IdentityUserManager.
Could not find a parameterless constructor.
StackTrace :
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyInstance(Type proxyType, List`1 proxyArguments, Type classToProxy, Object[] constructorArguments)
at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
at NSubstitute.Proxies.CastleDynamicProxy.CastleDynamicProxyFactory.CreateProxyUsingCastleProxyGenerator(Type typeToProxy, Type[] additionalInterfaces, Object[] constructorArguments, IInterceptor[] interceptors, ProxyGenerationOptions proxyGenerationOptions)
at NSubstitute.Proxies.CastleDynamicProxy.CastleDynamicProxyFactory.GenerateTypeProxy(ICallRouter callRouter, Type typeToProxy, Type[] additionalInterfaces, Object[] constructorArguments)
at NSubstitute.Proxies.CastleDynamicProxy.CastleDynamicProxyFactory.GenerateProxy(ICallRouter callRouter, Type typeToProxy, Type[] additionalInterfaces, Object[] constructorArguments)
at NSubstitute.Core.SubstituteFactory.Create(Type[] typesToProxy, Object[] constructorArguments, Boolean callBaseByDefault)
at NSubstitute.Core.SubstituteFactory.Create(Type[] typesToProxy, Object[] constructorArguments)
at NSubstitute.Substitute.For(Type[] typesToProxy, Object[] constructorArguments)
at NSubstitute.Substitute.For[T](Object[] constructorArguments)
at SCV.Litmus.LitmusIdentity.LitmusUserInfoApplicationTests.AfterAddApplication(IServiceCollection services) in D:\Litmus\Projects\ap-ar-dashboard\SCV.Litmus\aspnet-core\modules\litmus-core\test\SCV.Litmus.Application.Tests\LitmusIdentity\LitmusUserInfoApplicationTests.cs:line 26
at Volo.Abp.Testing.AbpIntegratedTest`1..ctor()
at SCV.Litmus.LitmusTestBase`1..ctor()
at SCV.Litmus.LitmusApplicationTestBase..ctor()
at SCV.Litmus.LitmusIdentity.LitmusUserInfoApplicationTests..ctor() in D:\Litmus\Projects\ap-ar-dashboard\SCV.Litmus\aspnet-core\modules\litmus-core\test\SCV.Litmus.Application.Tests\LitmusIdentity\LitmusUserInfoApplicationTests.cs:line 19
My Code :
public class LitmusUserInfoApplicationTests : LitmusApplicationTestBase
{
private readonly ILitmusUserInfoAppService _litmusUserInfoAppService;
private IdentityUserManager _identityUserManager;
public LitmusUserInfoApplicationTests()
{
_litmusUserInfoAppService = GetRequiredService<ILitmusUserInfoAppService>();
}
protected override void AfterAddApplication(IServiceCollection services)
{
_identityUserManager = Substitute.For<IdentityUserManager>();
services.AddSingleton(_identityUserManager);
}
[Fact]
public async Task GetSellerQuestionnaireForMakerCheckAsync()
{
_identityUserManager.FindByIdAsync("39faa1bb-6509-6a7d-b17f-0deee2cf47db")
.Returns(Task.FromResult(JsonConvert.DeserializeObject<IdentityUser>(@"{
'TenantId': 'd1be844b-d3a2-031a-f036-39f5d4380239',
'UserName': 'Seller.Admin',
'NormalizedUserName': 'SELLER.ADMIN',
'Name': 'Seller',
'Surname': 'Admin',
'Email': 'seller.admin@ness.com',
'NormalizedEmail': 'LALIT.CHOUGULE@NESS.COM',
'EmailConfirmed': false,
'PasswordHash': 'AQAAAAEAACcQAAAAEOK/7B0qge7madNnCVW5zGiVxa7sgIYc7XIKR/wG+fuDFn2g28hDGmd/i34RV/Rc8Q==',
'SecurityStamp': 'CUICLIBP3N5Z7NV52SKWF2MHBRIGDEPZ',
'PhoneNumber': null,
'PhoneNumberConfirmed': false,
'TwoFactorEnabled': true,
'LockoutEnd': null,
'LockoutEnabled': true,
'AccessFailedCount': 0,
'Roles': [
{
'TenantId': 'd1be844b-d3a2-031a-f036-39f5d4380239',
'UserId': '39fd4aa9-8553-35c0-4312-0d7b5f01b810',
'RoleId': '39fc43a0-e722-2bc3-7d24-9cc6992ccd3a'
}
],
'Claims': [],
'Logins': [],
'Tokens': [],
'OrganizationUnits': [],
'IsDeleted': false,
'DeleterId': null,
'DeletionTime': null,
'LastModificationTime': '2021-06-23T16:22:02.440744',
'LastModifierId': null,
'CreationTime': '2021-06-23T16:18:53.936857',
'CreatorId': '1c26f3a7-fa8f-dbaf-406b-39f5d443409f',
'ExtraProperties': {
'PasswordSetDate': '2021-09-21T10:50:14.4543311Z',
'HaveOptedMakerChecker': true
},
'ConcurrencyStamp': '5224e087605a4f498a9684556b5506dc',
'Id': '39fd4aa9-8553-35c0-4312-0d7b5f01b810'
}")));
var mock_sellerRequesterUsers = @"[
{
'TenantId': 'd1be844b-d3a2-031a-f036-39f5d4380239',
'UserName': 'Seller.Requester',
'NormalizedUserName': 'SELLER.REQUESTER',
'Name': 'Seller',
'Surname': 'Requester',
'Email': 'Kaustubh.Kale@ness.com',
'NormalizedEmail': 'KAUSTUBH.KALE@NESS.COM',
'EmailConfirmed': false,
'PasswordHash': 'AQAAAAEAACcQAAAAEFCPsMT+tOATxKorhUkndGa1/k3SOjnx3+emm2sWafeYlVvcnDFnSeP0k5uXlgYJwA==',
'SecurityStamp': 'NUUY6ROI2NTZ7UBM2FBDHZBKP5UPXS7B',
'PhoneNumber': null,
'PhoneNumberConfirmed': false,
'TwoFactorEnabled': true,
'LockoutEnd': null,
'LockoutEnabled': true,
'AccessFailedCount': 0,
'Roles': null,
'Claims': null,
'Logins': null,
'Tokens': null,
'OrganizationUnits': null,
'IsDeleted': false,
'DeleterId': null,
'DeletionTime': null,
'LastModificationTime': '2021-06-23T16:30:40.180889',
'LastModifierId': '1c26f3a7-fa8f-dbaf-406b-39f5d443409f',
'CreationTime': '2021-06-23T16:30:29.23093',
'CreatorId': '1c26f3a7-fa8f-dbaf-406b-39f5d443409f',
'ExtraProperties': {
'PasswordSetDate': '2021-09-21T11:00:28.4022237Z',
'HaveOptedMakerChecker': false
},
'ConcurrencyStamp': '0b7b68128a81401fbc6fa3f91e36b3f3',
'Id': '39fd4ab4-2271-7518-4964-a131224f8919'
}
]";
_identityUserManager.GetUsersInRoleAsync("SellerRequester")
.Returns(Task.FromResult(JsonConvert.DeserializeObject<IList<IdentityUser>>(mock_sellerRequesterUsers)));
var mock_sellerApproverUsers = @"[
{
'TenantId': 'd1be844b-d3a2-031a-f036-39f5d4380239',
'UserName': 'Seller.Approver',
'NormalizedUserName': 'SELLER.APPROVER',
'Name': 'Seller',
'Surname': 'Approver',
'Email': 'Yaduraj.Shakti@ness.com',
'NormalizedEmail': 'YADURAJ.SHAKTI@NESS.COM',
'EmailConfirmed': false,
'PasswordHash': 'AQAAAAEAACcQAAAAEJkl+HrzdX1HQPWcLTvhmgtiibs2F4pX4avyk4UxK6iHFSCa5Ca4/VyNxVgyY47xIA==',
'SecurityStamp': 'TUOGMEIA2RJSFMXCKARFLZO2XSK2QWCA',
'PhoneNumber': null,
'PhoneNumberConfirmed': false,
'TwoFactorEnabled': true,
'LockoutEnd': null,
'LockoutEnabled': true,
'AccessFailedCount': 0,
'Roles': null,
'Claims': null,
'Logins': null,
'Tokens': null,
'OrganizationUnits': null,
'IsDeleted': false,
'DeleterId': null,
'DeletionTime': null,
'LastModificationTime': '2021-06-23T16:29:45.804466',
'LastModifierId': '1c26f3a7-fa8f-dbaf-406b-39f5d443409f',
'CreationTime': '2021-06-23T16:29:33.925747',
'CreatorId': '1c26f3a7-fa8f-dbaf-406b-39f5d443409f',
'ExtraProperties': {
'PasswordSetDate': '2021-09-21T10:59:32.8141291Z',
'HaveOptedMakerChecker': false
},
'ConcurrencyStamp': '7d9f64db3fa74b2b827940360d2b5185',
'Id': '39fd4ab3-494d-9f88-56ac-e9b402130a4d'
}
]";
_identityUserManager.GetUsersInRoleAsync("SellerApprover")
.Returns(Task.FromResult(JsonConvert.DeserializeObject<IList<IdentityUser>>(mock_sellerApproverUsers)));
var result = await _litmusUserInfoAppService.GetSellerQuestionnaireInfoAsync();
}
}
How do I mock IdentityUserManager ?
Can we have a session ? May be you can figure it out if you have a look ? It's bit urgent as my app is about to go live in few days.