Skip to content

Commit 28a6625

Browse files
authored
Merge pull request #1732 from bcgov/dev
Dev
2 parents 865b615 + d2d8a5e commit 28a6625

13 files changed

Lines changed: 167 additions & 107 deletions

File tree

applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Application/PaymentRequests/Notifications/FinancialAnalystEmailStrategy.cs

Lines changed: 0 additions & 51 deletions
This file was deleted.

applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Application/PaymentsApplicationModule.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ public override void ConfigureServices(ServiceConfigurationContext context)
7575

7676
// Register email recipient strategies as singletons for background job usage
7777
// Singletons are preferred for background jobs since they are stateless and reused across job executions
78-
context.Services.AddSingleton<IEmailRecipientStrategy, FinancialAnalystEmailStrategy>();
7978
context.Services.AddSingleton<IEmailRecipientStrategy, PaymentsEmailGroupStrategy>();
8079

8180
context.Services.AddAbpDbContext<PaymentsDbContext>(options =>

applications/Unity.GrantManager/src/Unity.GrantManager.Application.Contracts/GrantManagerFeaturesDefinitionProvider.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ public override void Define(IFeatureDefinitionContext context)
3838
displayName: LocalizableString
3939
.Create<GrantManagerResource>("Reporting"),
4040
valueType: new ToggleStringValueType());
41+
42+
myGroup.AddFeature("Unity.AIReporting",
43+
defaultValue: defaultValue,
44+
displayName: LocalizableString
45+
.Create<GrantManagerResource>("AIReporting"),
46+
valueType: new ToggleStringValueType());
4147
}
4248
}
4349
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using Microsoft.Extensions.Configuration;
2+
using Microsoft.IdentityModel.Tokens;
3+
using System;
4+
using System.IdentityModel.Tokens.Jwt;
5+
using System.Security.Claims;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
using Unity.Modules.Shared.Permissions;
9+
using Volo.Abp;
10+
using Volo.Abp.MultiTenancy;
11+
using Volo.Abp.Users;
12+
13+
namespace Unity.GrantManager.Identity
14+
{
15+
[RemoteService]
16+
public class JwtTokenAppService : GrantManagerAppService
17+
{
18+
private readonly ICurrentTenant _currentTenant;
19+
private readonly ICurrentUser _currentUser;
20+
private readonly IConfiguration _configuration;
21+
22+
public JwtTokenAppService(ICurrentTenant currentTenant, ICurrentUser currentUser, IConfiguration configuration)
23+
{
24+
_currentTenant = currentTenant;
25+
_currentUser = currentUser;
26+
_configuration = configuration;
27+
}
28+
29+
public Task<string> GenerateJWTTokenAsync()
30+
{
31+
// Get user & tenant info
32+
var userId = _currentUser.GetId().ToString();
33+
var tenant = _currentTenant.Name ?? "UnknownTenant";
34+
var isITAdmin = _currentUser.IsInRole(IdentityConsts.ITAdminRoleName);
35+
36+
// Build claims
37+
var claims = new[]
38+
{
39+
new Claim("user_id", userId),
40+
new Claim("tenant", tenant),
41+
new Claim("is_it_admin", isITAdmin.ToString().ToLower()),
42+
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
43+
};
44+
45+
// Ensure secretKey is not null or empty
46+
var secretKey = _configuration["ReportingAI:JWTSecret"];
47+
if (string.IsNullOrWhiteSpace(secretKey))
48+
{
49+
throw new AbpException("JWT secret key is not configured.");
50+
}
51+
52+
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey!));
53+
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
54+
55+
// Create token
56+
var token = new JwtSecurityToken(
57+
issuer: "Unity.GrantManager",
58+
audience: "Unity.GrantManager.Users",
59+
claims: claims,
60+
expires: DateTime.UtcNow.AddHours(1),
61+
signingCredentials: creds
62+
);
63+
64+
// Return encoded JWT
65+
var jwt = new JwtSecurityTokenHandler().WriteToken(token);
66+
return Task.FromResult(jwt);
67+
}
68+
}
69+
}

applications/Unity.GrantManager/src/Unity.GrantManager.Domain.Shared/Integrations/DynamicUrlKeyNames.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ public static class DynamicUrlKeyNames
77
public const string INTAKE_API_BASE = "INTAKE_API_BASE";
88
public const string PAYMENT_API_BASE = "PAYMENT_API_BASE";
99
public const string ORGBOOK_API_BASE = "ORGBOOK_API_BASE";
10+
public const string REPORTING_AI = "REPORTING_AI";
1011
public const string NOTIFICATION_API_BASE = "NOTIFICATION_API_BASE";
1112
public const string NOTIFICATION_AUTH = "NOTIFICATION_AUTH";
1213
public const string DIRECT_MESSAGE_KEY_PREFIX = "DIRECT_MESSAGE_"; // Teams Direct Message URL Weebhook- Dynamically incremented

applications/Unity.GrantManager/src/Unity.GrantManager.Domain.Shared/Localization/GrantManager/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"texts": {
44
"Menu:Home": "Home",
55
"Menu:Dashboard": "Dashboard",
6+
"Menu:AIReporting": "AI Reporting",
67
"Menu:GrantPrograms": "Grant Programs",
78
"Menu:GrantTracker": "Grant Tracker",
89
"Menu:Applications": "Applications",

applications/Unity.GrantManager/src/Unity.GrantManager.Domain/Integrations/DynamicUrlDataSeeder.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public static class DynamicUrls
3030
public const string CSS_TOKEN_API_BASE_URL = $"{PROTOCOL}//loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/token";
3131
public const string GEOCODER_BASE_URL = $"{PROTOCOL}//openmaps.gov.bc.ca/geo/pub/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=";
3232
public const string GEOCODER_LOCATION_BASE_URL = $"{PROTOCOL}//geocoder.api.gov.bc.ca";
33+
public const string REPORTING_AI = $"{PROTOCOL}//reporting.grants.gov.bc.ca";
3334
}
3435

3536
private async Task SeedDynamicUrlAsync()
@@ -48,6 +49,7 @@ private async Task SeedDynamicUrlAsync()
4849
new() { KeyName = DynamicUrlKeyNames.ORGBOOK_API_BASE, Url = DynamicUrls.ORGBOOK_PROD_URL, Description = "OrgBook Services API" },
4950
new() { KeyName = DynamicUrlKeyNames.INTAKE_API_BASE, Url = DynamicUrls.CHEFS_PROD_URL, Description = "Common Hosted Forms Service API" },
5051
new() { KeyName = DynamicUrlKeyNames.NOTIFICATION_API_BASE, Url = DynamicUrls.CHES_PROD_URL, Description = "Common Hosted Email Service API" },
52+
new() { KeyName = DynamicUrlKeyNames.REPORTING_AI, Url = DynamicUrls.REPORTING_AI, Description = "Reporting AI iFrame Source" },
5153
new() { KeyName = DynamicUrlKeyNames.NOTIFICATION_AUTH, Url = DynamicUrls.CHES_PROD_AUTH, Description = "Common Hosted Email Service OAUTH" },
5254
new() { KeyName = $"{DynamicUrlKeyNames.DIRECT_MESSAGE_KEY_PREFIX}{messageIndex++}", Url = "", Description = $"Direct message webhook {messageIndex}" },
5355
new() { KeyName = $"{DynamicUrlKeyNames.DIRECT_MESSAGE_KEY_PREFIX}{messageIndex++}", Url = "", Description = $"Direct message webhook {messageIndex}" },

applications/Unity.GrantManager/src/Unity.GrantManager.Web/Menus/GrantManagerMenuContributor.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
using Unity.TenantManagement.Web.Navigation;
88
using Volo.Abp.Identity;
99
using Volo.Abp.UI.Navigation;
10+
using Microsoft.Extensions.DependencyInjection;
11+
using Volo.Abp.Features;
12+
using Volo.Abp.Users;
1013

1114
namespace Unity.GrantManager.Web.Menus;
1215

@@ -23,9 +26,11 @@ public async Task ConfigureMenuAsync(MenuConfigurationContext context)
2326
}
2427
}
2528

26-
private static Task ConfigureMainMenuAsync(MenuConfigurationContext context)
29+
private async static Task ConfigureMainMenuAsync(MenuConfigurationContext context)
2730
{
2831
var l = context.GetLocalizer<GrantManagerResource>();
32+
var featureChecker = context.ServiceProvider.GetRequiredService<IFeatureChecker>();
33+
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
2934

3035
context.Menu.AddItem(
3136
new ApplicationMenuItem(
@@ -111,8 +116,20 @@ private static Task ConfigureMainMenuAsync(MenuConfigurationContext context)
111116
"~/EndpointManagement/Endpoints",
112117
requiredPermissionName: IdentityConsts.ITOperationsPermissionName
113118
)
114-
);
119+
);
115120

121+
if (await featureChecker.IsEnabledAsync("Unity.AIReporting") || currentUser.IsInRole(IdentityConsts.ITAdminRoleName))
122+
{
123+
context.Menu.AddItem(
124+
new ApplicationMenuItem(
125+
GrantManagerMenus.AIReporting,
126+
l["Menu:AIReporting"],
127+
"~/AIReporting",
128+
icon: "fl fl-view-dashboard",
129+
order: 9
130+
)
131+
);
132+
}
116133

117134
// ********************
118135
// Admin - Tenant Management
@@ -158,7 +175,7 @@ private static Task ConfigureMainMenuAsync(MenuConfigurationContext context)
158175
//}
159176
//*/
160177

161-
return Task.CompletedTask;
178+
//return Task.CompletedTask;
162179
#pragma warning restore S125 // Sections of code should not be commented out
163180
}
164181
}

applications/Unity.GrantManager/src/Unity.GrantManager.Web/Menus/GrantManagerMenus.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ public static class GrantManagerMenus
1717
public const string Intakes = Prefix + ".Intakes";
1818
public const string ApplicationForms = Prefix + ".ApplicationForms";
1919
public const string EndpointManagement = Prefix + ".EndpointManagement";
20+
public const string AIReporting = Prefix + ".AIReporting";
2021
public const string Applicants = Prefix + ".Applicants";
2122
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
@page
2+
@model Unity.GrantManager.Web.Pages.AIReporting.IndexModel
3+
@using Unity.GrantManager.Web.Pages.AIReporting
4+
@using Unity.Modules.Shared.Permissions
5+
@using Volo.Abp.Features
6+
7+
@section styles {
8+
<abp-style src="/libs/bootstrap/css/bootstrap.css" />
9+
}
10+
@section scripts
11+
{
12+
<abp-script src="/libs/jquery/jquery.js" />
13+
<abp-script src="/libs/bootstrap-4/dist/js/bootstrap.min.js"></abp-script>
14+
@if (await FeatureChecker.IsEnabledAsync("Unity.AIReporting") || User.IsInRole(IdentityConsts.ITAdminRoleName))
15+
{
16+
<script>
17+
window.reportingAiUrl = '@Model.ReportingAiUrl';
18+
</script>
19+
<abp-script src="/Pages/AIReporting/Index.js" />
20+
}
21+
}
22+
@inject IFeatureChecker FeatureChecker
23+
24+
<style>
25+
#container {
26+
height: calc(100vh - 6.75rem);
27+
}
28+
29+
.unity-app-main-container {
30+
padding: 0px;
31+
}
32+
</style>
33+
34+
<div id="container"></div>

0 commit comments

Comments
 (0)