Base solution for your next web application
Ends in:
01 DAYS
01 HRS
01 MIN
01 SEC

Activities of "sedulen"

thanks @ismcagdas

so the concern is that parts of the application may start before migrations are completed, and that may cause an exception?

understood on the suggestion of running the Migrator to update the databases.

what I'm working on is a way to hot-swap Docker Containers, either through AKS or Azure AppServices, where I can deploy an upgrade to the application to a deployment slot, or to a second set of Docker Containers, warm them up, and then hot swap the traffic over to the new instances.

so having the ability for the application to self-migrate would be a huge help.

in looking at the documentation provided for wiring up ANZ into Azure DevOps Pipelines, we don't have connectivity to the SQL database. That connectionString is private to our hosting environment. So for using the Migrator or for generating the EF Migration SQL Scripts, we don't have access to the SQL DB in our DevOps pipeline.

Hello again.
An update on this idea, I was able to change the target framework to netcoreapp2.1.

Building clean and the rebuilding, I ran into assembly reference issues referencing version 1.2.2 of "Abp.AspNetZeroCore" Reverting that assembly reference down to version 1.1.11 resolved that issue.

Then there were a handful of sections of code that reference "Abp.AspNetZeroCore.Web.Authentication.External.WsFederation" that I had to remove.

After that I am now able to successfully build my application using ANZ v6.9.1 downgraded to dotnet core 2.1.

I will continue to test through next week to see how this goes, but my next step will be to build my application and attempt to deploy to a linux-based Azure AppService running dotnet 2.1 as it's runtime.

I'll keep you posted on how it goes. Thanks again for the help!

Thanks @ismcagdas,

If I'm running an ANZ v6.9.1 solution, that's built on ABP v4.5.0, and I want to downgrade the dotnet core framework from 2.2 to 2.1, it looks like I'll have to also downgrade ABP from v4.5.0 to ABP v4.1.0, and then I run the risk of feature regression.

Ideally I would prefer to upgrade from ANZ v6.9.1 to ANZ v9.3.0 (not quite ready to go to dotnet core 5+ yet), but I'm a little concerned with the amount of additional features that have been added and the regression testing required.

What I'm wondering is if it would make sense to fork/clone the ABP v4.5.0 repo and re-compile the assemblies to dotnet core 2.1.

My concern there is that I'm continuing to move further away from the base ABP and ANZ frameworks, making upgrading later even harder.

Any thoughts on how I could more easily downgrade? Is there an ANZ v6.9.1 project available that targets dotnet core 2.1 already? (The aspnetzero.com site is down at the moment for maintenance, so I can't check it myself).

Thanks again!

Hi everyone,

Sorry for my delayed response. Just to get us in-sync, what ANZ versions is everyone using?

I am on ANZ v6.9.1 (Angular, Single Solution), and I have modified the "build" file and the Dockerfiles to meet my needs.

I am using Azure DevOps Pipelines to build my code, and in my pipelines, I have tasks to build the docker image and publish to a private azure container registry.

In looking at later ANZ versions, like v9.1.0, it looks like the docker files and build files have changed. I haven't yet explored the upgrade path yet.

If it would be helpful, I can post the files that I have generated here so that you can see what I'm doing.

-Brian

It appears that was, indeed, my issue.

I had previously modified the Dockerfile at the root of the .Host project to try and make it fully contained, rather than using the build scripts that were provided as part of the template.

To note, the only change I found I had to make was in the build-with-ng.ps1 script, the following line seems to give me issue:

Copy-Item (Join-Path $ngFolder "dist") (Join-Path $outputFolder "ng/") -Recurse

When I look at my angular.json file, I see:

  "architect": {
    "build": {
      "builder": "@angular-devkit/build-angular:browser",
      "options": {
        "outputPath": "wwwroot/dist",

So if I change that Copy-Item line to be: Copy-Item (Join-Path $ngFolder "wwwroot/dist") (Join-Path $outputFolder "ng/") -Recurse

the build scripts work for me.

I think I see the issue. In my .Host project, my Dockerfile looks different from what I see when I look back at my base 6.9.0 project. So I may be causing my own issue here. I think I attempted to work with the Dockerfile a few months back and may have inadvertently made some changes. I will look back at my revision history to see if I accidentally changed anything in the default template regarding Docker.

thanks @aaron.

I agree that typically we wouldn't disable pagination. In this case, the entity that is being retrieved will only have a very small # of records, as it's managed by the Host and retrieved by the Tenants, so this is a controlled safe situation.

I had wanted to go with a type-ahead multi-select implementation, such as select2, but they requirements for some reason are to retrieve and load all results into a multi-select control

Understood. Thanks for the clarification @ismcagdas.

I've only ever worked with the merged solution, so I haven't had to deal with hosting Angular & WebAPI separately.

Cheers!

I've seen this discussed a few times, and the best solution I've seen has been to implement a new Hangfire Dashboard Authorization Filter:

1.) in Startup.cs, change the Hangfire Dashboard Authorization option to the following:

options.Authorization = new[] { new HangfireTokenAuthorizationFilter(AppPermissions.Pages_Administration_HangfireDashboard) };

2.) somewhere in your solution, mine is in my .Web.Host project, I have defined this class:

public class HangfireTokenAuthorizationFilter : IDashboardAuthorizationFilter
{
  private readonly string _requiredPermissionName;

  public HangfireTokenAuthorizationFilter(string requiredPermissionName = null)
  {
    _requiredPermissionName = requiredPermissionName;
  }

  public bool Authorize([NotNull]DashboardContext context)
  {
    var logger = context.GetHttpContext().RequestServices.GetRequiredService<ILogger>();

    // if we have a cookies and we are in release mode
    var cookies = context.GetHttpContext().Request.Cookies;
    if (cookies["Abp.AuthToken"] != null)
    {
      var jwtCookie = cookies["Abp.AuthToken"];
      string jwtToken = jwtCookie;
      JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
      JwtSecurityToken securityToken = handler.ReadToken(jwtToken) as JwtSecurityToken;
      var id = securityToken.Claims.FirstOrDefault(claim => claim.Type.EndsWith("sub"));
      var tenanIdClaim = securityToken.Claims.FirstOrDefault(claim => claim.Type.EndsWith("tenantId"));
      int? tenanId = null;
      if (tenanIdClaim != null)
      {
        tenanId = int.Parse(tenanIdClaim.Value);
      }
      logger.InfoFormat("[HangfireTokenAuthorizationFilter.Authorize]: checking Permissions: permission: '{0}', tenant: '{1}', user_id: '{2}'", _requiredPermissionName, tenanId, id.Value);
      var isPermissionGranted = IsPermissionGranted(context, _requiredPermissionName, new UserIdentifier(tenanId, long.Parse(id.Value)));
      if(!isPermissionGranted)
      {
        logger.WarnFormat("[HangfireTokenAuthorizationFilter.Authorize]: Unauthorized Attempt to access the Hangfire Dashboard: tenant: '{0}', user_id: '{1}'", _requiredPermissionName, tenanId, id.Value);
      }
      return isPermissionGranted;
    }
    logger.Warn("[HangfireTokenAuthorizationFilter.Authorize]: no Abp.AuthToken cookie present.");
    return false;

  }

  private static bool IsPermissionGranted(DashboardContext context, string requiredPermissionName, UserIdentifier userIdentifier)
  {
    var permissionChecker = context.GetHttpContext().RequestServices.GetRequiredService<IPermissionChecker>();
    return permissionChecker.IsGranted(userIdentifier, requiredPermissionName);
  }
}

3.) in your .Core project, under Authorization, in the AppPermissions.cs and AppAuthorizationProvider.cs classes, make sure that you have lines that define the Hangfire Dashboard permission

administration.CreateChildPermission(AppPermissions.Pages_Administration_HangfireDashboard, L("HangfireDashboard"), multiTenancySides: _isMultiTenancyEnabled ? MultiTenancySides.Host : MultiTenancySides.Tenant);

and

public const string Pages_Administration_HangfireDashboard = "Pages.Administration.HangfireDashboard";

At this point, when you setup role permissions through the .Web.Host UI, you should see Hangfire Dashboard listed as a permission-controlled item.

Then the last step is you need to add navigation to the Hangfire Dashboard to your Admin UI.

4.) In the .Web.Host project, under src\app\shared\layout\nav\app-navigation.service.ts, you need to add:

import { AppConsts } from '@shared/AppConsts'; ~line 5 in the import statements @ the top

new AppMenuItem('HangfireDashboard', 'Pages.Administration.HangfireDashboard', 'flaticon-line-graph', AppConsts.remoteServiceBaseUrl + '/hangfire', [], true), somewhere under your Administration AppMenuItem definition.

once you have that you should now see Hangfire Dashboard in your Administration menu, and if you click on it, it should open a new tab/window to the Hangfire Dashboard using the correct authorization filter/scheme that adheres to your ASPNZ permissions model.

thank you!

Showing 81 to 90 of 104 entries