first commit
This commit is contained in:
84
ui/app/_fallbacks/enterprise/lib/contexts/rbacContext.tsx
Normal file
84
ui/app/_fallbacks/enterprise/lib/contexts/rbacContext.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
import { createContext, useContext } from "react";
|
||||
|
||||
// RBAC Resource Names (must match backend definitions)
|
||||
export enum RbacResource {
|
||||
GuardrailsConfig = "GuardrailsConfig",
|
||||
GuardrailsProviders = "GuardrailsProviders",
|
||||
GuardrailRules = "GuardrailRules",
|
||||
UserProvisioning = "UserProvisioning",
|
||||
Cluster = "Cluster",
|
||||
Settings = "Settings",
|
||||
Users = "Users",
|
||||
Logs = "Logs",
|
||||
Observability = "Observability",
|
||||
VirtualKeys = "VirtualKeys",
|
||||
ModelProvider = "ModelProvider",
|
||||
Plugins = "Plugins",
|
||||
MCPGateway = "MCPGateway",
|
||||
AdaptiveRouter = "AdaptiveRouter",
|
||||
AuditLogs = "AuditLogs",
|
||||
Customers = "Customers",
|
||||
Teams = "Teams",
|
||||
RBAC = "RBAC",
|
||||
Governance = "Governance",
|
||||
RoutingRules = "RoutingRules",
|
||||
PIIRedactor = "PIIRedactor",
|
||||
PromptRepository = "PromptRepository",
|
||||
PromptDeploymentStrategy = "PromptDeploymentStrategy",
|
||||
AccessProfiles = "AccessProfiles",
|
||||
}
|
||||
|
||||
// RBAC Operation Names (must match backend definitions)
|
||||
export enum RbacOperation {
|
||||
Read = "Read",
|
||||
View = "View",
|
||||
Create = "Create",
|
||||
Update = "Update",
|
||||
Delete = "Delete",
|
||||
Download = "Download",
|
||||
}
|
||||
|
||||
interface RbacContextType {
|
||||
isAllowed: (resource: RbacResource, operation: RbacOperation) => boolean;
|
||||
permissions: Record<string, Record<string, boolean>>;
|
||||
isLoading: boolean;
|
||||
refetch: () => void;
|
||||
}
|
||||
|
||||
const RbacContext = createContext<RbacContextType | null>(null);
|
||||
|
||||
// Dummy provider that allows all permissions
|
||||
export function RbacProvider({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<RbacContext.Provider
|
||||
value={{
|
||||
isAllowed: () => true, // Always allow in OSS
|
||||
permissions: {},
|
||||
isLoading: false,
|
||||
refetch: () => {},
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</RbacContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
// Hook that always returns true (no restrictions in OSS)
|
||||
export function useRbac(_resource: RbacResource, _operation: RbacOperation): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Hook to access full RBAC context
|
||||
export function useRbacContext() {
|
||||
const context = useContext(RbacContext);
|
||||
if (!context) {
|
||||
// Return dummy values if used outside provider
|
||||
return {
|
||||
isAllowed: () => true,
|
||||
permissions: {},
|
||||
isLoading: false,
|
||||
refetch: () => {},
|
||||
};
|
||||
}
|
||||
return context;
|
||||
}
|
||||
25
ui/app/_fallbacks/enterprise/lib/index.ts
Normal file
25
ui/app/_fallbacks/enterprise/lib/index.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
// Fallback exports for non-enterprise builds
|
||||
export * from "./store";
|
||||
|
||||
// Re-export OAuth token management utilities for convenience (fallback no-ops)
|
||||
export {
|
||||
REFRESH_TOKEN_ENDPOINT,
|
||||
clearOAuthStorage,
|
||||
clearUserInfo,
|
||||
getAccessToken,
|
||||
getRefreshState,
|
||||
getRefreshToken,
|
||||
getTokenExpiry,
|
||||
getUserInfo,
|
||||
isTokenExpired,
|
||||
setOAuthTokens,
|
||||
setRefreshState,
|
||||
setUserInfo,
|
||||
type UserInfo,
|
||||
} from "./store/utils/tokenManager";
|
||||
|
||||
// Re-export base query (fallback passthrough)
|
||||
export { createBaseQueryWithRefresh } from "./store/utils/baseQueryWithRefresh";
|
||||
|
||||
// Re-export RBAC context (dummy implementation for OSS)
|
||||
export * from "./contexts/rbacContext";
|
||||
@@ -0,0 +1,18 @@
|
||||
import { GetUserAccessProfilesResponse } from "@enterprise/lib/types/accessProfile";
|
||||
|
||||
// OSS build has no access-profile backend — return undefined data so consumers
|
||||
// (e.g. useVirtualKeyUsage) fall back to VK-owned budget/rate-limit values.
|
||||
export const useGetUserAccessProfilesQuery = (
|
||||
_userId: string,
|
||||
_opts?: { skip?: boolean; pollingInterval?: number },
|
||||
): {
|
||||
data: GetUserAccessProfilesResponse | undefined;
|
||||
isLoading: boolean;
|
||||
isError: boolean;
|
||||
error: null;
|
||||
} => ({
|
||||
data: undefined,
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
error: null,
|
||||
});
|
||||
11
ui/app/_fallbacks/enterprise/lib/store/apis/index.ts
Normal file
11
ui/app/_fallbacks/enterprise/lib/store/apis/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
// Placeholder for enterprise APIs
|
||||
// Export empty objects when enterprise features are not available
|
||||
|
||||
export const scimApi = null;
|
||||
export const guardrailsApi = null;
|
||||
export const clusterApi = null;
|
||||
export const rbacApi = null;
|
||||
export const auditLogsApi = null;
|
||||
|
||||
// Empty apis array when enterprise features are not available
|
||||
export const apis = [];
|
||||
@@ -0,0 +1,18 @@
|
||||
import { LargePayloadConfig } from "@enterprise/lib/types/largePayload";
|
||||
|
||||
export const useGetLargePayloadConfigQuery = (): {
|
||||
data: LargePayloadConfig | undefined;
|
||||
isLoading: boolean;
|
||||
isError: boolean;
|
||||
error: null;
|
||||
} => ({
|
||||
data: undefined,
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
error: null,
|
||||
});
|
||||
|
||||
export const useUpdateLargePayloadConfigMutation = (): [
|
||||
(_config: LargePayloadConfig) => { unwrap: () => Promise<void> },
|
||||
{ isLoading: boolean },
|
||||
] => [() => ({ unwrap: async () => {} }), { isLoading: false }];
|
||||
@@ -0,0 +1,22 @@
|
||||
import { User } from "@enterprise/lib/types/user";
|
||||
|
||||
export interface GetVirtualKeyUsersResponse {
|
||||
users: User[];
|
||||
}
|
||||
|
||||
// OSS build has no VK-user-attachment backend — return undefined data so the
|
||||
// consumer treats the VK as unassigned (no AP-managed detection happens).
|
||||
export const useGetVirtualKeyUsersQuery = (
|
||||
_vkId: string,
|
||||
_opts?: { skip?: boolean },
|
||||
): {
|
||||
data: GetVirtualKeyUsersResponse | undefined;
|
||||
isLoading: boolean;
|
||||
isError: boolean;
|
||||
error: null;
|
||||
} => ({
|
||||
data: undefined,
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
error: null,
|
||||
});
|
||||
23
ui/app/_fallbacks/enterprise/lib/store/index.ts
Normal file
23
ui/app/_fallbacks/enterprise/lib/store/index.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
// Fallback exports for non-enterprise builds
|
||||
export * from "./apis";
|
||||
export * from "./slices";
|
||||
|
||||
// Export OAuth token management utilities (fallback no-ops)
|
||||
export {
|
||||
REFRESH_TOKEN_ENDPOINT,
|
||||
clearOAuthStorage,
|
||||
clearUserInfo,
|
||||
getAccessToken,
|
||||
getRefreshState,
|
||||
getRefreshToken,
|
||||
getTokenExpiry,
|
||||
getUserInfo,
|
||||
isTokenExpired,
|
||||
setOAuthTokens,
|
||||
setRefreshState,
|
||||
setUserInfo,
|
||||
type UserInfo,
|
||||
} from "./utils/tokenManager";
|
||||
|
||||
// Export base query (fallback passthrough)
|
||||
export { createBaseQueryWithRefresh } from "./utils/baseQueryWithRefresh";
|
||||
12
ui/app/_fallbacks/enterprise/lib/store/slices/index.ts
Normal file
12
ui/app/_fallbacks/enterprise/lib/store/slices/index.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
// Placeholder for enterprise reducers
|
||||
// Export noop reducers when enterprise features are not available
|
||||
|
||||
export const scimReducer = (state = {}) => state;
|
||||
export const userReducer = (state = {}) => state;
|
||||
export const guardrailReducer = (state = {}) => state;
|
||||
|
||||
// Empty reducers map when enterprise features are not available
|
||||
export const reducers = {};
|
||||
|
||||
// Empty enterprise state type when enterprise features are not available
|
||||
export type EnterpriseState = {};
|
||||
@@ -0,0 +1,13 @@
|
||||
// Fallback base query for non-enterprise builds
|
||||
// Simply passes through the base query without any refresh logic
|
||||
|
||||
import type { BaseQueryFn } from "@reduxjs/toolkit/query/react";
|
||||
|
||||
/**
|
||||
* Fallback base query wrapper that does nothing
|
||||
* Used when enterprise features are not available
|
||||
*/
|
||||
export function createBaseQueryWithRefresh(baseQuery: BaseQueryFn): BaseQueryFn {
|
||||
// Simply return the base query as-is (no refresh logic)
|
||||
return baseQuery;
|
||||
}
|
||||
77
ui/app/_fallbacks/enterprise/lib/store/utils/tokenManager.ts
Normal file
77
ui/app/_fallbacks/enterprise/lib/store/utils/tokenManager.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
// Fallback OAuth Token Manager for non-enterprise builds
|
||||
// These functions return null/no-op when enterprise features are not available
|
||||
|
||||
export const getAccessToken = async (): Promise<string | null> => Promise.resolve(null);
|
||||
|
||||
export const getRefreshToken = async (): Promise<string | null> => Promise.resolve(null);
|
||||
|
||||
export const getTokenExpiry = (): number | null => null;
|
||||
|
||||
export const isTokenExpired = (): boolean => false;
|
||||
|
||||
export const setOAuthTokens = async (_accessToken: string, _expiresIn?: number | null) => {
|
||||
// No-op in non-enterprise builds
|
||||
};
|
||||
|
||||
export const clearOAuthStorage = () => {
|
||||
// No-op in non-enterprise builds
|
||||
};
|
||||
|
||||
export const getRefreshState = () => ({
|
||||
isRefreshing: false,
|
||||
refreshPromise: null,
|
||||
});
|
||||
|
||||
export const setRefreshState = (_refreshing: boolean, _promise: Promise<any> | null = null) => {
|
||||
// No-op in non-enterprise builds
|
||||
};
|
||||
|
||||
export const REFRESH_TOKEN_ENDPOINT = "";
|
||||
|
||||
// User info type definition (matching enterprise version)
|
||||
export interface UserInfo {
|
||||
name?: string;
|
||||
email?: string;
|
||||
picture?: string;
|
||||
preferred_username?: string;
|
||||
given_name?: string;
|
||||
family_name?: string;
|
||||
}
|
||||
|
||||
// Fallback getUserInfo that returns null for non-enterprise builds
|
||||
export const getUserInfo = (): UserInfo | null => null;
|
||||
|
||||
// Fallback setUserInfo - no-op
|
||||
export const setUserInfo = (_userInfo: UserInfo) => {
|
||||
// No-op in non-enterprise builds
|
||||
};
|
||||
|
||||
// Fallback clearUserInfo - no-op
|
||||
export const clearUserInfo = () => {
|
||||
// No-op in non-enterprise builds
|
||||
};
|
||||
|
||||
// Fallback secure storage functions - no-op
|
||||
export const setSecureItem = async (key: string, value: string): Promise<void> => {
|
||||
// No-op in non-enterprise builds
|
||||
};
|
||||
|
||||
export const getSecureItem = async (key: string): Promise<string | null> => Promise.resolve(null);
|
||||
|
||||
export const removeSecureItem = (key: string): void => {
|
||||
// No-op in non-enterprise builds
|
||||
};
|
||||
|
||||
export const setSecureLocalItem = async (key: string, value: string): Promise<void> => {
|
||||
// No-op in non-enterprise builds
|
||||
};
|
||||
|
||||
export const getSecureLocalItem = async (key: string): Promise<string | null> => Promise.resolve(null);
|
||||
|
||||
export const removeSecureLocalItem = (key: string): void => {
|
||||
// No-op in non-enterprise builds
|
||||
};
|
||||
|
||||
export const clearEncryptionKey = (): void => {
|
||||
// No-op in non-enterprise builds
|
||||
};
|
||||
41
ui/app/_fallbacks/enterprise/lib/types/accessProfile.ts
Normal file
41
ui/app/_fallbacks/enterprise/lib/types/accessProfile.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
export interface AccessProfileBudgetLine {
|
||||
id: string;
|
||||
scope: string;
|
||||
max_limit: number;
|
||||
reset_duration: string;
|
||||
current_usage: number;
|
||||
last_reset: string;
|
||||
alert_thresholds?: number[];
|
||||
}
|
||||
|
||||
export interface AccessProfileRateLimitLine {
|
||||
token_max_limit?: number;
|
||||
token_reset_duration?: string;
|
||||
token_current_usage?: number;
|
||||
token_last_reset?: string;
|
||||
request_max_limit?: number;
|
||||
request_reset_duration?: string;
|
||||
request_current_usage?: number;
|
||||
request_last_reset?: string;
|
||||
}
|
||||
|
||||
export interface UserAccessProfile {
|
||||
id: number;
|
||||
user_id: string;
|
||||
parent_profile_id?: number;
|
||||
virtual_key_ids?: string[];
|
||||
virtual_key_values?: Record<string, string>;
|
||||
name: string;
|
||||
is_active: boolean;
|
||||
expires_at?: string;
|
||||
provider_configs?: unknown[];
|
||||
budgets?: AccessProfileBudgetLine[];
|
||||
rate_limit?: AccessProfileRateLimitLine;
|
||||
mcp_configs?: unknown;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface GetUserAccessProfilesResponse {
|
||||
access_profiles: UserAccessProfile[];
|
||||
}
|
||||
17
ui/app/_fallbacks/enterprise/lib/types/largePayload.ts
Normal file
17
ui/app/_fallbacks/enterprise/lib/types/largePayload.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
export interface LargePayloadConfig {
|
||||
enabled: boolean;
|
||||
request_threshold_bytes: number;
|
||||
response_threshold_bytes: number;
|
||||
prefetch_size_bytes: number;
|
||||
max_payload_bytes: number;
|
||||
truncated_log_bytes: number;
|
||||
}
|
||||
|
||||
export const DefaultLargePayloadConfig: LargePayloadConfig = {
|
||||
enabled: false,
|
||||
request_threshold_bytes: 10 * 1024 * 1024, // 10MB
|
||||
response_threshold_bytes: 10 * 1024 * 1024, // 10MB
|
||||
prefetch_size_bytes: 64 * 1024, // 64KB
|
||||
max_payload_bytes: 500 * 1024 * 1024, // 500MB
|
||||
truncated_log_bytes: 1024 * 1024, // 1MB
|
||||
};
|
||||
30
ui/app/_fallbacks/enterprise/lib/types/user.ts
Normal file
30
ui/app/_fallbacks/enterprise/lib/types/user.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { UserAccessProfile } from "@enterprise/lib/types/accessProfile";
|
||||
|
||||
export interface User {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
role_id?: number;
|
||||
role?: {
|
||||
id: number;
|
||||
name: string;
|
||||
description: string;
|
||||
is_system_role: boolean;
|
||||
};
|
||||
profile?: Record<string, unknown>;
|
||||
config?: Record<string, unknown>;
|
||||
claims?: Record<string, unknown>;
|
||||
access_profile?: UserAccessProfile;
|
||||
teams?: Array<{ id: string; name: string; business_unit_id?: string; business_unit_name?: string }>;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface GetUsersResponse {
|
||||
users: User[];
|
||||
total: number;
|
||||
page: number;
|
||||
limit: number;
|
||||
total_pages: number;
|
||||
has_more: boolean;
|
||||
}
|
||||
Reference in New Issue
Block a user