Base solution for your next web application

Activities of "feloff"

Use your demo sites:

  • minimise the sidebar
  • try and access the administration submenus, e.g. Roles

Accordian: It isn't possible without maximising the sidebar first. If the visual settings is set to set show the sidebar menu as an accordian no submenu is shown.

If is set as a dropdown it shows the dropdown pops up at with an odd offset

Both screenshots taken from your demo applications, so completely unchanged code.

  • latest 9.0.1
  • default theme
  • didn't make any changes that I am aware of

Believe it is a bug introduced in changes when upgrading to metronic v7. The notifications used to be wrapped in a 'kt-checkbox-list' class and is now wrapped in a 'checkbox-inline' class. Changing it to 'checkbox-list' seems to solve it

The available noticiations in the settings modal show in a row. Suspect you wanted to use checkbox-list rather than checkbox-inline. (notification-settings-modal.component.html)

This was an issue in the past that seems to be back in v9+. Can't find any open issues on it, but thought I'd check before opening a new one https://github.com/aspnetzero/aspnet-zero-core/issues/2531

Click on << icon on sidebar to collapse Hover over icon on sidebar Issue Sidebar does not auto expand Expected: Sidebar should expand

Makes it impossible to get to submenu without having to maximise sidebar first.

Many thanks

No - gave up in the end. Would be great to get it to work as it would make it much easier to develop integrations tests, i.e. build a sequence/workflow of api calls, and performance tests for workflows using a test database.

I can't get the claims I set in UserClaimsPrincipalFactory to work with Identity Server.

The claims set in

        public override async Task<ClaimsPrincipal> CreateAsync(User user)
        {
            var claim = await base.CreateAsync(user);
            ...
        }

works without issue for normal angular app, but not when I use the ConsoleApiClient. Nothing I tried worked, so not worth listing my futile efforts.

How do I add these claims to the Identity Server claims?

many thanks

Spent the day copying logic into the template only to have a moment of clarity after it was all done:

From docs

Filters can only be defined for the root Entity Type of an inheritance hierarchy.

Thank you - found a hack and it seems to work. Have a new issue with the data filter following the article though.

When I evaluate the generated SQL command of the IQuerayable prior to execution all seems fine. The filter and parameters seems to be captured (replaced the select columns with * for readability)

SELECT `c*
FROM `Comments` AS `c`
INNER JOIN (
    SELECT `p*
    FROM `Programmes` AS `p`
    WHERE (@__ef_filter__p_1 OR NOT (`p`.`IsDeleted`)) AND ((@__ef_filter__p_2 AND (@__ef_filter__p_3 OR EXISTS (
        SELECT 1
        FROM `ProgrammeBrokers` AS `p0`
        WHERE ((@__ef_filter__p_6 OR NOT (`p0`.`IsDeleted`)) AND (`p`.`Id` = `p0`.`ProgrammeId`)) AND ((`p0`.`BrokerId` = @__ef_filter__CurrentTenantId_4) AND (`p0`.`Status` <> 2))))) AND (@__ef_filter__p_5 OR ((`p`.`ProtectionBuyerId` = @__ef_filter__CurrentTenantId_4) OR (`p`.`ProtectionBuyerId` IS NULL AND @__ef_filter__CurrentTenantId_4 IS NULL))))
) AS `t` ON `c`.`ProgrammeId` = `t`.`Id`
LEFT JOIN (
    SELECT `p1*
    FROM `ProgrammeAccess` AS `p1`
    INNER JOIN (
        SELECT `a*
        FROM `Approvals` AS `a`
        WHERE @__ef_filter__p_8 OR NOT (`a`.`IsDeleted`)
    ) AS `t0` ON `p1`.`AccessStatusId` = `t0`.`Id`
    WHERE @__ef_filter__p_7 OR NOT (`p1`.`IsDeleted`)
) AS `t1` ON `t`.`Id` = `t1`.`ProgrammeId`
LEFT JOIN (
    SELECT `p2`.`*
    FROM `ProgrammeBrokers` AS `p2`
    WHERE @__ef_filter__p_6 OR NOT (`p2`.`IsDeleted`)
) AS `t2` ON `t`.`Id` = `t2`.`ProgrammeId`
WHERE (`c`.`Discriminator` = 'ProgrammeComment') AND (@__ef_filter__p_0 OR NOT (`c`.`IsDeleted`))
ORDER BY `c`.`Id`, `t`.`Id`, `t1`.`Id`, `t1`.`Id0`, `t2`.`Id`

The final query only includes the isDeleted filter though and everything else is dropped

DbCommand (3ms) [Parameters=[@__ef_filter__p_0='False'], CommandType='Text', CommandTimeout='30']
      SELECT COUNT(*)
      FROM `Comments` AS `c`
      WHERE (`c`.`Discriminator` = 'ProgrammeComment') AND (@__ef_filter__p_0 OR NOT (`c`.`IsDeleted`))

The documentation suggests that it should pass the values via the property and it should all flow through. My code includes

In the context:

        protected virtual bool CurrentIsBroker => GetCurrentIsBroker();
        protected virtual bool CurrentIsBuyer => GetCurrentIsBuyer();
        protected virtual bool CurrentIsSeller => GetCurrentIsSeller();
        ...

        protected override bool ShouldFilterEntity&lt;TEntity&gt;(IMutableEntityType entityType)
        {
            if (typeof(IMustHaveProgramme).IsAssignableFrom(typeof(TEntity)))
                return true;
            ...

            return base.ShouldFilterEntity&lt;TEntity&gt;(entityType);
        }

        protected override Expression&lt;Func&lt;TEntity, bool&gt;> CreateFilterExpression&lt;TEntity&gt;()
        {
            if (typeof(IMustHaveProgramme).IsAssignableFrom(typeof(TEntity)))
                {
                    Expression&lt;Func&lt;TEntity, bool&gt;> progFilter = p => !CurrentIsBroker || !IsMustHaveProgrammeFilterEnabled
                    || ((IMustHaveProgramme)p).Programme.Brokers.Any(b => b.BrokerId == this.CurrentTenantId && b.Status != BrokerAppointmentStatus.BrokerWithdrawn);

                    Expression&lt;Func&lt;TEntity, bool&gt;> buyerExpr = p => !CurrentIsBuyer || !IsMustHaveProgrammeFilterEnabled
                    || (((IMustHaveProgramme)p).Programme.ProtectionBuyerId == this.CurrentTenantId);
                    progFilter = progFilter == null ? buyerExpr : CombineExpressions(progFilter, buyerExpr);

                    Expression&lt;Func&lt;TEntity, bool&gt;> sellerExpr = p => !CurrentIsSeller || !IsMustHaveProgrammeFilterEnabled
                    || ((IMustHaveProgramme)p).Programme.AccessRequests.Any(a => a.AccessStatus.Status == ApprovalStatus.Approved && a.TenantId == this.CurrentTenantId);
                    progFilter = progFilter == null ? sellerExpr : CombineExpressions(progFilter, sellerExpr);

                    expression = expression == null ? progFilter : CombineExpressions(expression, progFilter);
                }
                ...
        }

and in core module - PreInitialize

Configuration.UnitOfWork.RegisterFilter(ReinsuranceConst.IMustHaveProgramme, true);

I can also see my filters are enabled and the property values are correctly set when debugging, but the final query doesn't filter.

The 3 properties have the correct value:

The filter is enabled and correctly refelcts in the property in the context:

Is there anything else I need to do that is not included in the documentation?

Many thanks

Followed guidelines in article Custom Filters

Having difficulty with unit testing as the IPrincipalAccessor is always null, and even if it were to be injected the claims will never be added. Using the claims therefore seems the wrong way to do this - how should we implement to also allow for unit tests?

Question

Really looking forward the pending webhook feature, as the timing is perfect for the automation/integration we need to implement in our solution.

Before I implement I thought I'd check if anyone has implemented any form on automation, and if they have any advice.

My general approach to allow other systems to perform actions on behalf of users will include:

  • borrow from impersonation logic to give systems necessary tokens to make API calls
  • implement some form of public/secret auth logic to ensure legitimate machine-to-machine calls
  • extend webhook subscriptions with boolean variable AllowAutomation, so anly certain subscriptions can automate

Am I missing something obvious, particularly security wise? Any other suggestions?

Many thanks

Showing 1 to 10 of 32 entries