fix: source owner_principal_id from current organization
OwnerPrincipalIdField was reading currentClusterAtom, which no callers ever wrote — so every form submission ended up with owner_principal_id=null and the backend rejected non-admins with "Only platform admin can create global ...". Pin the field to currentOrganizationId instead (the Org the caller is acting under). Cluster ownership is the wrong source: a cluster_access grant lets one Org schedule on another Org's cluster, but the new resource is still owned by the caller's Org, and the backend enforces owner_principal_id == ctx.current_principal_id. Also drops the dead currentClusterAtom.
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
import { ClusterListItem } from '@/pages/cluster-management/config/types';
|
||||
import { atom } from 'jotai';
|
||||
|
||||
export const currentClusterAtom = atom<
|
||||
(Partial<ClusterListItem> & { label?: string; value?: number }) | null
|
||||
>(null);
|
||||
@@ -3,6 +3,15 @@ import { atomWithStorage } from 'jotai/utils';
|
||||
|
||||
export const userAtom = atomWithStorage<any>('userInfo', null);
|
||||
|
||||
// Backs the `currentOrganizationId` localStorage key. Stays null in
|
||||
// builds with no Org context (single-tenant), and is shared with any
|
||||
// extension that persists the same key so both sides stay in sync
|
||||
// without one side having to import from the other.
|
||||
export const currentOrganizationIdAtom = atomWithStorage<number | null>(
|
||||
'currentOrganizationId',
|
||||
null
|
||||
);
|
||||
|
||||
export const GPUStackVersionAtom = atom<{
|
||||
version: string;
|
||||
git_commit: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { currentClusterAtom } from '@/atoms/gpuservice';
|
||||
import { currentOrganizationIdAtom } from '@/atoms/user';
|
||||
import { Input as CInput } from '@gpustack/core-ui';
|
||||
import { Form } from 'antd';
|
||||
import type { NamePath } from 'antd/es/form/interface';
|
||||
@@ -9,18 +9,22 @@ interface OwnerPrincipalIdFieldProps {
|
||||
name?: NamePath;
|
||||
}
|
||||
|
||||
// Pins `owner_principal_id` to the Org the caller is currently acting
|
||||
// under. Cluster ownership is irrelevant here: cluster_access grants
|
||||
// let one Org schedule on another Org's cluster, but the resource the
|
||||
// caller creates still belongs to *their* Org, and the backend enforces
|
||||
// `owner_principal_id == ctx.current_principal_id`.
|
||||
const OwnerPrincipalIdField: React.FC<OwnerPrincipalIdFieldProps> = ({
|
||||
name = 'owner_principal_id'
|
||||
}) => {
|
||||
const currentCluster = useAtomValue(currentClusterAtom);
|
||||
const ownerPrincipalId = currentCluster?.owner_principal_id;
|
||||
const currentOrgId = useAtomValue(currentOrganizationIdAtom);
|
||||
const form = Form.useFormInstance();
|
||||
|
||||
useEffect(() => {
|
||||
if (ownerPrincipalId != null) {
|
||||
form.setFieldValue(name, ownerPrincipalId);
|
||||
if (currentOrgId != null) {
|
||||
form.setFieldValue(name, currentOrgId);
|
||||
}
|
||||
}, [ownerPrincipalId, name, form]);
|
||||
}, [currentOrgId, name, form]);
|
||||
|
||||
return (
|
||||
<Form.Item name={name} hidden>
|
||||
|
||||
Reference in New Issue
Block a user