diff --git a/agent/utils/files/fileinfo.go b/agent/utils/files/fileinfo.go index 25c5380e0e0b..0d6900ccdc6d 100644 --- a/agent/utils/files/fileinfo.go +++ b/agent/utils/files/fileinfo.go @@ -92,31 +92,33 @@ var binaryPreviewExtensions = map[string]struct{}{ } type FileInfo struct { - Fs afero.Fs `json:"-"` - Path string `json:"path"` - Name string `json:"name"` - User string `json:"user"` - Group string `json:"group"` - Uid string `json:"uid"` - Gid string `json:"gid"` - Extension string `json:"extension"` - Content string `json:"content"` - Size int64 `json:"size"` - IsDir bool `json:"isDir"` - IsSymlink bool `json:"isSymlink"` - IsHidden bool `json:"isHidden"` - LinkPath string `json:"linkPath"` - Type string `json:"type"` - Mode string `json:"mode"` - MimeType string `json:"mimeType"` - UpdateTime time.Time `json:"updateTime"` - ModTime time.Time `json:"modTime"` - FileMode os.FileMode `json:"-"` - Items []*FileInfo `json:"items"` - ItemTotal int `json:"itemTotal"` - FavoriteID uint `json:"favoriteID"` - ShareCode string `json:"shareCode"` - IsDetail bool `json:"isDetail"` + Fs afero.Fs `json:"-"` + Path string `json:"path"` + Name string `json:"name"` + User string `json:"user"` + Group string `json:"group"` + Uid string `json:"uid"` + Gid string `json:"gid"` + Extension string `json:"extension"` + Content string `json:"content"` + Size int64 `json:"size"` + IsDir bool `json:"isDir"` + IsSymlink bool `json:"isSymlink"` + IsHidden bool `json:"isHidden"` + LinkPath string `json:"linkPath"` + Type string `json:"type"` + Mode string `json:"mode"` + MimeType string `json:"mimeType"` + UpdateTime time.Time `json:"updateTime"` + ModTime time.Time `json:"modTime"` + FileMode os.FileMode `json:"-"` + Items []*FileInfo `json:"items"` + ItemTotal int `json:"itemTotal"` + FavoriteID uint `json:"favoriteID"` + ShareCode string `json:"shareCode"` + IsDetail bool `json:"isDetail"` + IsAppendOnly bool `json:"isAppendOnly"` + IsImmutable bool `json:"isImmutable"` } type FileOption struct { @@ -173,6 +175,7 @@ func NewFileInfo(op FileOption) (*FileInfo, error) { if favorite.ID > 0 { file.FavoriteID = favorite.ID } + file.IsAppendOnly, file.IsImmutable = getFileAttributes(op.Path) if file.IsSymlink { linkPath := GetSymlink(op.Path) @@ -204,6 +207,18 @@ func NewFileInfo(op FileOption) (*FileInfo, error) { return file, nil } +func getFileAttributes(filePath string) (bool, bool) { + output, err := exec.Command("lsattr", "-d", "--", filePath).Output() + if err != nil { + return false, false + } + fields := strings.Fields(string(output)) + if len(fields) == 0 { + return false, false + } + return strings.Contains(fields[0], "a"), strings.Contains(fields[0], "i") +} + func handleExpansion(file *FileInfo, op FileOption) error { if file.IsDir { return file.listChildren(op) diff --git a/frontend/src/api/interface/file.ts b/frontend/src/api/interface/file.ts index a2fb9178fabb..886580aee063 100644 --- a/frontend/src/api/interface/file.ts +++ b/frontend/src/api/interface/file.ts @@ -25,6 +25,8 @@ export namespace File { favoriteID: number; shareCode: string; remark?: string; + isAppendOnly: boolean; + isImmutable: boolean; } export interface ReqFile extends ReqPage { @@ -117,6 +119,7 @@ export namespace File { linkPath?: boolean; sub?: boolean; name?: string; + isAppendOnly?: boolean; } export interface FileDelete { diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 2b7e74392ead..2cc7d6edfe61 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -5050,6 +5050,8 @@ const message = { }, tamper: { tamper: 'Website Tamper Protection', + tamperCreateHint: + 'The current directory may be affected by tamper protection or file attributes, causing creation to fail.', ignoreTemplate: 'Exclusion Template', protectTemplate: 'Protection Template', ignoreTemplateHelper: diff --git a/frontend/src/lang/modules/es-es.ts b/frontend/src/lang/modules/es-es.ts index ce2bd960170d..9045b736f6a5 100644 --- a/frontend/src/lang/modules/es-es.ts +++ b/frontend/src/lang/modules/es-es.ts @@ -5092,6 +5092,8 @@ const message = { }, tamper: { tamper: 'Anti-manipulación web', + tamperCreateHint: + 'El directorio actual puede verse afectado por la protección antimanipulación o los atributos de archivo, lo que provoca un error de creación.', ignoreTemplate: 'Plantilla de Exclusión', protectTemplate: 'Plantilla de Protección', ignoreTemplateHelper: diff --git a/frontend/src/lang/modules/fa.ts b/frontend/src/lang/modules/fa.ts index d6ed9939ce76..aeee0220e3e5 100644 --- a/frontend/src/lang/modules/fa.ts +++ b/frontend/src/lang/modules/fa.ts @@ -5013,6 +5013,8 @@ const message = { }, tamper: { tamper: 'محافظت در برابر دستکاری وب‌سایت', + tamperCreateHint: + 'دایرکتوری فعلی ممکن است تحت تأثیر محافظت در برابر دستکاری یا ویژگی‌های فایل باشد و ایجاد با خطا مواجه شود.', ignoreTemplate: 'الگوی حذف', protectTemplate: 'الگوی محافظت', ignoreTemplateHelper: diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts index b91406c78c46..a6cd77b53dbb 100644 --- a/frontend/src/lang/modules/ja.ts +++ b/frontend/src/lang/modules/ja.ts @@ -5065,6 +5065,7 @@ const message = { }, tamper: { tamper: 'ウェブサイトの改ざん防止', + tamperCreateHint: '現在のディレクトリは改ざん防止またはファイル属性の影響を受け、作成に失敗する可能性があります。', ignoreTemplate: '除外テンプレート', protectTemplate: '保護テンプレート', ignoreTemplateHelper: diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts index 95909b2a2324..59e866ee5c6c 100644 --- a/frontend/src/lang/modules/ko.ts +++ b/frontend/src/lang/modules/ko.ts @@ -4969,6 +4969,7 @@ const message = { }, tamper: { tamper: '웹사이트 변조 방지', + tamperCreateHint: '현재 디렉터리는 변조 방지 또는 파일 속성의 영향을 받아 생성에 실패할 수 있습니다.', ignoreTemplate: '제외 템플릿', protectTemplate: '보호 템플릿', ignoreTemplateHelper: diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts index c0e8b2e9f488..e517e1e82102 100644 --- a/frontend/src/lang/modules/ms.ts +++ b/frontend/src/lang/modules/ms.ts @@ -5128,6 +5128,8 @@ const message = { }, tamper: { tamper: 'Perlindungan laman web', + tamperCreateHint: + 'Direktori semasa mungkin dipengaruhi oleh perlindungan gangguan atau atribut fail, menyebabkan penciptaan gagal.', ignoreTemplate: 'Templat Pengecualian', protectTemplate: 'Templat Perlindungan', ignoreTemplateHelper: diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts index 0cb67fd64175..bd6e1b2ed014 100644 --- a/frontend/src/lang/modules/pt-br.ts +++ b/frontend/src/lang/modules/pt-br.ts @@ -5274,6 +5274,8 @@ const message = { }, tamper: { tamper: 'Proteção contra adulteração do site', + tamperCreateHint: + 'O diretório atual pode ser afetado pela proteção contra alterações ou por atributos de arquivo, causando falha na criação.', ignoreTemplate: 'Modelo de Exclusão', protectTemplate: 'Modelo de Proteção', ignoreTemplateHelper: diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts index 2a83aa84f58f..be98a40ba95c 100644 --- a/frontend/src/lang/modules/ru.ts +++ b/frontend/src/lang/modules/ru.ts @@ -5121,6 +5121,8 @@ const message = { }, tamper: { tamper: 'Защита от подделки сайта', + tamperCreateHint: + 'Текущий каталог может быть затронут защитой от изменений или атрибутами файла, что приведет к ошибке создания.', ignoreTemplate: 'Шаблон Исключения', protectTemplate: 'Шаблон Защиты', ignoreTemplateHelper: diff --git a/frontend/src/lang/modules/tr.ts b/frontend/src/lang/modules/tr.ts index 9207aa6cbe55..5706abeabad7 100644 --- a/frontend/src/lang/modules/tr.ts +++ b/frontend/src/lang/modules/tr.ts @@ -5117,6 +5117,8 @@ const message = { }, tamper: { tamper: 'Web Sitesi Değiştirme Koruması', + tamperCreateHint: + 'Geçerli dizin kurcalama korumasından veya dosya özniteliklerinden etkilenerek oluşturma işleminin başarısız olmasına neden olabilir.', ignoreTemplate: 'Hariç Tutma Şablonu', protectTemplate: 'Koruma Şablonu', ignoreTemplateHelper: diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts index e073d31b5ddc..124903e721f6 100644 --- a/frontend/src/lang/modules/zh-Hant.ts +++ b/frontend/src/lang/modules/zh-Hant.ts @@ -4710,6 +4710,7 @@ const message = { }, tamper: { tamper: '網站防篡改', + tamperCreateHint: '目前目錄可能受防篡改或檔案屬性限制影響,導致建立失敗。', ignoreTemplate: '排除範本', protectTemplate: '保護範本', ignoreTemplateHelper: diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 320c1f53de17..3be2918c6da1 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -4159,6 +4159,7 @@ const message = { }, tamper: { tamper: '网站防篡改', + tamperCreateHint: '当前目录可能受防篡改或文件属性限制影响,导致创建失败。', ignoreTemplate: '排除模版', protectTemplate: '保护模版', ignoreTemplateHelper: diff --git a/frontend/src/views/host/file-management/create/index.vue b/frontend/src/views/host/file-management/create/index.vue index f86048d96394..10f4ace9d1fc 100644 --- a/frontend/src/views/host/file-management/create/index.vue +++ b/frontend/src/views/host/file-management/create/index.vue @@ -1,7 +1,14 @@