diff --git a/docs/rest-api.md b/docs/rest-api.md
index f4b20b03..94afb8f9 100644
--- a/docs/rest-api.md
+++ b/docs/rest-api.md
@@ -41,3 +41,5 @@ You can also restrict administrator access based on the source IP address. If yo
The OpenAPI 3 schema for the exposed API can be found inside the source tree: [openapi.yaml](../httpd/schema/openapi.yaml "OpenAPI 3 specs").
You can generate your own REST client in your preferred programming language, or even bash scripts, using an OpenAPI generator such as [swagger-codegen](https://github.com/swagger-api/swagger-codegen) or [OpenAPI Generator](https://openapi-generator.tech/).
+
+You can also use [Swagger UI](https://github.com/swagger-api/swagger-ui).
diff --git a/examples/rest-api-cli/README.md b/examples/rest-api-cli/README.md
index 46edd959..2a8ba037 100644
--- a/examples/rest-api-cli/README.md
+++ b/examples/rest-api-cli/README.md
@@ -1,6 +1,6 @@
# REST API CLI client
-:warning: This sample client is deprecated and it will work only with api V1 (SFTPGo <= 1.2.2). You can easily build your own client from the OpenAPI schema.
+:warning: This sample client is deprecated and it will work only with API V1 (SFTPGo <= 1.2.2). You can easily build your own client from the [OpenAPI](../../httpd/schema/openapi.yaml) schema or use [Swagger UI](https://github.com/swagger-api/swagger-ui).
`sftpgo_api_cli` is a very simple command line client for `SFTPGo` REST API written in python.
diff --git a/httpd/api_admin.go b/httpd/api_admin.go
index 781d673a..1b20f3ed 100644
--- a/httpd/api_admin.go
+++ b/httpd/api_admin.go
@@ -131,7 +131,7 @@ func updateAdmin(w http.ResponseWriter, r *http.Request) {
sendAPIResponse(w, r, err, "", getRespStatus(err))
return
}
- sendAPIResponse(w, r, nil, "Update admin", http.StatusOK)
+ sendAPIResponse(w, r, nil, "Admin updated", http.StatusOK)
}
func deleteAdmin(w http.ResponseWriter, r *http.Request) {
diff --git a/httpd/schema/openapi.yaml b/httpd/schema/openapi.yaml
index 73f8ddbd..2e405d5d 100644
--- a/httpd/schema/openapi.yaml
+++ b/httpd/schema/openapi.yaml
@@ -2,7 +2,7 @@ openapi: 3.0.3
info:
title: SFTPGo
description: SFTPGo REST API
- version: 2.4.0
+ version: 2.4.1
servers:
- url: /api/v2
@@ -327,7 +327,7 @@ paths:
example: reset
requestBody:
required: true
- description: The only user mandatory fields are username,used_quota_size and used_quota_files. Please note that if the quota fields are missing they will default to 0
+ description: The only user mandatory fields are username, used_quota_size and used_quota_files. Please note that if the quota fields are missing they will default to 0
content:
application/json:
schema:
@@ -723,7 +723,7 @@ paths:
schema:
$ref : '#/components/schemas/ApiResponse'
example:
- message: "User updated"
+ message: "Admin updated"
400:
$ref: '#/components/responses/BadRequest'
401:
@@ -756,7 +756,7 @@ paths:
schema:
$ref : '#/components/schemas/ApiResponse'
example:
- message: "User deleted"
+ message: "Admin deleted"
400:
$ref: '#/components/responses/BadRequest'
401:
@@ -1688,7 +1688,7 @@ components:
description: connection time as unix timestamp in milliseconds
command:
type: string
- description: SSH/FTP command or WebDAV method
+ description: Last SSH/FTP command or WebDAV method
last_activity:
type: integer
format: int64
@@ -1795,13 +1795,16 @@ components:
type: array
items:
$ref: '#/components/schemas/SSHBinding'
+ nullable: true
host_keys:
type: array
items:
$ref: '#/components/schemas/SSHHostKey'
+ nullable: true
ssh_commands:
- type: string
- description: accepted SSH commands comma separated
+ type: array
+ items:
+ type: string
FTPPassivePortRange:
type: object
properties:
@@ -1818,6 +1821,7 @@ components:
type: array
items:
$ref: '#/components/schemas/FTPDBinding'
+ nullable: true
passive_port_range:
$ref: '#/components/schemas/FTPPassivePortRange'
WebDAVServiceStatus:
@@ -1829,6 +1833,7 @@ components:
type: array
items:
$ref: '#/components/schemas/WebDAVBinding'
+ nullable: true
DataProviderStatus:
type: object
properties:
diff --git a/sftpd/server.go b/sftpd/server.go
index 0fa9292e..a11b9fc6 100644
--- a/sftpd/server.go
+++ b/sftpd/server.go
@@ -258,7 +258,7 @@ func (c *Configuration) Initialize(configDir string) error {
}
serviceStatus.IsActive = true
- serviceStatus.SSHCommands = strings.Join(c.EnabledSSHCommands, ", ")
+ serviceStatus.SSHCommands = c.EnabledSSHCommands
return <-exitChannel
}
diff --git a/sftpd/sftpd.go b/sftpd/sftpd.go
index a179821c..ad45f26e 100644
--- a/sftpd/sftpd.go
+++ b/sftpd/sftpd.go
@@ -4,6 +4,7 @@
package sftpd
import (
+ "strings"
"time"
)
@@ -39,10 +40,15 @@ type HostKey struct {
type ServiceStatus struct {
IsActive bool `json:"is_active"`
Bindings []Binding `json:"bindings"`
- SSHCommands string `json:"ssh_commands"`
+ SSHCommands []string `json:"ssh_commands"`
HostKeys []HostKey `json:"host_keys"`
}
+// GetSSHCommandsAsString returns enabled SSH commands as comma separated string
+func (s ServiceStatus) GetSSHCommandsAsString() string {
+ return strings.Join(s.SSHCommands, ", ")
+}
+
// GetStatus returns the server status
func GetStatus() ServiceStatus {
return serviceStatus
diff --git a/sftpd/sftpd_test.go b/sftpd/sftpd_test.go
index b9f29c5c..c83710cd 100644
--- a/sftpd/sftpd_test.go
+++ b/sftpd/sftpd_test.go
@@ -385,6 +385,8 @@ func TestBasicSFTPHandling(t *testing.T) {
assert.NoError(t, err)
status := sftpd.GetStatus()
assert.True(t, status.IsActive)
+ sshCommands := status.GetSSHCommandsAsString()
+ assert.NotEmpty(t, sshCommands)
}
func TestBasicSFTPFsHandling(t *testing.T) {
diff --git a/templates/status.html b/templates/status.html
index a5367393..a7af9580 100644
--- a/templates/status.html
+++ b/templates/status.html
@@ -16,7 +16,7 @@
Address: "{{.GetAddress}}" {{if .HasProxy}}Proxy: ON{{end}}
{{end}}
- Accepted commands: "{{.Status.SSH.SSHCommands}}"
+ Accepted commands: "{{.Status.SSH.GetSSHCommandsAsString}}"
{{range .Status.SSH.HostKeys}}