mirror of
https://github.com/thomiceli/opengist.git
synced 2026-08-07 07:14:49 +00:00
Disable file upload (#737)
Go CI / Lint (push) Has been cancelled
Go CI / Check (push) Has been cancelled
Go CI / Test (mysql, 1.26, mysql:8, ubuntu-latest, 3306:3306) (push) Has been cancelled
Go CI / Test (postgres, 1.26, postgres:16, ubuntu-latest, 5432:5432) (push) Has been cancelled
Go CI / Test (sqlite, 1.26, macOS-latest) (push) Has been cancelled
Go CI / Test (sqlite, 1.26, ubuntu-latest) (push) Has been cancelled
Go CI / Build (1.26, macOS-latest) (push) Has been cancelled
Go CI / Build (1.26, ubuntu-latest) (push) Has been cancelled
Go CI / Build (1.26, windows-latest) (push) Has been cancelled
Go CI / Lint (push) Has been cancelled
Go CI / Check (push) Has been cancelled
Go CI / Test (mysql, 1.26, mysql:8, ubuntu-latest, 3306:3306) (push) Has been cancelled
Go CI / Test (postgres, 1.26, postgres:16, ubuntu-latest, 5432:5432) (push) Has been cancelled
Go CI / Test (sqlite, 1.26, macOS-latest) (push) Has been cancelled
Go CI / Test (sqlite, 1.26, ubuntu-latest) (push) Has been cancelled
Go CI / Build (1.26, macOS-latest) (push) Has been cancelled
Go CI / Build (1.26, ubuntu-latest) (push) Has been cancelled
Go CI / Build (1.26, windows-latest) (push) Has been cancelled
This commit is contained in:
@@ -59,6 +59,9 @@ http.git-enabled: true
|
||||
# Enable or disable the REST API (either `true` or `false`). Default: true
|
||||
api.enabled: true
|
||||
|
||||
# Disable file uploads when creating or editing gists (either `true` or `false`). Default: false
|
||||
disable-file-upload: false
|
||||
|
||||
# File permissions for Unix socket (octal format). Default: 0666
|
||||
unix-socket-permissions: 0666
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ aside: false
|
||||
| http.port | OG_HTTP_PORT | `6157` | The port on which the HTTP server should listen. |
|
||||
| http.git-enabled | OG_HTTP_GIT_ENABLED | `true` | Enable or disable git operations (clone, pull, push) via HTTP. (`true` or `false`) |
|
||||
| api.enabled | OG_API_ENABLED | `true` | Enable or disable the REST API. (`true` or `false`) |
|
||||
| disable-file-upload | OG_DISABLE_FILE_UPLOAD | `false` | Disable file uploads when creating or editing gists. (`true` or `false`) |
|
||||
| unix-socket-permissions | OG_UNIX_SOCKET_PERMISSIONS | `0666` | File permissions for Unix socket (octal format). |
|
||||
| metrics.enabled | OG_METRICS_ENABLED | `false` | Enable or disable Prometheus metrics server (`true` or `false`) |
|
||||
| metrics.host | OG_METRICS_HOST | `0.0.0.0` | The host on which the metrics server should bind. |
|
||||
|
||||
@@ -64,6 +64,8 @@ type config struct {
|
||||
|
||||
ApiEnabled bool `yaml:"api.enabled" env:"OG_API_ENABLED"`
|
||||
|
||||
DisableFileUpload bool `yaml:"disable-file-upload" env:"OG_DISABLE_FILE_UPLOAD"`
|
||||
|
||||
UnixSocketPermissions string `yaml:"unix-socket-permissions" env:"OG_UNIX_SOCKET_PERMISSIONS"`
|
||||
|
||||
SshGit string `yaml:"ssh.git-enabled" env:"OG_SSH_GIT_ENABLED"` // builtin | host | disabled (true → builtin, false → disabled)
|
||||
|
||||
@@ -272,6 +272,7 @@ error.invalid-number: Invalid number
|
||||
error.invalid-character-unescaped: Invalid character unescaped
|
||||
error.not-in-mfa-session: User is not in a MFA session
|
||||
error.no-file-uploaded: No file uploaded
|
||||
error.file-upload-disabled: File upload is disabled
|
||||
error.cannot-open-file: Cannot open uploaded file
|
||||
|
||||
header.menu.all: All
|
||||
|
||||
@@ -65,10 +65,10 @@ func ProcessCreate(ctx *context.Context) error {
|
||||
})
|
||||
}
|
||||
|
||||
// Process uploaded files from UUID arrays
|
||||
// Process uploaded files from UUID arrays, unless file upload is disabled instance-wide
|
||||
fileUUIDs := dto.UploadedFilesUUID
|
||||
fileFilenames := dto.UploadedFilesNames
|
||||
if len(fileUUIDs) == len(fileFilenames) {
|
||||
if !config.C.DisableFileUpload && len(fileUUIDs) == len(fileFilenames) {
|
||||
for i, fileUUID := range fileUUIDs {
|
||||
if !uuidRegex.MatchString(filepath.Base(fileUUID)) {
|
||||
continue
|
||||
|
||||
@@ -251,6 +251,15 @@ func checkRequireLogin(next Handler) Handler {
|
||||
return makeCheckRequireLogin(false)(next)
|
||||
}
|
||||
|
||||
func checkFileUploadEnabled(next Handler) Handler {
|
||||
return func(ctx *context.Context) error {
|
||||
if config.C.DisableFileUpload {
|
||||
return ctx.ErrorRes(403, ctx.Tr("error.file-upload-disabled"), nil)
|
||||
}
|
||||
return next(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// makeApiCheckRequireLogin is the /api/v1 counterpart of makeCheckRequireLogin:
|
||||
// it enforces the instance's RequireLogin / AllowGistsWithoutLogin settings on
|
||||
// anonymous gist reads, but responds with a JSON 401 instead of redirecting to
|
||||
|
||||
@@ -32,8 +32,8 @@ func (s *Server) registerRoutes() {
|
||||
r.GET("/", gist.Create, logged)
|
||||
r.POST("/", gist.ProcessCreate, logged)
|
||||
r.POST("/preview", gist.Preview, logged)
|
||||
r.POST("/upload", gist.Upload, logged)
|
||||
r.DELETE("/upload/:uuid", gist.DeleteUpload, logged)
|
||||
r.POST("/upload", gist.Upload, logged, checkFileUploadEnabled)
|
||||
r.DELETE("/upload/:uuid", gist.DeleteUpload, logged, checkFileUploadEnabled)
|
||||
|
||||
r.GET("/healthcheck", health.Healthcheck)
|
||||
|
||||
|
||||
+9
-3
@@ -324,9 +324,15 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
|
||||
// File upload functionality
|
||||
let uploadedFileUUIDs: {uuid: string, filename: string}[] = [];
|
||||
const fileUploadInput = document.getElementById("file-upload") as HTMLInputElement;
|
||||
const uploadedFilesContainer = document.getElementById("uploaded-files")!;
|
||||
const fileUploadZone = document.getElementById("file-upload-zone")!.querySelector('.border-dashed') as HTMLElement;
|
||||
const fileUploadInput = document.getElementById("file-upload") as HTMLInputElement | null;
|
||||
const uploadedFilesContainer = document.getElementById("uploaded-files");
|
||||
const fileUploadZoneEl = document.getElementById("file-upload-zone");
|
||||
|
||||
// File upload may be disabled instance-wide, in which case the upload zone is absent
|
||||
if (!fileUploadInput || !uploadedFilesContainer || !fileUploadZoneEl) {
|
||||
return;
|
||||
}
|
||||
const fileUploadZone = fileUploadZoneEl.querySelector('.border-dashed') as HTMLElement;
|
||||
|
||||
// Handle file selection
|
||||
const handleFiles = (files: FileList) => {
|
||||
|
||||
Vendored
+2
@@ -41,6 +41,7 @@
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
{{ if not .c.DisableFileUpload }}
|
||||
<div id="file-upload-zone" class="space-y-4">
|
||||
<label for="file-upload" class="cursor-pointer block">
|
||||
<div class="border-2 border-dashed border-gray-300 dark:border-gray-600 rounded-lg p-6 text-center hover:border-primary-400 dark:hover:border-primary-500 transition-colors">
|
||||
@@ -58,6 +59,7 @@
|
||||
</label>
|
||||
<div id="uploaded-files" class="space-y-2"></div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
<div class="flex items-center">
|
||||
<button type="button" id="add-file" class="inline-flex items-center px-4 py-2 border border-transparent border-gray-200 dark:border-gray-700 text-sm font-medium rounded-md shadow-sm text-gray-700 dark:text-white bg-gray-100 dark:bg-gray-600 hover:bg-gray-200 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500">{{ .locale.Tr "gist.new.add-file" }}</button>
|
||||
|
||||
Vendored
+2
@@ -72,6 +72,7 @@
|
||||
{{ template "_editor" . }}
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ if not .c.DisableFileUpload }}
|
||||
<div id="file-upload-zone" class="space-y-4">
|
||||
<label for="file-upload" class="cursor-pointer block">
|
||||
<div class="border-2 border-dashed border-gray-300 dark:border-gray-600 rounded-lg p-6 text-center hover:border-primary-400 dark:hover:border-primary-500 transition-colors">
|
||||
@@ -89,6 +90,7 @@
|
||||
</label>
|
||||
<div id="uploaded-files" class="space-y-2"></div>
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="flex">
|
||||
<button type="button" id="add-file" class="inline-flex items-center px-4 py-2 border border-transparent border-gray-200 dark:border-gray-700 text-sm font-medium rounded-md shadow-sm text-gray-700 dark:text-white bg-gray-100 dark:bg-gray-600 hover:bg-gray-200 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500">{{ .locale.Tr "gist.new.add-file" }}</button>
|
||||
<a href="{{ $.c.ExternalUrl }}/{{ .gist.User.Username }}/{{ .gist.Identifier }}" class="ml-auto inline-flex items-center px-4 py-2 border border-transparent border-gray-200 dark:border-gray-700 text-sm font-medium rounded-md shadow-sm bg-gray-100 dark:bg-gray-600 hover:bg-gray-200 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 text-rose-600 dark:text-rose-400 hover:text-rose-700">{{ .locale.Tr "gist.edit.cancel" }}</a>
|
||||
|
||||
Reference in New Issue
Block a user