mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-24 04:32:32 +00:00
mcp user mgmt, vul report re-scan logging
This commit is contained in:
@@ -1 +1 @@
|
||||
679
|
||||
680
|
||||
|
||||
@@ -23,6 +23,7 @@ public class AuthFunction
|
||||
private readonly PreviewWhitelistService _previewWhitelistService;
|
||||
private readonly TelegramNotificationService _telegramNotificationService;
|
||||
private readonly GlobalNotificationService _globalNotificationService;
|
||||
private readonly McpUserService _mcpUserService;
|
||||
|
||||
public AuthFunction(
|
||||
ILogger<AuthFunction> logger,
|
||||
@@ -32,7 +33,8 @@ public class AuthFunction
|
||||
IMetricsRepository metricsRepo,
|
||||
PreviewWhitelistService previewWhitelistService,
|
||||
TelegramNotificationService telegramNotificationService,
|
||||
GlobalNotificationService globalNotificationService)
|
||||
GlobalNotificationService globalNotificationService,
|
||||
McpUserService mcpUserService)
|
||||
{
|
||||
_logger = logger;
|
||||
_globalAdminService = globalAdminService;
|
||||
@@ -42,6 +44,7 @@ public class AuthFunction
|
||||
_previewWhitelistService = previewWhitelistService;
|
||||
_telegramNotificationService = telegramNotificationService;
|
||||
_globalNotificationService = globalNotificationService;
|
||||
_mcpUserService = mcpUserService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -176,6 +179,9 @@ public class AuthFunction
|
||||
_ = _metricsRepo.RecordUserLoginAsync(tenantId, upn, displayName, objectId)
|
||||
.ContinueWith(t => _logger.LogWarning(t.Exception?.InnerException, "Fire-and-forget RecordUserLoginAsync failed"), TaskContinuationOptions.OnlyOnFaulted);
|
||||
|
||||
// Check MCP access (cached, lightweight)
|
||||
var mcpCheck = await _mcpUserService.IsAllowedAsync(upn);
|
||||
|
||||
var userInfo = new
|
||||
{
|
||||
tenantId,
|
||||
@@ -185,7 +191,8 @@ public class AuthFunction
|
||||
isGlobalAdmin,
|
||||
isTenantAdmin,
|
||||
role,
|
||||
canManageBootstrapTokens
|
||||
canManageBootstrapTokens,
|
||||
hasMcpAccess = mcpCheck.IsAllowed
|
||||
};
|
||||
|
||||
var response = req.CreateResponse(HttpStatusCode.OK);
|
||||
|
||||
@@ -38,18 +38,23 @@ export function useSessionAnalysis(
|
||||
}, [sessionId, sessionTenantId, getAccessToken]);
|
||||
|
||||
const fetchVulnerabilityReport = useCallback(async (rescan = false) => {
|
||||
if (!sessionTenantId || !GUID_REGEX.test(sessionTenantId)) return;
|
||||
if (!sessionTenantId || !GUID_REGEX.test(sessionTenantId)) {
|
||||
console.warn("[VulnReport] Skipped fetch: sessionTenantId missing or invalid", { sessionTenantId, rescan });
|
||||
return;
|
||||
}
|
||||
const url = api.sessions.vulnerabilityReport(sessionId, sessionTenantId, rescan || undefined);
|
||||
console.info(`[VulnReport] Fetching: rescan=${rescan}, url=${url}`);
|
||||
try {
|
||||
const response = await authenticatedFetch(
|
||||
api.sessions.vulnerabilityReport(sessionId, sessionTenantId, rescan || undefined),
|
||||
getAccessToken
|
||||
);
|
||||
const response = await authenticatedFetch(url, getAccessToken);
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
console.info(`[VulnReport] Response OK: rescan=${rescan}, hasReport=${data.report != null}, rescanned=${data.rescanned ?? false}`);
|
||||
setVulnerabilityReport(data.report ?? null);
|
||||
} else {
|
||||
console.warn(`[VulnReport] Response not OK: status=${response.status}, rescan=${rescan}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch vulnerability report:", error);
|
||||
console.error("[VulnReport] Failed to fetch vulnerability report:", error);
|
||||
}
|
||||
}, [sessionId, sessionTenantId, getAccessToken]);
|
||||
|
||||
|
||||
@@ -175,8 +175,21 @@ export function GlobalSidebar({ children }: { children: ReactNode }) {
|
||||
}
|
||||
};
|
||||
|
||||
// Visible expandable groups
|
||||
const visibleExpandableGroups = EXPANDABLE_NAV_GROUPS.filter(isGroupVisible);
|
||||
// Visible expandable groups (with item-level filtering for feature-gated items)
|
||||
const hasMcpAccess = user?.hasMcpAccess ?? false;
|
||||
const visibleExpandableGroups = useMemo(() => {
|
||||
return EXPANDABLE_NAV_GROUPS
|
||||
.filter(isGroupVisible)
|
||||
.map((group) => {
|
||||
// Filter out MCP item if user doesn't have MCP access
|
||||
const filteredItems = group.items.filter((item) => {
|
||||
if (item.id === "cfg-mcp") return hasMcpAccess;
|
||||
return true;
|
||||
});
|
||||
return { ...group, items: filteredItems };
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isAdminOrOperator, isGlobalAdmin, globalAdminMode, hasMcpAccess]);
|
||||
|
||||
// Auto-expand the group containing the current pathname
|
||||
useEffect(() => {
|
||||
|
||||
@@ -68,6 +68,7 @@ interface UserInfo {
|
||||
isTenantAdmin: boolean;
|
||||
role: 'Admin' | 'Operator' | 'Viewer' | null;
|
||||
canManageBootstrapTokens: boolean;
|
||||
hasMcpAccess: boolean;
|
||||
}
|
||||
|
||||
interface AuthContextType {
|
||||
@@ -157,6 +158,7 @@ function AuthProviderInternal({ children }: { children: React.ReactNode }) {
|
||||
isTenantAdmin: false,
|
||||
role: null,
|
||||
canManageBootstrapTokens: false,
|
||||
hasMcpAccess: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -174,6 +176,7 @@ function AuthProviderInternal({ children }: { children: React.ReactNode }) {
|
||||
isTenantAdmin: data.isTenantAdmin || false,
|
||||
role: data.role || null,
|
||||
canManageBootstrapTokens: data.canManageBootstrapTokens || false,
|
||||
hasMcpAccess: data.hasMcpAccess || false,
|
||||
};
|
||||
} catch (error) {
|
||||
// If the refresh token is expired or consent is required, redirect to
|
||||
@@ -203,6 +206,7 @@ function AuthProviderInternal({ children }: { children: React.ReactNode }) {
|
||||
isTenantAdmin: false,
|
||||
role: null,
|
||||
canManageBootstrapTokens: false,
|
||||
hasMcpAccess: false,
|
||||
};
|
||||
}
|
||||
}, [instance]);
|
||||
|
||||
@@ -200,6 +200,12 @@ export const EXPANDABLE_NAV_GROUPS: ExpandableNavGroup[] = [
|
||||
{ id: "cfg-offboarding", label: "Offboarding", href: "/settings/management/offboarding" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "cfg-mcp", label: "MCP", icon: <ChartBarIcon />,
|
||||
items: [
|
||||
{ id: "cfg-mcp-usage", label: "Usage", href: "/settings/mcp/usage" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -220,6 +226,7 @@ export const EXPANDABLE_NAV_GROUPS: ExpandableNavGroup[] = [
|
||||
items: [
|
||||
{ id: "ga-agent-metrics", label: "Agent Metrics", href: "/admin/metrics/agent-metrics" },
|
||||
{ id: "ga-usage", label: "Platform Usage", href: "/admin/metrics/usage" },
|
||||
{ id: "ga-mcp-usage", label: "MCP Usage", href: "/admin/metrics/mcp-usage" },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -245,6 +252,7 @@ export const EXPANDABLE_NAV_GROUPS: ExpandableNavGroup[] = [
|
||||
{ id: "ga-diag-paths", label: "Diagnostics Log Paths", href: "/admin/settings/diagnostics-log-paths" },
|
||||
{ id: "ga-mcp-users", label: "MCP Users", href: "/admin/settings/mcp-users" },
|
||||
{ id: "ga-config-reseed", label: "Config Reseed", href: "/admin/settings/config-reseed" },
|
||||
{ id: "ga-usage-plans", label: "Usage Plans", href: "/admin/settings/usage-plans" },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user