Activities of "abhisheksreesaila"

thank you!

Overall Goal :

Enabled users to self register + Assign a **new **database for each new user.


Problem I was calling var result = await base.OnPostAsync(); which registers a user in the host. a new tenant with a admin role with the same email address was the duplicate email.

Solution : I override the post async and remove the RegisterLocalUserAsync which solved the duplicate email. I dont want to store this user in the host


Current Problem: Attached the current code. https://drive.google.com/file/d/10yTLcz5QeiZ8Gy7FulbGPP5YzeOC_2UZ/view?usp=sharing Attached the current logs : https://drive.google.com/file/d/1eu1ukcUamo0Lrd-50aNEpkmWE6YdzlxK/view?usp=sharing

this is needed for a TENANT with a new database to be created. ** await _dbSchemaMigrator.MigrateAsync();**

This line is needed for the USERNAME to have the same name entered in the registration OR else the default admin name "admin" is used. ** await _dataSeeder.SeedAsync(new DataSeedContext(tenant.Id) .WithProperty(IdentityDataSeedContributor.AdminEmailPropertyName, Input.EmailAddress) .WithProperty(IdentityDataSeedContributor.AdminPasswordPropertyName, Input.Password) .WithProperty(IdentityDataSeedContributor.AdminUserNamePropertyName, Input.UserName)); **

If I use both, I get a transient failure to ABP permission grants. How do i resolve the issue?

this is happening every time during the initial registration. Lets say, you have USER100, it will say USER100 is duplicate because the migration are running twice.

DUPS EMAIL ISSUE

I am spinning up a new database with a new user. this is the only user in the whole database. then its says duplicate email found.

  • Problem // its called the base.onpostsync() -- which adds the user.
  • Then we are creating a new tenant with an admin user with the same email and id. I think that' s the problem.
  • Do you agree?

What code changes do you suggest? we want to make use of all the code in the base class except make sure to have a seperate db for each user.

This is closely related to the https://abp.io/support/questions/8116/Change-default-admin-name-to-the-provided-USER-NAME-when-creating-a-new-tenant

It didnt completely resolve the problem.

Good News Code below

  • Create a new tenant with a new database (works)
  • Create a ADMIN USER with a USER NAME provided in the registration page (works)

However, 2 problems **

  1. Duplicate Email Issue However, I see this error in the logs --> https://drive.google.com/file/d/1-fctzIxKqW5zSgSvLGbjCdaWh31mvWAV/view?usp=sharing

  2. Once we resolve #1, how do we assign custom permission to the admin user. This will be customer facing app - so i dont want the admin to meddle with CMS KIT, View Security Logs, Audit Logs etc. I just want him to look at APP pages that i created + Add new users if he wants to. Is that possible. The code below for permission is a simple prototype I was trying - but even that didnt work.

PLEASE Help.

*** removing import statement for brevity ******

namespace Janvika.Finxplorer.Blazor.Pages.Account
{
    public class CustomRegisterModel : RegisterModel
    {
        private readonly ITenantAppService _tenantAppService;
        private readonly IConfiguration _configuration;
        private readonly IdentityUserManager _identityUserManager;
        private readonly IUnitOfWorkManager _unitOfWorkManager;
        private readonly ILogger<CustomRegisterModel> _logger;
        private readonly IFinxplorerDbSchemaMigrator _dbSchemaMigrator;
        private readonly ICurrentTenant _currentTenant;
        private readonly IDataSeeder _dataSeeder;
        private readonly IIdentityRoleRepository _roleRepository;
        private readonly IPermissionManager _permissionManager;

        public CustomRegisterModel(
            IAuthenticationSchemeProvider schemeProvider,
            IOptions<AbpAccountOptions> accountOptions,
            IAccountExternalProviderAppService accountExternalProviderAppService,
            ICurrentPrincipalAccessor currentPrincipalAccessor,
            IHttpClientFactory httpClientFactory,
            ITenantAppService tenantAppService,
            IConfiguration configuration,
            IdentityUserManager identityUserManager,
            IUnitOfWorkManager unitOfWorkManager,
            ILogger<CustomRegisterModel> logger,
            IFinxplorerDbSchemaMigrator dbSchemaMigrator,
            ICurrentTenant currentTenant,
            IDataSeeder dataSeeder,
            IIdentityRoleRepository roleRepository,
            IPermissionManager permissionManager
        ) : base(schemeProvider, accountOptions, accountExternalProviderAppService, currentPrincipalAccessor, httpClientFactory)
        {
            _tenantAppService = tenantAppService;
            _configuration = configuration;
            _identityUserManager = identityUserManager;
            _unitOfWorkManager = unitOfWorkManager;
            _logger = logger;
            _dbSchemaMigrator = dbSchemaMigrator;
            _currentTenant = currentTenant;
            _dataSeeder = dataSeeder;
            _roleRepository = roleRepository;
            _permissionManager = permissionManager;
        }

        public override async Task<IActionResult> OnPostAsync()
        {

               // Call the base OnPostAsync method to retain the base functionality
            var result = await base.OnPostAsync();
            if (!ModelState.IsValid)
            {
                return result;
            }

            try
            {
                var tenantName = $"{Input.UserName}-dedicated-tenant";
                var defaultConnectionString = _configuration.GetConnectionString("Default");

                if (string.IsNullOrEmpty(defaultConnectionString))
                {
                    throw new Exception("Default connection string is not configured in app settings.");
                }

                // Create the database for the new tenant
                var tenantConnectionString = CreateTenantSpecificConnectionString(defaultConnectionString, tenantName);

                SaasTenantDto tenant;
                using (var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
                {
                    var tenantCreateDto = new SaasTenantCreateDto
                    {
                        Name = tenantName,
                        AdminEmailAddress = Input.EmailAddress,
                        AdminPassword = Input.Password,
                        ConnectionStrings = new SaasTenantConnectionStringsDto
                        {
                            Default = tenantConnectionString
                        }
                    };

                    tenant = await _tenantAppService.CreateAsync(tenantCreateDto);

                    await MigrateAndSeedTenantDatabaseAsync(tenant.Id);

                    // Assign permissions to the existing admin role
                    await AssignPermissionsToAdminRoleAsync(tenant.Id);

                    await uow.CompleteAsync();
                }


                    // Migrate and seed the tenant database
              

            

                // Redirect to the login page
                return RedirectToPage("./Login");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "An error occurred during registration");
                // Redirect to the login page
                return RedirectToPage("./Login");
            }
        }

        private string CreateTenantSpecificConnectionString(string defaultConnectionString, string tenantName)
        {
            var builder = new NpgsqlConnectionStringBuilder(defaultConnectionString);
            builder.Database = tenantName;
            return builder.ConnectionString;
        }

        private async Task MigrateAndSeedTenantDatabaseAsync(Guid tenantId)
        {
            using (_currentTenant.Change(tenantId))
            {
              await _dbSchemaMigrator.MigrateAsync();

              
              await _dataSeeder.SeedAsync(
                    new DataSeedContext(tenantId)
                    .WithProperty(IdentityDataSeedContributor.AdminEmailPropertyName, Input.EmailAddress)
                    .WithProperty(IdentityDataSeedContributor.AdminUserNamePropertyName, Input.UserName)
                    .WithProperty(IdentityDataSeedContributor.AdminPasswordPropertyName, Input.Password)
                    
                    );
        
           
            
            }
        }

        private async Task AssignPermissionsToAdminRoleAsync(Guid tenantId)
        {
            using (_currentTenant.Change(tenantId))
            {
                // Find the existing admin role
                var adminRole = await _roleRepository.FindByNormalizedNameAsync("ADMIN");
                if (adminRole == null)
                {
                    throw new Exception("Admin role not found.");
                }

         
                var permissions = new[] { "My.CUSTOM" }; // permission names
                foreach (var permission in permissions)
                {
                    await _permissionManager.SetForRoleAsync(adminRole.Name, permission, true);
                }

                // Assign admin role to the registered user
                var user = await _identityUserManager.FindByEmailAsync(Input.EmailAddress);
                if (user != null)
                {
                    await _identityUserManager.AddToRoleAsync(user, adminRole.Name);
                }
            }
        }
    }
}

yes that worked like a charm! thanks you.

Its working when you are adding text, however the button is not rendering. do you have any ideas? I have not added any custom code. Just copy paste the same code from the source module.

Thanks! I was able to get the the test page working too. it could be an issue with the script itself I wonder. atleast I can proceed at this point. Thank you for the fast response

Apologies. I read it as Auth Server (for angular only).

I tried adding that to the blazor project (server) but it didnt work.

I dont have "auth server" project now. How i can add it?

I already have a solution. Can i add a "auth server" project now? or create a new solution and transfer my code?

I see, makes sense. Let me try that and close this issue

Showing 1 to 10 of 16 entries
Made with ❤️ on ABP v9.1.0-preview. Updated on December 13, 2024, 06:09