mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
fix(mcp): block view-only admin from /register; log settings failure; warn on active server reject
This commit is contained in:
parent
1a2d7fd7f6
commit
90e256d805
2 changed files with 17 additions and 4 deletions
|
|
@ -746,7 +746,10 @@ if MCP_AVAILABLE:
|
|||
Creates the server with approval_status=pending_review.
|
||||
Requires a team-scoped API key.
|
||||
"""
|
||||
if user_api_key_dict.user_role == LitellmUserRoles.PROXY_ADMIN:
|
||||
if user_api_key_dict.user_role in (
|
||||
LitellmUserRoles.PROXY_ADMIN,
|
||||
LitellmUserRoles.PROXY_ADMIN_VIEW_ONLY,
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail={
|
||||
|
|
|
|||
|
|
@ -78,13 +78,17 @@ function StatCard({
|
|||
type ConfirmDialogProps = {
|
||||
action: "approve" | "reject";
|
||||
serverName: string;
|
||||
isCurrentlyActive?: boolean;
|
||||
onConfirm: (reviewNotes?: string) => void;
|
||||
onCancel: () => void;
|
||||
};
|
||||
|
||||
function ConfirmDialog({ action, serverName, onConfirm, onCancel }: ConfirmDialogProps) {
|
||||
function ConfirmDialog({ action, serverName, isCurrentlyActive, onConfirm, onCancel }: ConfirmDialogProps) {
|
||||
const [reviewNotes, setReviewNotes] = useState("");
|
||||
const isApprove = action === "approve";
|
||||
const rejectBody = isCurrentlyActive
|
||||
? "This server is currently live. Rejecting it will immediately remove it from the proxy runtime."
|
||||
: "This will mark the submission as rejected.";
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black/30 flex items-center justify-center z-50">
|
||||
<div className="bg-white rounded-xl shadow-xl p-6 max-w-sm w-full mx-4">
|
||||
|
|
@ -107,7 +111,7 @@ function ConfirmDialog({ action, serverName, onConfirm, onCancel }: ConfirmDialo
|
|||
<span className="font-medium text-gray-700">"{serverName}"</span>?{" "}
|
||||
{isApprove
|
||||
? "This will make it active and available for use."
|
||||
: "This will mark it as rejected."}
|
||||
: rejectBody}
|
||||
</p>
|
||||
{!isApprove && (
|
||||
<textarea
|
||||
|
|
@ -468,6 +472,7 @@ export function MCPSubmissionsTab({ accessToken }: MCPSubmissionsTabProps) {
|
|||
serverId: string;
|
||||
serverName: string;
|
||||
action: "approve" | "reject";
|
||||
isCurrentlyActive?: boolean;
|
||||
} | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
|
@ -484,7 +489,10 @@ export function MCPSubmissionsTab({ accessToken }: MCPSubmissionsTabProps) {
|
|||
try {
|
||||
const [res, settings] = await Promise.all([
|
||||
fetchMCPSubmissions(accessToken),
|
||||
getGeneralSettingsCall(accessToken).catch(() => null),
|
||||
getGeneralSettingsCall(accessToken).catch((err) => {
|
||||
console.warn("MCPSubmissionsTab: failed to load general settings, compliance rules will be empty:", err);
|
||||
return null;
|
||||
}),
|
||||
]);
|
||||
setSummary(res);
|
||||
if (settings?.data && Array.isArray(settings.data)) {
|
||||
|
|
@ -625,6 +633,7 @@ export function MCPSubmissionsTab({ accessToken }: MCPSubmissionsTabProps) {
|
|||
serverId: server.server_id,
|
||||
serverName: server.alias ?? server.server_name ?? server.server_id,
|
||||
action: "reject",
|
||||
isCurrentlyActive: server.approval_status === "active",
|
||||
})
|
||||
}
|
||||
/>
|
||||
|
|
@ -635,6 +644,7 @@ export function MCPSubmissionsTab({ accessToken }: MCPSubmissionsTabProps) {
|
|||
<ConfirmDialog
|
||||
action={confirmAction.action}
|
||||
serverName={confirmAction.serverName}
|
||||
isCurrentlyActive={confirmAction.isCurrentlyActive}
|
||||
onConfirm={(reviewNotes) =>
|
||||
confirmAction.action === "approve"
|
||||
? handleApprove(confirmAction.serverId, confirmAction.serverName)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue