mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/1Panel-dev/1Panel.git
synced 2026-09-20 08:03:55 +08:00
fix: tighten rbac and release resources (#12886)
This commit is contained in:
@@ -748,7 +748,6 @@ func upgradeInstall(req request.AppInstallUpgrade) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dockerCLi, _ := docker.NewClient()
|
||||
if req.PullImage {
|
||||
composeContent := []byte(detail.DockerCompose)
|
||||
if req.DockerCompose != "" {
|
||||
@@ -758,6 +757,11 @@ func upgradeInstall(req request.AppInstallUpgrade) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dockerCLi, err := docker.NewClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dockerCLi.Close()
|
||||
for _, image := range images {
|
||||
t.Log(i18n.GetWithName("PullImageStart", image))
|
||||
if err = dockerCLi.PullImageWithProcess(t, image); err != nil {
|
||||
@@ -1182,6 +1186,7 @@ func upApp(task *task.Task, appInstall *model.AppInstall, pullImages bool) error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dockerCLi.Close()
|
||||
for _, image := range images {
|
||||
if imagePrefix != "" {
|
||||
lastSlashIndex := strings.LastIndex(image, "/")
|
||||
|
||||
@@ -377,6 +377,7 @@ func snapAppImage(snap snapHelper, req dto.SnapshotCreate, targetDir string) err
|
||||
snap.Task.Log("load docker client failed, skip save app images")
|
||||
return nil
|
||||
}
|
||||
defer client.Close()
|
||||
images, err := client.ImageList(context.Background(), image.ListOptions{})
|
||||
if err != nil {
|
||||
snap.Task.Log("list docker images failed, skip save app images")
|
||||
|
||||
@@ -503,6 +503,7 @@ func loadImage(dbType, version string) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer cli.Close()
|
||||
images, err := cli.ImageList(context.Background(), image.ListOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
||||
@@ -40,6 +40,7 @@ func HandleGet(url string) (*http.Response, error) {
|
||||
}
|
||||
}
|
||||
if resp.StatusCode == 404 {
|
||||
_ = resp.Body.Close()
|
||||
return nil, buserr.New("ErrHttpReqNotFound")
|
||||
}
|
||||
|
||||
@@ -71,6 +72,7 @@ func HandleRequestWithClient(client *http.Client, url, method string, timeout in
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return 0, nil, errors.New(resp.Status)
|
||||
}
|
||||
@@ -78,7 +80,6 @@ func HandleRequestWithClient(client *http.Client, url, method string, timeout in
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return resp.StatusCode, body, nil
|
||||
}
|
||||
@@ -143,6 +144,7 @@ func RequestFile(url, method string, timeout int) (io.ReadCloser, context.Cancel
|
||||
return nil, cancel, err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
_ = resp.Body.Close()
|
||||
return nil, cancel, errors.New(resp.Status)
|
||||
}
|
||||
return resp.Body, cancel, nil
|
||||
|
||||
@@ -190,6 +190,7 @@ func HandleRequest(url, method string, timeout int) (int, []byte, error) {
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return 0, nil, errors.New(resp.Status)
|
||||
}
|
||||
@@ -197,7 +198,6 @@ func HandleRequest(url, method string, timeout int) (int, []byte, error) {
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return resp.StatusCode, body, nil
|
||||
}
|
||||
|
||||
@@ -807,10 +807,10 @@ func checkProxy(req dto.ProxyUpdate) error {
|
||||
if err != nil {
|
||||
return buserr.WithErr("ErrProxySetting", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if _, err := io.ReadAll(resp.Body); err != nil {
|
||||
return buserr.WithErr("ErrProxySetting", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -314,11 +314,11 @@ func (u *UpgradeService) LoadRelease() ([]dto.ReleasesNotes, error) {
|
||||
if err != nil {
|
||||
return notes, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return notes, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
var nodeItem noteHelper
|
||||
if err := json.Unmarshal(body, &nodeItem); err != nil {
|
||||
return notes, err
|
||||
|
||||
@@ -54,11 +54,11 @@ func handleRequestWithTransport(url, method string, transport *http.Transport, t
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return resp.StatusCode, body, nil
|
||||
}
|
||||
@@ -106,6 +106,7 @@ func handleGetWithTransport(url string, transport *http.Transport) (*http.Respon
|
||||
}
|
||||
}
|
||||
if resp.StatusCode == 404 {
|
||||
_ = resp.Body.Close()
|
||||
return nil, buserr.WithErr("ErrHttpReqNotFound", errors.New("no such resource"))
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ export namespace Login {
|
||||
mfaInterval: number;
|
||||
role: string;
|
||||
permissions: string[];
|
||||
masterOnlyPermissions?: string[];
|
||||
nodeRoles: Array<{ nodeId: number; nodeName: string; roleId: number; roleName: string }>;
|
||||
|
||||
apiInterfaceStatus: string;
|
||||
|
||||
@@ -57,6 +57,7 @@ export interface GlobalState {
|
||||
// tags
|
||||
isAdmin: boolean;
|
||||
permissions: string[];
|
||||
masterOnlyPermissions: string[];
|
||||
nodeRoles: Array<{ nodeId: number; nodeName: string; roleId: number; roleName: string }>;
|
||||
isEnterprise: boolean;
|
||||
isIntl: boolean;
|
||||
|
||||
@@ -4,7 +4,7 @@ import piniaPersistConfig from '@/config/pinia-persist';
|
||||
import { GlobalState } from '../interface';
|
||||
import { DeviceType } from '@/enums/app';
|
||||
import i18n, { setActiveLocale } from '@/lang';
|
||||
import { isMasterOnlyPermissionCode, toManageCode } from '@/utils/permission-codes';
|
||||
import { isMasterOnlyPermissionCode, setMasterOnlyPermissionCodes, toManageCode } from '@/utils/permission-codes';
|
||||
|
||||
const CN_DOCS_URL = 'https://1panel.cn/docs/v2';
|
||||
const INTL_DOCS_URL = 'https://docs.1panel.pro/v2';
|
||||
@@ -55,6 +55,7 @@ const GlobalStore = defineStore('GlobalState', {
|
||||
// tags
|
||||
isAdmin: false,
|
||||
permissions: [],
|
||||
masterOnlyPermissions: [],
|
||||
nodeRoles: [],
|
||||
isEnterprise: false,
|
||||
isIntl: false,
|
||||
@@ -109,18 +110,24 @@ const GlobalStore = defineStore('GlobalState', {
|
||||
setAuthInfo(payload: {
|
||||
isAdmin: boolean;
|
||||
permissions: string[];
|
||||
masterOnlyPermissions?: string[];
|
||||
nodeRoles?: Array<{ nodeId: number; nodeName: string; roleId: number; roleName: string }>;
|
||||
}) {
|
||||
this.isAdmin = !!payload.isAdmin;
|
||||
this.permissions = payload.permissions || [];
|
||||
this.masterOnlyPermissions = payload.masterOnlyPermissions || [];
|
||||
this.nodeRoles = payload.nodeRoles || [];
|
||||
setMasterOnlyPermissionCodes(this.masterOnlyPermissions);
|
||||
},
|
||||
clearAuthInfo() {
|
||||
this.permissions = [];
|
||||
this.masterOnlyPermissions = [];
|
||||
this.nodeRoles = [];
|
||||
this.isAdmin = false;
|
||||
setMasterOnlyPermissionCodes([]);
|
||||
},
|
||||
hasPermission(permission: string) {
|
||||
setMasterOnlyPermissionCodes(this.masterOnlyPermissions);
|
||||
const normalizedPermission = permission.trim();
|
||||
if (!normalizedPermission) {
|
||||
return false;
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
const masterOnlyPermissionCodes = new Set([
|
||||
'ai_proxy_view',
|
||||
'ai_proxy_manage',
|
||||
'ai_proxy_key_view',
|
||||
'ai_benchmark_view',
|
||||
'ai_benchmark_manage',
|
||||
'ai_skills_hub_view',
|
||||
'ai_skills_hub_manage',
|
||||
'xpack_ops_report_view',
|
||||
'xpack_ops_report_manage',
|
||||
]);
|
||||
let masterOnlyPermissionCodes = new Set<string>();
|
||||
let masterOnlyPermissionCodesKey = '';
|
||||
|
||||
export const setMasterOnlyPermissionCodes = (permissions?: string[]) => {
|
||||
const codes = (permissions || []).filter(Boolean);
|
||||
const key = codes.join('\n');
|
||||
if (key === masterOnlyPermissionCodesKey) {
|
||||
return;
|
||||
}
|
||||
masterOnlyPermissionCodesKey = key;
|
||||
masterOnlyPermissionCodes = new Set(codes);
|
||||
};
|
||||
|
||||
export const toManageCode = (permission: string): string => {
|
||||
if (!permission) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import router from '@/routers';
|
||||
import { GlobalStore } from '@/store';
|
||||
import { isMasterOnlyPermissionCode, normalizeToManageCode } from '@/utils/permission-codes';
|
||||
import { normalizeToManageCode } from '@/utils/permission-codes';
|
||||
|
||||
export type PermissionBindingValue = string | string[] | undefined;
|
||||
export type PermissionMode = 'manage' | 'view';
|
||||
@@ -51,15 +51,7 @@ const hasPermissionAccessByMode = (mode: PermissionMode, value?: PermissionBindi
|
||||
const permissions = toPermissionList(value);
|
||||
const normalizedPermissions = mode === 'manage' ? permissions.map(toManagePermission).filter(Boolean) : permissions;
|
||||
if (normalizedPermissions.length === 0) {
|
||||
return globalStore.isAdmin || globalStore.isNodeAdmin;
|
||||
}
|
||||
if (
|
||||
mode === 'manage' &&
|
||||
globalStore.isNodeAdmin &&
|
||||
!globalStore.isMaster &&
|
||||
normalizedPermissions.some((permission) => !isMasterOnlyPermissionCode(permission))
|
||||
) {
|
||||
return true;
|
||||
return globalStore.isAdmin;
|
||||
}
|
||||
return normalizedPermissions.some((permission) => globalStore.hasPermission(permission));
|
||||
};
|
||||
|
||||
@@ -25,6 +25,7 @@ export const syncAuthInfo = async (currentNode?: string) => {
|
||||
globalStore.setAuthInfo({
|
||||
isAdmin: res.data.role === 'ADMIN',
|
||||
permissions: res.data.permissions || [],
|
||||
masterOnlyPermissions: res.data.masterOnlyPermissions || [],
|
||||
nodeRoles: res.data.nodeRoles || [],
|
||||
});
|
||||
return res.data;
|
||||
@@ -33,6 +34,7 @@ export const syncAuthInfo = async (currentNode?: string) => {
|
||||
globalStore.setAuthInfo({
|
||||
isAdmin: res.data.role === 'ADMIN',
|
||||
permissions: res.data.permissions || [],
|
||||
masterOnlyPermissions: res.data.masterOnlyPermissions || [],
|
||||
nodeRoles: res.data.nodeRoles || [],
|
||||
});
|
||||
return res.data;
|
||||
|
||||
Reference in New Issue
Block a user