Aktivity „alexander.nikonov“

Could you please make a test project demonstrating how to accomplish our goal? I've spent a lot of time searching for solution on stackoverflow, analyzing ABP code, etc. and I am far behind the schedule. But the solution is still not working.

The pieces of code I have ended up with are the following:

        [Authorize]
        public async Task<PagedResultDto<LookupDto<string>>> GetTenantsForCurrentUser()
        {
            if (!CurrentUser.IsAuthenticated)
                return null;

            var items = await _abxUserRepository.FindTenantsByLoginAsync(CurrentUser.UserName);

            return new PagedResultDto<LookupDto<string>>
            {
                TotalCount = items.Count(),
                Items = ObjectMapper.Map<List<Tenant>, List<LookupDto<string>>>(items)
            };
        }
        
       <div *ngIf="user.isAuthenticated" class="dropdown btn-group" ngbDropdown>
          <a
            class="btn"
            role="button"
            id="dropdownMenuTenantsLink"
            ngbDropdownToggle
            *ngIf="(selectedTenant$ | async)?.name as tenantName"
          >
            <span>{{ '::Tenants:CurrentTenant' | abpLocalization }}: <b>{{ tenantName }}</b></span>
          </a>
          <div
            ngbDropdownMenu
            class="dropdown-menu dropdown-menu-right"
            *ngIf="dropdownTenants$ | async"
          >
            <h6 class="dropdown-header">{{ '::Tenants:SwitchTenant' | abpLocalization }}</h6>
            <a
              *ngFor="let tenant of dropdownTenants$ | async"
              class="dropdown-item pointer"
              (click)="switchTenant(user.userName, tenant)"
            >
              {{ tenant.displayName }}</a
            >
          </div>
        </div>
        
  switchTenant(userName: string, tenant: Common.Lookup<string>) {
    this.oAuthService.configure(
      this.store.selectSnapshot(ConfigState.getOne('environment')).oAuthConfig,
    );

    return from(this.oAuthService.loadDiscoveryDocument())
      .pipe(
          switchMap(() =>
              from(
                  this.oAuthService.fetchTokenUsingGrant(
                      'Custom', // why we cannot use own name??
                      null,
                      new HttpHeaders(
                        { ...(tenant.id && { __tenant: tenant.id })}
                        && (userName && { user: userName })
                      )
                  ),
              ),
          ),
          switchMap(() => this.store.dispatch(new GetAppConfiguration())),
          tap(() => {
              const redirectUrl =
              snq(() => window.history.state.redirectUrl) || (this.options || {}).redirectUrl || '/';
              this.store.dispatch(new Navigate([redirectUrl]));
          }),
          take(1),
      ).subscribe(() => {});
  }

All in all, the idea is:

  1. in app service layer to get the list of all tenants for current user (login name) - see above;

  2. fill dropdown of tenants for passwordless login and supply the tenant id for each entry - see above;

  3. make request from Angular app (using oAuthService->[some passwordless workflow?]) supplying the access token of currently authenticated user, some custom passwordless grant-type and tenant id in order to login (custom extension validator is going to intercept this request on server-side and approve or reject the login).

  4. is the most tricky part, since OAuthService still does not support custom grant type. I've tried to patch the latest angular-oauth2-oidc from github (10.x) and add fetchTokenUsingGrant, but how to update our solution to the patched version? Your framework uses this package inside and I even cannot see angular-oauth2-oidc via npm outdated.

Hi, where I can find information (or better - test examples) how to work with Identity Server in ABP? Generate tokens, use Identity resources, grant types, etc. I saw doc on abp.io, but Identity Server section is very scarse. In fact, I'd like to know what each parameter in Identity Server section in Angular app means and how it is supposed to be used.

Hi,

thank you, would give it a try, but two questions right away:

Change permissions about tenants scope

where this needs to be placed?

public class TenantInfo : AggregateRoot, IMultiTenant

we already use the table for our Tenant entity (it has Id and MasterId for tenant id and master tenant id correspondingly). It also has 1:1 ABP tenant entity:

    public class Tenant : SoftDeleteLogEntity<int>
    {
        ...
        public int? MasterId { get; set; }
        public Tenant MasterTenant { get; set; }
        public Guid AbpId { get; set; } // it is ABP tenant's id
        public AbpTenant AbpTenant { get; set; } // it is ABP tenant
        ...
    }
        
    public abstract class SoftDeleteLogEntity<TKey> : LogEntity<TKey>, IMayHaveDeleterName, ISoftDelete, IDeletionAuditedObject {...}
    public abstract class LogEntity<TKey> : AuditedEntity<TKey>, IMayHaveCreatorName, IMayHaveLastModifierName {...}

but we did not implement IMultiTenant. Now, when I'd like to do that - I can see TenantId has to be Guid, but in our table Id (MasterId too, accordingly) is Integer (it was customer's decision)... How to overcome this problem? Is it OK just to implement a 'fake' Guid TenantId field and not use it?

Thank you - will consider this!

Everything seems to be working good. But one complaint: speed. For some reason, login - just like a tenant creation - takes very long, despite the fact we are in local network (well, DB is on Azure cloud actually). Is it possible to trace somehow to make sure it's DB problem or not?

Hi,

switching current tenant works - thank you. But as to the first part of the question... we would prefer to authenticate and log in identity user after finding him in the repository, I hoped something like this would work (not dealing with password):

        using var _ = _abpCurrentTenant.Change(tenantId);

        var currentTenant = await _abxTenantRepository.FirstOrDefaultAsync(x => x.AbpId == _abpCurrentTenant.Id.Value);
        var identityUser = await _identityUserRepository.FindByNormalizedUserNameAsync(abxUser.Login.ToUpper());
        await _signInManager.SignInAsync(identityUser, true);

        return ObjectMapper.Map<Tenant, TenantDto>(currentTenant);

However, this does not work.

Am I on right track, all in all? What do I need to make this work (to make our IdentityServer take care on authenticating the selected identityUser and logging him in automatically, it needs to look like a simple page reload)?

liangshiwei, thank you very much for your invaluable help! Our test team will check transactions thouroughly with standard driver to make sure the problem went away. And I will be able to close the ticket, if so.

Already tried that, but for some reason it does not work - probably, it does not work with Oracle. Is it possible for you to try transaction thing witn Devart provider (while I am stuck on case mismatch issue) so I was sure the lock was really a Devart problem? Thank you. P.S. How to implement something kind of DB query inteceptor (where I can remove quotes, etc.) by means of ABP framework? This thing did not work:

        Configure&lt;AbpDbContextOptions&gt;(options =>
        {
            options.UseOracle(oracleDbContextOptionsBuilder =>
            {
                var dbContextOptionsBuilder = new DbContextOptionsBuilder();
                dbContextOptionsBuilder.AddInterceptors(new RemoveQuotesInterceptor());
                oracleDbContextOptionsBuilder = new Oracle.EntityFrameworkCore.Infrastructure.OracleDbContextOptionsBuilder(dbContextOptionsBuilder);
            });
        });

Hi, I was unable to run the solution without Devart driver. We have uppercased table names and column names. Devart driver setting below eliminates quotes around object names in the generated queries. As a result, queries are not case-sensitive. If Devart driver is not used - the queries contain quotes and tables / columns are not found - "ORA-00942: table or view does not exist":

public class qaEntityFrameworkCoreModule : AbpModule
{
    ...
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        ...
        Configure&lt;AbpDbContextOptions&gt;(options =>
        {
            var config = Devart.Data.Oracle.Entity.Configuration.OracleEntityProviderConfig.Instance;
            config.Workarounds.DisableQuoting = true;
            ...
        }
    }
}

Do you by chance know the setting how to achieve the same result without Devart? This setting works only if using Devart Oracle driver, not official driver.

Please be aware we have DB-first solution! Our local DB tables are already created - so we don't want our solution to depend on the code (e.g. make the code setting to generate all the tables in lower- or upper-case). We would like to ignore case instead.

Hi.

We are using commercial version of ABP framework - so it took me some time to change your project to using it instead of free version.

I have replaced TenantManagement projects to Saas projects. There are some other changes. I have also changed the view of QaTenant entity to match our entity.

And I was able to reproduce the lock issue. Please have a look at ABP Tenant transaction deadlock

Looking for your reply ASAP, since we really need transactions.

Zobrazených 211 až 220 z 230 záznamov
Made with ❤️ on ABP v8.2.0-preview Updated on marca 25, 2024, 15:11