Base solution for your next web application
Open Closed

When creating user in any tenant, create same user in default Tenant if not exist? #9468


User avatar
0
bulutyonetim created

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)
  • User Avatar
    0
    ismcagdas created
    Support Team
  • User Avatar
    0
    bulutyonetim created

    Hi,

    Thanks for solution, Domain events are great feature.

  • User Avatar
    0
    bulutyonetim created

    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);
                        }
                    }
                }
            }
    
  • User Avatar
    0
    ismcagdas created
    Support Team

    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.

  • User Avatar
    0
    bulutyonetim created

    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.

  • User Avatar
    0
    ismcagdas created
    Support Team

    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.

  • User Avatar
    0
    bulutyonetim created

    Hi,

    Thanks.

  • User Avatar
    0
    ismcagdas created
    Support Team

    @bulutyonetim I'm closing the issue, please reopen if you can't solve the problem.