Activities of "alexander.nikonov"

Thank you! Will be waiting. Also please suggest me how to logout directly to Identity Server Login box without visiting intermediate root page (Home page). I was trying to find the way (like editing SignOut URLs in Identity Server settings via admin UI page), but it did not bring me anywhere. I believe this used to work properly in some previous ABP version. Maybe we have unintentionally have changed some relevant setting.

Hi Anjali.

Don't want to upset you, but it's even worse now: the mentioned API call is still GET called after I press 'Logout'. But now after I'm doing this - I never gets logged out: after several chaning screens I'm eventually redirected to the root page, i.e. Home page...

Hi Anjali,

i've run debug again.

  1. when I click "Logout" on Home page - the onInit method IS get triggered with expected this.authService.isAuthenticated == false. But prior to that, I'm already getting 401 error request (sometimes - only this one request, sometimes - another one too): The "initiator" there is shown as "zone.js", later on it's getting cleared. So it's still looking confusing.

  2. our users complain about being redirected to landing page "Login" dialog, then - to Identity Server "Login" dialog (as shown on second screenshot). The request is to be redirected to the second "Login" dialog straight away... How to do that?

Hi Anjali.

I have to reopen this ticket, because without using this.routesService.refresh() it appeared, that sometimes just setting items to invisible is not enough: menu is still shown complete (suprisingly - sometimes it DOES work properly - when navigating to specific page menu is rebuilt according to invisibility of items). But using this.routesService.refresh() makes combineLatest trigger again. Could you please suggest the changed code - where the menu always refreshes properly, but there are no extra unnecessary invocations?

      init() {
        this.routesService.flat.filter(x => x.requiredPolicy && (x as any).data?.moduleId).forEach(x => x.invisible = true);
        this.routesService.refresh(); // HAVE TO USE IT to make invisibility to have effect
        combineLatest([this.configStateService.getDeep$('extraProperties.modulePermissionMap'), this.routesService.flat$.pipe(take(1))])
          .pipe
          (
            filter(([modulePermissionMap, route]) => Object.keys(modulePermissionMap).length > 0 && Object.keys(route).length > 0),
            takeUntil(this.destroy)
          )
          .subscribe(([modulePermissionMap, nonLazyLoadedRoute])  => {
            nonLazyLoadedRoute.filter(node => node.requiredPolicy).forEach((nonLazyRouteItem: ABP.Route) => {
              let moduleId = (nonLazyRouteItem as any).data?.moduleId;
              if (moduleId) {
                const moduleIdPolicyViolated = !modulePermissionMap[moduleId] || modulePermissionMap[moduleId] && !modulePermissionMap[moduleId].includes(nonLazyRouteItem.requiredPolicy as string);
                const ordinaryRolePolicyViolated = !modulePermissionMap['_ordinaryRole'] || modulePermissionMap['_ordinaryRole'] && !modulePermissionMap['_ordinaryRole'].includes(nonLazyRouteItem.requiredPolicy as string);
                if (!moduleIdPolicyViolated || !ordinaryRolePolicyViolated) {
                  nonLazyRouteItem.invisible = false;
                }
              }
            });
            this.routesService.refresh(); // HAVE TO USE IT to make invisibility to have effect, but combineLatest is called again... :(
        });
      }
      

UPDATE: this is a modified version - does it look ok?

      init() {
        this.routesService.flat.filter(x => x.requiredPolicy && (x as any).data?.moduleId).forEach(x => x.invisible = true);
        this.routesService.refresh();
        let routeStateBefore = JSON.stringify(this.routesService.flat, ['name', 'invisible']);
        combineLatest([this.configStateService.getDeep$('extraProperties.modulePermissionMap'), this.routesService.flat$.pipe(take(1))])
          .pipe
          (
            filter(([modulePermissionMap, route]) => Object.keys(modulePermissionMap).length > 0 && Object.keys(route).length > 0),
            takeUntil(this.destroy)
          )
          .subscribe(([modulePermissionMap, nonLazyLoadedRoute])  => {
            nonLazyLoadedRoute.filter(node => node.requiredPolicy).forEach((nonLazyRouteItem: ABP.Route) => {
              let moduleId = (nonLazyRouteItem as any).data?.moduleId;
              if (moduleId) {
                const moduleIdPolicyViolated = !modulePermissionMap[moduleId] || modulePermissionMap[moduleId] && !modulePermissionMap[moduleId].includes(nonLazyRouteItem.requiredPolicy as string);
                const ordinaryRolePolicyViolated = !modulePermissionMap['_ordinaryRole'] || modulePermissionMap['_ordinaryRole'] && !modulePermissionMap['_ordinaryRole'].includes(nonLazyRouteItem.requiredPolicy as string);
                if (!moduleIdPolicyViolated || !ordinaryRolePolicyViolated) {
                  nonLazyRouteItem.invisible = false;
                }
              }
            });
            let routeStateNow = JSON.stringify(this.routesService.flat, ['name', 'invisible']);
            if (routeStateNow !== routeStateBefore) {
              routeStateBefore = routeStateNow;
              this.routesService.refresh();
            }
          });
      }

Hi Anjali,

unfortunately, it did not help - still getting 401 on logout in one of two methods. Suprisingly, this method has another problem - it is for some reason invoked twice, even though in debug I just got it triggered once.

I'm attaching the Home module code - probably you will figure out what is wrong. It is actually not my code, so I am not sure I would be able to reply you all the questions. But I'm ready to assist in any possible way.

Thank you. Home page

Actually one more thing confuses me: after I do log out - I'm redirected to this page ("Home"): instead of this: So I need to click "Login" again to be redirected to the second dialog. But the routing in the app is the same as in test ABP app...

I've finally managed to resolve my issue. I will show my approach - probably this would come in handy for someone:

Actually two steps are needed:

  1. Create permission itself and add it as a child either to another custom permission or to the root permission node (in my case it is roleSubgroupPermissionDefinition):

     readModuleRolePermissionDefinition = roleSubgroupPermissionDefinition?.AddChild(readRoleName).WithProviders(ModulePermissionRoleValueProvider.ProviderName);
    
  2. Add the created permission to PermissionDefinitions collection of ABP static permission store:

     await (_staticPermissionDefinitionStore as IExtendedStaticPermissionDefinitionStore).AddPermissionDefinitionAsync(readModuleRolePermissionDefinition.Name, readModuleRolePermissionDefinition);
    

For this, i've extended ABP class with own methods. They are very simple - just to have access to PermissionDefinitions collection:

    public Task AddPermissionDefinitionAsync(string key, PermissionDefinition permissionDefinition)
    {
        if (!PermissionDefinitions.ContainsKey(key))
        {
            PermissionDefinitions.Add(key, permissionDefinition);
        }
        return Task.CompletedTask;
    }

Nothing more is needed - no refresh or something...

Thank you for your cooperation.

I already did this before. And I'm getting the error about missing custom permission definition group: All other permission definition groups are at place. When I do not override StaticPermissionDefinitionStore - the custom permission definition group is present as expected.

What do I need to adjust in MyStaticPermissionDefinitionStore to make the group available?

To avoid compile errors, I had also to add providers: [SubscriptionService] to app.component.ts - hope it is a correct string. But anyway - closeAll() call did not help: i'm still getting the same 401 error on logout. It happens to any method which is obviously being loaded at the moment of logout. The methods are pretty typical:

//some component
this.fineDigitLoading = true;
this.fineDigitsService
  .getById(fineDigit.ordinanceId, fineDigit.number, fineDigit.subdivision, fineDigit.version)
  .pipe(
    finalize(() => (this.fineDigitLoading = false)),
    takeUntil(this.unsubscriber$)
  )
  .subscribe((state: FineDigits.FineDigit) => {
     ...
  });

//fineDigitsService
getById(
    ordinanceId: number,
    number: string,
    subdivision: string,
    version: number): Observable<FineDigits.FineDigit> {
    return this.restService.request<void, FineDigits.FineDigit>({
        method: 'GET',
        url: `/api/md/fine-digits/${ordinanceId}/${number}/${version}/${subdivision === null ? '' : subdivision}`,
    },
    { apiName: this.apiName });
}

//base class for any component
ngOnDestroy(): void {
    this.ngOnDestroyInner();
    this.unsubscriber$.next(null);
    this.unsubscriber$.complete();
}

Probably the latter approach is the reason? When the user is logging out - the current component is not being destroyed, so ngOnDestroy is not being triggered. If this is the case - please let me know the recommended approach to unsubscribe from all API calls by adjusting the code in base component class - adding 'logout' event handling which is now done in app.component.ts? Suprisingly I did not see any special handling for such scenario in ABP components...

UPDATE: I've added this to Base component constructor, but stil keep getting the same 401 errors:

this.oAuthService.events
  .pipe(filter(event => event?.type === 'logout'), takeUntil(this.unsubscriber$))
  .subscribe(() => {
    this.unsubscriber$.next(null);
    this.unsubscriber$.complete();
  });
  

The above part IS triggered after I click "Logout" link. But after this my server API calls are still made. How it's possible if I use takeUntil(this.unsubscriber$) for all API calls?

Thank you! I've also removed this.routesService.refresh(); both occurences and seems to be working fine now.

I've overridden ABP PermissionAppService and debugged it. No issue found inside - the code below is called and contains correct data:

    public virtual async Task UpdateAsync(string providerName, string providerKey, UpdatePermissionsDto input)
    {
        await CheckProviderPolicy(providerName);

        foreach (var permissionDto in input.Permissions)
        {
            await PermissionManager.SetAsync(permissionDto.Name, providerName, providerKey, permissionDto.IsGranted);
        }

        await RabbitMqManager.UpdateAbpPermissionsAsync(input.Permissions, providerName, providerKey, CurrentTenant.Id);
    }

So moving on, I've overriden PermissionManager too and found out that SetAsync does not actually update DB:

I can see though, that there's no point to override PermissionManager - its method is very simple:

    public override async Task<PermissionDefinition> GetOrNullAsync(string name)
    {
        Check.NotNull(name, nameof(name));
    
        return await _staticStore.GetOrNullAsync(name) ??
               await _dynamicStore.GetOrNullAsync(name);
    }
    

So I proceeded - overridden StaticPermissionDefinitionStore:

    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(IStaticPermissionDefinitionStore))]
    public class ApiStaticPermissionDefinitionStore : StaticPermissionDefinitionStore, IApiStaticPermissionDefinitionStore
    {
        public ApiStaticPermissionDefinitionStore(
            IServiceProvider serviceProvider,
            IOptions<AbpPermissionOptions> options) : base(serviceProvider, options)
        {
        }
    
        public void AddPermissionDefinition(string key, PermissionDefinition permissionDefinition)
        {
            if (!PermissionDefinitions.ContainsKey(key))
            {
                PermissionDefinitions.Add(key, permissionDefinition);
            }
        }
    }

My idea was to create a method in my IStaticPermissionDefinitionStore override, where I would FORCE adding a new PermissionDefinition to the existing collection. However, after adding it I've discovered that a whole custom permission definition collection is broken. BTW - inside AddPermissionDefinition I've looked at a whole PermissionDefinitions collection and suprisingly discovered that not all definitions are there: my custom definitions were not there by this time (yet?)

Probably you can suggest another way around this?

Showing 91 to 100 of 276 entries
Made with ❤️ on ABP v9.0.0-preview Updated on September 20, 2024, 08:30