Hi,
When creating user in tenant I need to create a user with same properties (username, email, password, ...) in default tenant if it is not already created and add it linked account of that user, Also When a user changes his password in any tenant, I need to change password of all users with same username in any tenant (in defualt tenant also).
what is the best practice to achieve this?
Why I need this, Assume this senario:
- I have enabled multi tenant.
- Person A has two account:
- user1 Acoount on Tenant1
- user2 Acoount on Tenant2 (user1 and user2 should have same username).
I need a way that Person A login into system (defualt tenant) then select tenant (from linked accounts) and continue working. In other mean I don't want to users select tenants before logging in to system.
8 Answer(s)
-
0
Hi,
You can write a domain event to handle this, see https://aspnetboilerplate.com/Pages/Documents/EventBus-Domain-Events#entity-changes.
Here is a similar example, https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp.Zero.Common/Authorization/Users/UserAccountSynchronizer.cs.
-
0
Hi,
Thanks for solution, Domain events are great feature.
-
0
Hi,
I tried to get what I needed with the help of domain events. But I have a problem.
Suppose this: When I create a User1 in tenant A, my domain activity is triggered. In the case of domain, I add the new user with the same attributes to the Default tenant. however, this action triggers my domain activities again.
I am having the same problem updating user information. For example, when I change the user's last name in Tenant A, my domain activity is triggered, so I update the user's last name in Tenant Default, but again this update repeats the triggers domain event.
Any solution to turn off the domain event in a section of the code? Or is there any way to get any information that shows me that the event was routed by the system and not the end user?
Here is my code for recreate user in default tenant:
public virtual void HandleEvent(EntityCreatingEventData<AbpUserBase> eventData) { //If user is not being added to host or default tenant if (eventData.Entity.TenantId != null && eventData.Entity.TenantId != 1) { //Workining on default tenant using (_unitOfWorkManager.Current.SetTenantId(1)) { //Get all users of default tenant IQueryable<User> allUser = _userRepository.GetAll(); //Get user with same email or username var defaultTenantUser = allUser.FirstOrDefault(ua => ua.TenantId == 1 && (ua.UserName == eventData.Entity.UserName || ua.EmailAddress == eventData.Entity.EmailAddress)); //If user with same email or username is not available in default tenant if (defaultTenantUser == null) { //add "User" Role to new user roles var userRoles = new Collection<UserRole>(); var defaultRole = _roleRepository.FirstOrDefault(r => r.Name == Pudux.Authorization.Roles.StaticRoleNames.Tenants.User); userRoles.Add(new UserRole(1, eventData.Entity.Id, defaultRole.Id)); var userToAdd = new User { TenantId = 1, UserName = eventData.Entity.UserName, Name = eventData.Entity.Name, Surname = eventData.Entity.Surname, EmailAddress = eventData.Entity.EmailAddress, Password = eventData.Entity.Password, PasswordResetCode = eventData.Entity.PasswordResetCode, EmailConfirmationCode = eventData.Entity.EmailConfirmationCode, IsActive = eventData.Entity.IsActive, IsDeleted = eventData.Entity.IsDeleted, IsEmailConfirmed = eventData.Entity.IsEmailConfirmed, IsLockoutEnabled = eventData.Entity.IsLockoutEnabled, IsPhoneNumberConfirmed = eventData.Entity.IsPhoneNumberConfirmed, IsTwoFactorEnabled = eventData.Entity.IsTwoFactorEnabled, NormalizedEmailAddress = eventData.Entity.EmailAddress.ToUpperInvariant(), NormalizedUserName = eventData.Entity.UserName.ToUpperInvariant(), Roles = userRoles, }; //add user to default tenants _userRepository.Insert(userToAdd); } } } }
-
0
Hi @bulutyonetim
You are right, it will trigger same event and it will cause an endless loop. Another option would be overriding
CreateAsync
method of UserManager and create duplicate user entity on another tenant. -
0
Hi,
Thanks for answer. What is best practice of overriding
CreateAsync
method of UserManager. I do not want my code be lost when I update my project to lateset Asp.net Zero in future. -
0
Hi @bulutyonetim
You can directly implement it in the UserManager class. We don't modify this class. If we need to make any modifications on CreateAsync method, we basically change the AbpUserManager base class.
-
0
Hi,
Thanks.
-
0
@bulutyonetim I'm closing the issue, please reopen if you can't solve the problem.