mirror of
https://github.com/drakkan/sftpgo.git
synced 2024-11-21 23:20:24 +00:00
remove deprecated APIs
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
93ce593ed0
commit
686166f2ce
13 changed files with 117 additions and 1132 deletions
|
@ -1,6 +1,6 @@
|
|||
# SFTPGo
|
||||
|
||||
![CI Status](https://github.com/drakkan/sftpgo/workflows/CI/badge.svg?branch=main&event=push)
|
||||
[![CI Status](https://github.com/drakkan/sftpgo/workflows/CI/badge.svg?branch=main&event=push)](https://github.com/drakkan/sftpgo/workflows/CI/badge.svg?branch=main&event=push)
|
||||
[![Code Coverage](https://codecov.io/gh/drakkan/sftpgo/branch/main/graph/badge.svg)](https://codecov.io/gh/drakkan/sftpgo/branch/main)
|
||||
[![License: AGPL v3](https://img.shields.io/badge/License-AGPLv3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
|
||||
[![Docker Pulls](https://img.shields.io/docker/pulls/drakkan/sftpgo)](https://hub.docker.com/r/drakkan/sftpgo)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# SFTPGo
|
||||
|
||||
![CI Status](https://github.com/drakkan/sftpgo/workflows/CI/badge.svg?branch=main&event=push)
|
||||
[![CI Status](https://github.com/drakkan/sftpgo/workflows/CI/badge.svg?branch=main&event=push)](https://github.com/drakkan/sftpgo/workflows/CI/badge.svg?branch=main&event=push)
|
||||
[![Code Coverage](https://codecov.io/gh/drakkan/sftpgo/branch/main/graph/badge.svg)](https://codecov.io/gh/drakkan/sftpgo/branch/main)
|
||||
[![License: AGPL v3](https://img.shields.io/badge/License-AGPLv3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
|
||||
[![Docker Pulls](https://img.shields.io/docker/pulls/drakkan/sftpgo)](https://hub.docker.com/r/drakkan/sftpgo)
|
||||
|
|
4
go.mod
4
go.mod
|
@ -17,7 +17,7 @@ require (
|
|||
github.com/aws/aws-sdk-go-v2/service/s3 v1.26.11
|
||||
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.10
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.16.7
|
||||
github.com/cockroachdb/cockroach-go/v2 v2.2.12
|
||||
github.com/cockroachdb/cockroach-go/v2 v2.2.13
|
||||
github.com/coreos/go-oidc/v3 v3.2.0
|
||||
github.com/eikenb/pipeat v0.0.0-20210730190139-06b3e6902001
|
||||
github.com/fclairamb/ftpserverlib v0.18.1-0.20220515214847-f96d31ec626e
|
||||
|
@ -154,7 +154,7 @@ require (
|
|||
golang.org/x/tools v0.1.11 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac // indirect
|
||||
google.golang.org/genproto v0.0.0-20220614154056-d2c91c45c995 // indirect
|
||||
google.golang.org/grpc v1.47.0 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
gopkg.in/ini.v1 v1.66.6 // indirect
|
||||
|
|
8
go.sum
8
go.sum
|
@ -229,8 +229,8 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH
|
|||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/cockroachdb/cockroach-go/v2 v2.2.12 h1:yGneJ5OvdtAky2nD5BKTKmIqrcUlbrEIJ1ILHirnn3o=
|
||||
github.com/cockroachdb/cockroach-go/v2 v2.2.12/go.mod h1:xZ2VHjUEb/cySv0scXBx7YsBnHtLHkR1+w/w73b5i3M=
|
||||
github.com/cockroachdb/cockroach-go/v2 v2.2.13 h1:IsQmOtHQrfv0v3AqIEv+mStB09amzbH8gDDyVcpl3xQ=
|
||||
github.com/cockroachdb/cockroach-go/v2 v2.2.13/go.mod h1:xZ2VHjUEb/cySv0scXBx7YsBnHtLHkR1+w/w73b5i3M=
|
||||
github.com/coreos/go-oidc/v3 v3.2.0 h1:2eR2MGR7thBXSQ2YbODlF0fcmgtliLCfr9iX6RW11fc=
|
||||
github.com/coreos/go-oidc/v3 v3.2.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
|
@ -1202,8 +1202,8 @@ google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP
|
|||
google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
|
||||
google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
|
||||
google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8/go.mod h1:yKyY4AMRwFiC8yMMNaMi+RkCnjZJt9LoWuvhXjMs+To=
|
||||
google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac h1:ByeiW1F67iV9o8ipGskA+HWzSkMbRJuKLlwCdPxzn7A=
|
||||
google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
|
||||
google.golang.org/genproto v0.0.0-20220614154056-d2c91c45c995 h1:RJSqnopW/SLDXggSc2Psf704BMQ0Yz7AE6fjhQ62qYI=
|
||||
google.golang.org/genproto v0.0.0-20220614154056-d2c91c45c995/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
|
|
|
@ -6,13 +6,11 @@ import (
|
|||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/render"
|
||||
|
||||
"github.com/drakkan/sftpgo/v2/common"
|
||||
"github.com/drakkan/sftpgo/v2/dataprovider"
|
||||
"github.com/drakkan/sftpgo/v2/util"
|
||||
)
|
||||
|
||||
func getDefenderHosts(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -59,85 +57,6 @@ func deleteDefenderHostByID(w http.ResponseWriter, r *http.Request) {
|
|||
sendAPIResponse(w, r, nil, "OK", http.StatusOK)
|
||||
}
|
||||
|
||||
func getBanTime(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
ip := r.URL.Query().Get("ip")
|
||||
err := validateIPAddress(ip)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
banStatus := make(map[string]*string)
|
||||
|
||||
banTime, err := common.GetDefenderBanTime(ip)
|
||||
if err != nil {
|
||||
if _, ok := err.(*util.RecordNotFoundError); ok {
|
||||
banTime = nil
|
||||
} else {
|
||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
var banTimeString *string
|
||||
if banTime != nil {
|
||||
rfc3339String := banTime.UTC().Format(time.RFC3339)
|
||||
banTimeString = &rfc3339String
|
||||
}
|
||||
|
||||
banStatus["date_time"] = banTimeString
|
||||
render.JSON(w, r, banStatus)
|
||||
}
|
||||
|
||||
func getScore(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
ip := r.URL.Query().Get("ip")
|
||||
err := validateIPAddress(ip)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
score, err := common.GetDefenderScore(ip)
|
||||
if err != nil {
|
||||
if _, ok := err.(*util.RecordNotFoundError); ok {
|
||||
score = 0
|
||||
} else {
|
||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
scoreStatus := make(map[string]int)
|
||||
scoreStatus["score"] = score
|
||||
|
||||
render.JSON(w, r, scoreStatus)
|
||||
}
|
||||
|
||||
func unban(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
|
||||
var postBody map[string]string
|
||||
err := render.DecodeJSON(r.Body, &postBody)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
ip := postBody["ip"]
|
||||
err = validateIPAddress(ip)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if common.DeleteDefenderHost(ip) {
|
||||
sendAPIResponse(w, r, nil, "OK", http.StatusOK)
|
||||
} else {
|
||||
sendAPIResponse(w, r, nil, "Not found", http.StatusNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
func getIPFromID(r *http.Request) (string, error) {
|
||||
decoded, err := hex.DecodeString(getURLParam(r, "id"))
|
||||
if err != nil {
|
||||
|
@ -152,9 +71,6 @@ func getIPFromID(r *http.Request) (string, error) {
|
|||
}
|
||||
|
||||
func validateIPAddress(ip string) error {
|
||||
if ip == "" {
|
||||
return errors.New("ip address is required")
|
||||
}
|
||||
if net.ParseIP(ip) == nil {
|
||||
return fmt.Errorf("ip address %#v is not valid", ip)
|
||||
}
|
||||
|
|
|
@ -380,51 +380,6 @@ func getUserFilesAsZipStream(w http.ResponseWriter, r *http.Request) {
|
|||
renderCompressedFiles(w, connection, baseDir, filesList, nil)
|
||||
}
|
||||
|
||||
func getUserPublicKeys(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
claims, err := getTokenClaims(r)
|
||||
if err != nil || claims.Username == "" {
|
||||
sendAPIResponse(w, r, err, "Invalid token claims", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
user, err := dataprovider.UserExists(claims.Username)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, nil, "Unable to retrieve your user", getRespStatus(err))
|
||||
return
|
||||
}
|
||||
render.JSON(w, r, user.PublicKeys)
|
||||
}
|
||||
|
||||
func setUserPublicKeys(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
|
||||
claims, err := getTokenClaims(r)
|
||||
if err != nil || claims.Username == "" {
|
||||
sendAPIResponse(w, r, err, "Invalid token claims", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
user, err := dataprovider.UserExists(claims.Username)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, nil, "Unable to retrieve your user", getRespStatus(err))
|
||||
return
|
||||
}
|
||||
|
||||
var publicKeys []string
|
||||
err = render.DecodeJSON(r.Body, &publicKeys)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
user.PublicKeys = publicKeys
|
||||
err = dataprovider.UpdateUser(&user, dataprovider.ActionExecutorSelf, util.GetIPFromRemoteAddress(r.RemoteAddr))
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", getRespStatus(err))
|
||||
return
|
||||
}
|
||||
sendAPIResponse(w, r, err, "Public keys updated", http.StatusOK)
|
||||
}
|
||||
|
||||
func getUserProfile(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
claims, err := getTokenClaims(r)
|
||||
|
|
|
@ -49,22 +49,6 @@ func updateUserQuotaUsage(w http.ResponseWriter, r *http.Request) {
|
|||
doUpdateUserQuotaUsage(w, r, getURLParam(r, "username"), usage)
|
||||
}
|
||||
|
||||
func updateUserQuotaUsageCompat(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
var u dataprovider.User
|
||||
err := render.DecodeJSON(r.Body, &u)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
usage := quotaUsage{
|
||||
UsedQuotaSize: u.UsedQuotaSize,
|
||||
UsedQuotaFiles: u.UsedQuotaFiles,
|
||||
}
|
||||
|
||||
doUpdateUserQuotaUsage(w, r, u.Username, usage)
|
||||
}
|
||||
|
||||
func updateFolderQuotaUsage(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
var usage quotaUsage
|
||||
|
@ -76,53 +60,16 @@ func updateFolderQuotaUsage(w http.ResponseWriter, r *http.Request) {
|
|||
doUpdateFolderQuotaUsage(w, r, getURLParam(r, "name"), usage)
|
||||
}
|
||||
|
||||
func updateFolderQuotaUsageCompat(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
var f vfs.BaseVirtualFolder
|
||||
err := render.DecodeJSON(r.Body, &f)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
usage := quotaUsage{
|
||||
UsedQuotaSize: f.UsedQuotaSize,
|
||||
UsedQuotaFiles: f.UsedQuotaFiles,
|
||||
}
|
||||
doUpdateFolderQuotaUsage(w, r, f.Name, usage)
|
||||
}
|
||||
|
||||
func startUserQuotaScan(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
doStartUserQuotaScan(w, r, getURLParam(r, "username"))
|
||||
}
|
||||
|
||||
func startUserQuotaScanCompat(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
var u dataprovider.User
|
||||
err := render.DecodeJSON(r.Body, &u)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
doStartUserQuotaScan(w, r, u.Username)
|
||||
}
|
||||
|
||||
func startFolderQuotaScan(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
doStartFolderQuotaScan(w, r, getURLParam(r, "name"))
|
||||
}
|
||||
|
||||
func startFolderQuotaScanCompat(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
var f vfs.BaseVirtualFolder
|
||||
err := render.DecodeJSON(r.Body, &f)
|
||||
if err != nil {
|
||||
sendAPIResponse(w, r, err, "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
doStartFolderQuotaScan(w, r, f.Name)
|
||||
}
|
||||
|
||||
func updateUserTransferQuotaUsage(w http.ResponseWriter, r *http.Request) {
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
||||
var usage transferQuotaUsage
|
||||
|
|
|
@ -37,8 +37,6 @@ const (
|
|||
userLogoutPath = "/api/v2/user/logout"
|
||||
activeConnectionsPath = "/api/v2/connections"
|
||||
quotasBasePath = "/api/v2/quotas"
|
||||
quotaScanPath = "/api/v2/quota-scans"
|
||||
quotaScanVFolderPath = "/api/v2/folder-quota-scans"
|
||||
userPath = "/api/v2/users"
|
||||
versionPath = "/api/v2/version"
|
||||
folderPath = "/api/v2/folders"
|
||||
|
@ -46,21 +44,12 @@ const (
|
|||
serverStatusPath = "/api/v2/status"
|
||||
dumpDataPath = "/api/v2/dumpdata"
|
||||
loadDataPath = "/api/v2/loaddata"
|
||||
updateUsedQuotaPath = "/api/v2/quota-update"
|
||||
updateFolderUsedQuotaPath = "/api/v2/folder-quota-update"
|
||||
defenderHosts = "/api/v2/defender/hosts"
|
||||
defenderBanTime = "/api/v2/defender/bantime"
|
||||
defenderUnban = "/api/v2/defender/unban"
|
||||
defenderScore = "/api/v2/defender/score"
|
||||
adminPath = "/api/v2/admins"
|
||||
adminPwdPath = "/api/v2/admin/changepwd"
|
||||
adminPwdCompatPath = "/api/v2/changepwd/admin"
|
||||
adminProfilePath = "/api/v2/admin/profile"
|
||||
userPwdPath = "/api/v2/user/changepwd"
|
||||
userPublicKeysPath = "/api/v2/user/publickeys"
|
||||
userFolderPath = "/api/v2/user/folder"
|
||||
userDirsPath = "/api/v2/user/dirs"
|
||||
userFilePath = "/api/v2/user/file"
|
||||
userFilesPath = "/api/v2/user/files"
|
||||
userStreamZipPath = "/api/v2/user/streamzip"
|
||||
userUploadFilePath = "/api/v2/user/files/upload"
|
||||
|
|
|
@ -81,18 +81,10 @@ const (
|
|||
quotasBasePath = "/api/v2/quotas"
|
||||
quotaScanPath = "/api/v2/quotas/users/scans"
|
||||
quotaScanVFolderPath = "/api/v2/quotas/folders/scans"
|
||||
quotaScanCompatPath = "/api/v2/quota-scans"
|
||||
quotaScanVFolderCompatPath = "/api/v2/folder-quota-scans"
|
||||
updateUsedQuotaCompatPath = "/api/v2/quota-update"
|
||||
updateFolderUsedQuotaCompatPath = "/api/v2/folder-quota-update"
|
||||
defenderHosts = "/api/v2/defender/hosts"
|
||||
defenderBanTime = "/api/v2/defender/bantime"
|
||||
defenderUnban = "/api/v2/defender/unban"
|
||||
defenderScore = "/api/v2/defender/score"
|
||||
versionPath = "/api/v2/version"
|
||||
logoutPath = "/api/v2/logout"
|
||||
userPwdPath = "/api/v2/user/changepwd"
|
||||
userPublicKeysPath = "/api/v2/user/publickeys"
|
||||
userDirsPath = "/api/v2/user/dirs"
|
||||
userFilesPath = "/api/v2/user/files"
|
||||
userStreamZipPath = "/api/v2/user/streamzip"
|
||||
|
@ -1393,24 +1385,6 @@ func TestHTTPUserAuthentication(t *testing.T) {
|
|||
err = resp.Body.Close()
|
||||
assert.NoError(t, err)
|
||||
|
||||
req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("%v%v", httpBaseURL, userPublicKeysPath), nil)
|
||||
assert.NoError(t, err)
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", userToken))
|
||||
resp, err = httpclient.GetHTTPClient().Do(req)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
err = resp.Body.Close()
|
||||
assert.NoError(t, err)
|
||||
// using the admin token should not work
|
||||
req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("%v%v", httpBaseURL, userPublicKeysPath), nil)
|
||||
assert.NoError(t, err)
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", adminToken))
|
||||
resp, err = httpclient.GetHTTPClient().Do(req)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
||||
err = resp.Body.Close()
|
||||
assert.NoError(t, err)
|
||||
|
||||
req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("%v%v", httpBaseURL, userLogoutPath), nil)
|
||||
assert.NoError(t, err)
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", adminToken))
|
||||
|
@ -1429,15 +1403,6 @@ func TestHTTPUserAuthentication(t *testing.T) {
|
|||
err = resp.Body.Close()
|
||||
assert.NoError(t, err)
|
||||
|
||||
req, err = http.NewRequest(http.MethodGet, fmt.Sprintf("%v%v", httpBaseURL, userPublicKeysPath), nil)
|
||||
assert.NoError(t, err)
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", userToken))
|
||||
resp, err = httpclient.GetHTTPClient().Do(req)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
||||
err = resp.Body.Close()
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = httpdtest.RemoveUser(user, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
err = os.RemoveAll(user.GetHomeDir())
|
||||
|
@ -5191,35 +5156,14 @@ func TestDefenderAPI(t *testing.T) {
|
|||
|
||||
ip := "::1"
|
||||
|
||||
response, _, err := httpdtest.GetBanTime(ip, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
banTime, ok := response["date_time"]
|
||||
assert.True(t, ok)
|
||||
assert.Nil(t, banTime)
|
||||
|
||||
hosts, _, err := httpdtest.GetDefenderHosts(http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, hosts, 0)
|
||||
|
||||
response, _, err = httpdtest.GetScore(ip, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
score, ok := response["score"]
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, float64(0), score)
|
||||
|
||||
err = httpdtest.UnbanIP(ip, http.StatusNotFound)
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = httpdtest.RemoveDefenderHostByIP(ip, http.StatusNotFound)
|
||||
assert.NoError(t, err)
|
||||
|
||||
common.AddDefenderEvent(ip, common.HostEventNoLoginTried)
|
||||
response, _, err = httpdtest.GetScore(ip, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
score, ok = response["score"]
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, float64(2), score)
|
||||
|
||||
hosts, _, err = httpdtest.GetDefenderHosts(http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
if assert.Len(t, hosts, 1) {
|
||||
|
@ -5234,11 +5178,6 @@ func TestDefenderAPI(t *testing.T) {
|
|||
assert.Equal(t, 2, host.Score)
|
||||
|
||||
common.AddDefenderEvent(ip, common.HostEventNoLoginTried)
|
||||
response, _, err = httpdtest.GetBanTime(ip, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
banTime, ok = response["date_time"]
|
||||
assert.True(t, ok)
|
||||
assert.NotNil(t, banTime)
|
||||
hosts, _, err = httpdtest.GetDefenderHosts(http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
if assert.Len(t, hosts, 1) {
|
||||
|
@ -5252,13 +5191,10 @@ func TestDefenderAPI(t *testing.T) {
|
|||
assert.NotEmpty(t, host.GetBanTime())
|
||||
assert.Equal(t, 0, host.Score)
|
||||
|
||||
err = httpdtest.UnbanIP(ip, http.StatusOK)
|
||||
_, err = httpdtest.RemoveDefenderHostByIP(ip, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = httpdtest.UnbanIP(ip, http.StatusNotFound)
|
||||
assert.NoError(t, err)
|
||||
|
||||
host, _, err = httpdtest.GetDefenderHostByIP(ip, http.StatusNotFound)
|
||||
_, _, err = httpdtest.GetDefenderHostByIP(ip, http.StatusNotFound)
|
||||
assert.NoError(t, err)
|
||||
|
||||
common.AddDefenderEvent(ip, common.HostEventNoLoginTried)
|
||||
|
@ -5290,17 +5226,6 @@ func TestDefenderAPI(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDefenderAPIErrors(t *testing.T) {
|
||||
_, _, err := httpdtest.GetBanTime("", http.StatusBadRequest)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, err = httpdtest.GetBanTime("invalid", http.StatusBadRequest)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, err = httpdtest.GetScore("", http.StatusBadRequest)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = httpdtest.UnbanIP("", http.StatusBadRequest)
|
||||
require.NoError(t, err)
|
||||
if isDbDefenderSupported() {
|
||||
oldConfig := config.GetCommonConfig()
|
||||
|
||||
|
@ -5316,26 +5241,12 @@ func TestDefenderAPIErrors(t *testing.T) {
|
|||
err = dataprovider.Close()
|
||||
assert.NoError(t, err)
|
||||
|
||||
ip := "127.1.1.2"
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, defenderHosts, nil)
|
||||
assert.NoError(t, err)
|
||||
setBearerForReq(req, token)
|
||||
rr := executeRequest(req)
|
||||
checkResponseCode(t, http.StatusInternalServerError, rr)
|
||||
|
||||
req, err = http.NewRequest(http.MethodGet, defenderBanTime+"?ip="+ip, nil)
|
||||
assert.NoError(t, err)
|
||||
setBearerForReq(req, token)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusInternalServerError, rr)
|
||||
|
||||
req, err = http.NewRequest(http.MethodGet, defenderScore+"?ip="+ip, nil)
|
||||
assert.NoError(t, err)
|
||||
setBearerForReq(req, token)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusInternalServerError, rr)
|
||||
|
||||
err = config.LoadConfig(configDir, "")
|
||||
assert.NoError(t, err)
|
||||
providerConf := config.GetProviderConf()
|
||||
|
@ -5999,15 +5910,6 @@ func TestUpdateFolderInvalidJsonMock(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestUnbanInvalidJsonMock(t *testing.T) {
|
||||
token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
|
||||
assert.NoError(t, err)
|
||||
req, _ := http.NewRequest(http.MethodPost, defenderUnban, bytes.NewBuffer([]byte("invalid json")))
|
||||
setBearerForReq(req, token)
|
||||
rr := executeRequest(req)
|
||||
checkResponseCode(t, http.StatusBadRequest, rr)
|
||||
}
|
||||
|
||||
func TestAddUserInvalidJsonMock(t *testing.T) {
|
||||
token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
|
||||
assert.NoError(t, err)
|
||||
|
@ -8343,10 +8245,6 @@ func TestUpdateUserQuotaUsageMock(t *testing.T) {
|
|||
setBearerForReq(req, token)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusOK, rr)
|
||||
req, _ = http.NewRequest(http.MethodPut, updateUsedQuotaCompatPath, bytes.NewBuffer(userAsJSON))
|
||||
setBearerForReq(req, token)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusOK, rr)
|
||||
req, _ = http.NewRequest(http.MethodGet, path.Join(userPath, user.Username), nil)
|
||||
setBearerForReq(req, token)
|
||||
rr = executeRequest(req)
|
||||
|
@ -8386,10 +8284,6 @@ func TestUpdateUserQuotaUsageMock(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Equal(t, usedQuotaFiles*2, user.UsedQuotaFiles)
|
||||
assert.Equal(t, usedQuotaSize*2, user.UsedQuotaSize)
|
||||
req, _ = http.NewRequest(http.MethodPut, updateUsedQuotaCompatPath, bytes.NewBuffer([]byte("string")))
|
||||
setBearerForReq(req, token)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusBadRequest, rr)
|
||||
req, _ = http.NewRequest(http.MethodPut, path.Join(quotasBasePath, "users", u.Username, "usage"), bytes.NewBuffer([]byte("string")))
|
||||
setBearerForReq(req, token)
|
||||
rr = executeRequest(req)
|
||||
|
@ -8704,15 +8598,6 @@ func TestStartQuotaScanMock(t *testing.T) {
|
|||
|
||||
waitForUsersQuotaScan(t, token)
|
||||
|
||||
asJSON, err := json.Marshal(user)
|
||||
assert.NoError(t, err)
|
||||
req, _ = http.NewRequest(http.MethodPost, quotaScanCompatPath, bytes.NewBuffer(asJSON))
|
||||
setBearerForReq(req, token)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusAccepted, rr)
|
||||
|
||||
waitForUsersQuotaScan(t, token)
|
||||
|
||||
req, _ = http.NewRequest(http.MethodDelete, path.Join(userPath, user.Username), nil)
|
||||
setBearerForReq(req, token)
|
||||
rr = executeRequest(req)
|
||||
|
@ -8747,10 +8632,6 @@ func TestUpdateFolderQuotaUsageMock(t *testing.T) {
|
|||
setBearerForReq(req, token)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusOK, rr)
|
||||
req, _ = http.NewRequest(http.MethodPut, updateFolderUsedQuotaCompatPath, bytes.NewBuffer(folderAsJSON))
|
||||
setBearerForReq(req, token)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusOK, rr)
|
||||
var folderGet vfs.BaseVirtualFolder
|
||||
req, _ = http.NewRequest(http.MethodGet, path.Join(folderPath, folderName), nil)
|
||||
setBearerForReq(req, token)
|
||||
|
@ -8797,10 +8678,6 @@ func TestUpdateFolderQuotaUsageMock(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Equal(t, usedQuotaFiles*2, folderGet.UsedQuotaFiles)
|
||||
assert.Equal(t, usedQuotaSize*2, folderGet.UsedQuotaSize)
|
||||
req, _ = http.NewRequest(http.MethodPut, updateFolderUsedQuotaCompatPath, bytes.NewBuffer([]byte("string")))
|
||||
setBearerForReq(req, token)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusBadRequest, rr)
|
||||
req, _ = http.NewRequest(http.MethodPut, path.Join(quotasBasePath, "folders", folder.Name, "usage"),
|
||||
bytes.NewBuffer([]byte("not a json")))
|
||||
setBearerForReq(req, token)
|
||||
|
@ -8859,17 +8736,7 @@ func TestStartFolderQuotaScanMock(t *testing.T) {
|
|||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusAccepted, rr)
|
||||
waitForFoldersQuotaScanPath(t, token)
|
||||
|
||||
asJSON, err := json.Marshal(folder)
|
||||
assert.NoError(t, err)
|
||||
req, _ = http.NewRequest(http.MethodPost, quotaScanVFolderCompatPath, bytes.NewBuffer(asJSON))
|
||||
setBearerForReq(req, token)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusAccepted, rr)
|
||||
waitForFoldersQuotaScanPath(t, token)
|
||||
|
||||
// cleanup
|
||||
|
||||
req, _ = http.NewRequest(http.MethodDelete, path.Join(folderPath, folderName), nil)
|
||||
setBearerForReq(req, token)
|
||||
rr = executeRequest(req)
|
||||
|
@ -8891,24 +8758,6 @@ func TestStartQuotaScanNonExistentUserMock(t *testing.T) {
|
|||
checkResponseCode(t, http.StatusNotFound, rr)
|
||||
}
|
||||
|
||||
func TestStartQuotaScanBadUserMock(t *testing.T) {
|
||||
token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
|
||||
assert.NoError(t, err)
|
||||
req, _ := http.NewRequest(http.MethodPost, quotaScanCompatPath, bytes.NewBuffer([]byte("invalid json")))
|
||||
setBearerForReq(req, token)
|
||||
rr := executeRequest(req)
|
||||
checkResponseCode(t, http.StatusBadRequest, rr)
|
||||
}
|
||||
|
||||
func TestStartQuotaScanBadFolderMock(t *testing.T) {
|
||||
token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
|
||||
assert.NoError(t, err)
|
||||
req, _ := http.NewRequest(http.MethodPost, quotaScanVFolderCompatPath, bytes.NewBuffer([]byte("invalid json")))
|
||||
setBearerForReq(req, token)
|
||||
rr := executeRequest(req)
|
||||
checkResponseCode(t, http.StatusBadRequest, rr)
|
||||
}
|
||||
|
||||
func TestStartQuotaScanNonExistentFolderMock(t *testing.T) {
|
||||
token, err := getJWTAPITokenFromTestServer(defaultTokenAuthUser, defaultTokenAuthPass)
|
||||
assert.NoError(t, err)
|
||||
|
@ -9327,18 +9176,6 @@ func TestWebClientLoginMock(t *testing.T) {
|
|||
checkResponseCode(t, http.StatusNotFound, rr)
|
||||
assert.Contains(t, rr.Body.String(), "Unable to retrieve your user")
|
||||
|
||||
req, _ = http.NewRequest(http.MethodGet, userPublicKeysPath, nil)
|
||||
setBearerForReq(req, apiUserToken)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusNotFound, rr)
|
||||
assert.Contains(t, rr.Body.String(), "Unable to retrieve your user")
|
||||
|
||||
req, _ = http.NewRequest(http.MethodPut, userPublicKeysPath, bytes.NewBuffer([]byte(`{}`)))
|
||||
setBearerForReq(req, apiUserToken)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusNotFound, rr)
|
||||
assert.Contains(t, rr.Body.String(), "Unable to retrieve your user")
|
||||
|
||||
csrfToken, err := getCSRFToken(httpBaseURL + webClientLoginPath)
|
||||
assert.NoError(t, err)
|
||||
form := make(url.Values)
|
||||
|
@ -9872,75 +9709,6 @@ func TestWebClientChangePwd(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestWebAPIPublicKeys(t *testing.T) {
|
||||
user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
apiToken, err := getJWTAPIUserTokenFromTestServer(defaultUsername, defaultPassword)
|
||||
assert.NoError(t, err)
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, userPublicKeysPath, nil)
|
||||
assert.NoError(t, err)
|
||||
setBearerForReq(req, apiToken)
|
||||
rr := executeRequest(req)
|
||||
checkResponseCode(t, http.StatusOK, rr)
|
||||
var keys []string
|
||||
err = json.Unmarshal(rr.Body.Bytes(), &keys)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, keys, 0)
|
||||
|
||||
keys = []string{testPubKey, testPubKey1}
|
||||
asJSON, err := json.Marshal(keys)
|
||||
assert.NoError(t, err)
|
||||
req, err = http.NewRequest(http.MethodPut, userPublicKeysPath, bytes.NewBuffer(asJSON))
|
||||
assert.NoError(t, err)
|
||||
setBearerForReq(req, apiToken)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusOK, rr)
|
||||
|
||||
req, err = http.NewRequest(http.MethodGet, userPublicKeysPath, nil)
|
||||
assert.NoError(t, err)
|
||||
setBearerForReq(req, apiToken)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusOK, rr)
|
||||
keys = nil
|
||||
err = json.Unmarshal(rr.Body.Bytes(), &keys)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, keys, 2)
|
||||
|
||||
req, err = http.NewRequest(http.MethodPut, userPublicKeysPath, bytes.NewBuffer([]byte(`invalid json`)))
|
||||
assert.NoError(t, err)
|
||||
setBearerForReq(req, apiToken)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusBadRequest, rr)
|
||||
|
||||
keys = []string{`not a public key`}
|
||||
asJSON, err = json.Marshal(keys)
|
||||
assert.NoError(t, err)
|
||||
req, err = http.NewRequest(http.MethodPut, userPublicKeysPath, bytes.NewBuffer(asJSON))
|
||||
assert.NoError(t, err)
|
||||
setBearerForReq(req, apiToken)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusBadRequest, rr)
|
||||
assert.Contains(t, rr.Body.String(), "could not parse key")
|
||||
|
||||
user.Filters.WebClient = append(user.Filters.WebClient, sdk.WebClientPubKeyChangeDisabled)
|
||||
_, _, err = httpdtest.UpdateUser(user, http.StatusOK, "")
|
||||
assert.NoError(t, err)
|
||||
|
||||
apiToken, err = getJWTAPIUserTokenFromTestServer(defaultUsername, defaultPassword)
|
||||
assert.NoError(t, err)
|
||||
req, err = http.NewRequest(http.MethodGet, userPublicKeysPath, nil)
|
||||
assert.NoError(t, err)
|
||||
setBearerForReq(req, apiToken)
|
||||
rr = executeRequest(req)
|
||||
checkResponseCode(t, http.StatusForbidden, rr)
|
||||
|
||||
_, err = httpdtest.RemoveUser(user, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
err = os.RemoveAll(user.GetHomeDir())
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestPreDownloadHook(t *testing.T) {
|
||||
if runtime.GOOS == osWindows {
|
||||
t.Skip("this test is not available on Windows")
|
||||
|
|
|
@ -461,16 +461,6 @@ func TestInvalidToken(t *testing.T) {
|
|||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
assert.Contains(t, rr.Body.String(), "Invalid token claims")
|
||||
|
||||
rr = httptest.NewRecorder()
|
||||
getUserPublicKeys(rr, req)
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
assert.Contains(t, rr.Body.String(), "Invalid token claims")
|
||||
|
||||
rr = httptest.NewRecorder()
|
||||
setUserPublicKeys(rr, req)
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
assert.Contains(t, rr.Body.String(), "Invalid token claims")
|
||||
|
||||
rr = httptest.NewRecorder()
|
||||
generateTOTPSecret(rr, req)
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
|
@ -1079,8 +1069,8 @@ func TestJWTTokenValidation(t *testing.T) {
|
|||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
|
||||
rr = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest(http.MethodPost, userPublicKeysPath, nil)
|
||||
req.RequestURI = userPublicKeysPath
|
||||
req, _ = http.NewRequest(http.MethodPost, userProfilePath, nil)
|
||||
req.RequestURI = userProfilePath
|
||||
ctx = jwtauth.NewContext(req.Context(), token, errTest)
|
||||
fn.ServeHTTP(rr, req.WithContext(ctx))
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
|
|
|
@ -1179,8 +1179,6 @@ func (s *httpdServer) initializeRouter() {
|
|||
router.With(forbidAPIKeyAuthentication).Get(adminProfilePath, getAdminProfile)
|
||||
router.With(forbidAPIKeyAuthentication).Put(adminProfilePath, updateAdminProfile)
|
||||
router.With(forbidAPIKeyAuthentication).Put(adminPwdPath, changeAdminPassword)
|
||||
// compatibility layer to remove in v2.2
|
||||
router.With(forbidAPIKeyAuthentication).Put(adminPwdCompatPath, changeAdminPassword)
|
||||
// admin TOTP APIs
|
||||
router.With(forbidAPIKeyAuthentication).Get(adminTOTPConfigsPath, getTOTPConfigs)
|
||||
router.With(forbidAPIKeyAuthentication).Post(adminTOTPGeneratePath, generateTOTPSecret)
|
||||
|
@ -1203,13 +1201,9 @@ func (s *httpdServer) initializeRouter() {
|
|||
|
||||
router.With(s.checkPerm(dataprovider.PermAdminCloseConnections)).
|
||||
Delete(activeConnectionsPath+"/{connectionID}", handleCloseConnection)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminQuotaScans)).Get(quotaScanPath, getUsersQuotaScans)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminQuotaScans)).Get(quotasBasePath+"/users/scans", getUsersQuotaScans)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminQuotaScans)).Post(quotaScanPath, startUserQuotaScanCompat)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminQuotaScans)).Post(quotasBasePath+"/users/{username}/scan", startUserQuotaScan)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminQuotaScans)).Get(quotaScanVFolderPath, getFoldersQuotaScans)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminQuotaScans)).Get(quotasBasePath+"/folders/scans", getFoldersQuotaScans)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminQuotaScans)).Post(quotaScanVFolderPath, startFolderQuotaScanCompat)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminQuotaScans)).Post(quotasBasePath+"/folders/{name}/scan", startFolderQuotaScan)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminViewUsers)).Get(userPath, getUsers)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminAddUsers)).Post(userPath, addUser)
|
||||
|
@ -1230,20 +1224,15 @@ func (s *httpdServer) initializeRouter() {
|
|||
router.With(s.checkPerm(dataprovider.PermAdminManageSystem)).Get(dumpDataPath, dumpData)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageSystem)).Get(loadDataPath, loadData)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageSystem)).Post(loadDataPath, loadDataFromRequest)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminChangeUsers)).Put(updateUsedQuotaPath, updateUserQuotaUsageCompat)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminChangeUsers)).Put(quotasBasePath+"/users/{username}/usage",
|
||||
updateUserQuotaUsage)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminChangeUsers)).Put(quotasBasePath+"/users/{username}/transfer-usage",
|
||||
updateUserTransferQuotaUsage)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminChangeUsers)).Put(updateFolderUsedQuotaPath, updateFolderQuotaUsageCompat)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminChangeUsers)).Put(quotasBasePath+"/folders/{name}/usage",
|
||||
updateFolderQuotaUsage)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminViewDefender)).Get(defenderHosts, getDefenderHosts)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminViewDefender)).Get(defenderHosts+"/{id}", getDefenderHostByID)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageDefender)).Delete(defenderHosts+"/{id}", deleteDefenderHostByID)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminViewDefender)).Get(defenderBanTime, getBanTime)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminViewDefender)).Get(defenderScore, getScore)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageDefender)).Post(defenderUnban, unban)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageAdmins)).Get(adminPath, getAdmins)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageAdmins)).Post(adminPath, addAdmin)
|
||||
router.With(s.checkPerm(dataprovider.PermAdminManageAdmins)).Get(adminPath+"/{username}", getAdminByUsername)
|
||||
|
@ -1282,10 +1271,6 @@ func (s *httpdServer) initializeRouter() {
|
|||
router.With(forbidAPIKeyAuthentication).Get(userLogoutPath, s.logout)
|
||||
router.With(forbidAPIKeyAuthentication, s.checkSecondFactorRequirement,
|
||||
s.checkHTTPUserPerm(sdk.WebClientPasswordChangeDisabled)).Put(userPwdPath, changeUserPassword)
|
||||
router.With(forbidAPIKeyAuthentication, s.checkSecondFactorRequirement,
|
||||
s.checkHTTPUserPerm(sdk.WebClientPubKeyChangeDisabled)).Get(userPublicKeysPath, getUserPublicKeys)
|
||||
router.With(forbidAPIKeyAuthentication, s.checkSecondFactorRequirement,
|
||||
s.checkHTTPUserPerm(sdk.WebClientPubKeyChangeDisabled)).Put(userPublicKeysPath, setUserPublicKeys)
|
||||
router.With(forbidAPIKeyAuthentication).Get(userProfilePath, getUserProfile)
|
||||
router.With(forbidAPIKeyAuthentication, s.checkSecondFactorRequirement).Put(userProfilePath, updateUserProfile)
|
||||
// user TOTP APIs
|
||||
|
@ -1302,10 +1287,6 @@ func (s *httpdServer) initializeRouter() {
|
|||
router.With(forbidAPIKeyAuthentication, s.checkHTTPUserPerm(sdk.WebClientMFADisabled)).
|
||||
Post(user2FARecoveryCodesPath, generateRecoveryCodes)
|
||||
|
||||
// compatibility layer to remove in v2.3
|
||||
router.With(s.checkSecondFactorRequirement, compressor.Handler).Get(userFolderPath, readUserFolder)
|
||||
router.With(s.checkSecondFactorRequirement).Get(userFilePath, getUserFile)
|
||||
|
||||
router.With(s.checkSecondFactorRequirement, compressor.Handler).Get(userDirsPath, readUserFolder)
|
||||
router.With(s.checkSecondFactorRequirement, s.checkHTTPUserPerm(sdk.WebClientWriteDisabled)).
|
||||
Post(userDirsPath, createUserDir)
|
||||
|
|
|
@ -41,9 +41,6 @@ const (
|
|||
dumpDataPath = "/api/v2/dumpdata"
|
||||
loadDataPath = "/api/v2/loaddata"
|
||||
defenderHosts = "/api/v2/defender/hosts"
|
||||
defenderBanTime = "/api/v2/defender/bantime"
|
||||
defenderUnban = "/api/v2/defender/unban"
|
||||
defenderScore = "/api/v2/defender/score"
|
||||
adminPath = "/api/v2/admins"
|
||||
adminPwdPath = "/api/v2/admin/changepwd"
|
||||
apiKeysPath = "/api/v2/apikeys"
|
||||
|
@ -984,70 +981,6 @@ func RemoveDefenderHostByIP(ip string, expectedStatusCode int) ([]byte, error) {
|
|||
return body, checkResponse(resp.StatusCode, expectedStatusCode)
|
||||
}
|
||||
|
||||
// GetBanTime returns the ban time for the given IP address
|
||||
func GetBanTime(ip string, expectedStatusCode int) (map[string]any, []byte, error) {
|
||||
var response map[string]any
|
||||
var body []byte
|
||||
url, err := url.Parse(buildURLRelativeToBase(defenderBanTime))
|
||||
if err != nil {
|
||||
return response, body, err
|
||||
}
|
||||
q := url.Query()
|
||||
q.Add("ip", ip)
|
||||
url.RawQuery = q.Encode()
|
||||
resp, err := sendHTTPRequest(http.MethodGet, url.String(), nil, "", getDefaultToken())
|
||||
if err != nil {
|
||||
return response, body, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
err = checkResponse(resp.StatusCode, expectedStatusCode)
|
||||
if err == nil && expectedStatusCode == http.StatusOK {
|
||||
err = render.DecodeJSON(resp.Body, &response)
|
||||
} else {
|
||||
body, _ = getResponseBody(resp)
|
||||
}
|
||||
return response, body, err
|
||||
}
|
||||
|
||||
// GetScore returns the score for the given IP address
|
||||
func GetScore(ip string, expectedStatusCode int) (map[string]any, []byte, error) {
|
||||
var response map[string]any
|
||||
var body []byte
|
||||
url, err := url.Parse(buildURLRelativeToBase(defenderScore))
|
||||
if err != nil {
|
||||
return response, body, err
|
||||
}
|
||||
q := url.Query()
|
||||
q.Add("ip", ip)
|
||||
url.RawQuery = q.Encode()
|
||||
resp, err := sendHTTPRequest(http.MethodGet, url.String(), nil, "", getDefaultToken())
|
||||
if err != nil {
|
||||
return response, body, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
err = checkResponse(resp.StatusCode, expectedStatusCode)
|
||||
if err == nil && expectedStatusCode == http.StatusOK {
|
||||
err = render.DecodeJSON(resp.Body, &response)
|
||||
} else {
|
||||
body, _ = getResponseBody(resp)
|
||||
}
|
||||
return response, body, err
|
||||
}
|
||||
|
||||
// UnbanIP unbans the given IP address
|
||||
func UnbanIP(ip string, expectedStatusCode int) error {
|
||||
postBody := make(map[string]string)
|
||||
postBody["ip"] = ip
|
||||
asJSON, _ := json.Marshal(postBody)
|
||||
resp, err := sendHTTPRequest(http.MethodPost, buildURLRelativeToBase(defenderUnban), bytes.NewBuffer(asJSON),
|
||||
"", getDefaultToken())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
return checkResponse(resp.StatusCode, expectedStatusCode)
|
||||
}
|
||||
|
||||
// Dumpdata requests a backup to outputFile.
|
||||
// outputFile is relative to the configured backups_path
|
||||
func Dumpdata(outputFile, outputData, indent string, expectedStatusCode int) (map[string]any, []byte, error) {
|
||||
|
|
|
@ -439,37 +439,6 @@ paths:
|
|||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/changepwd/admin:
|
||||
put:
|
||||
security:
|
||||
- BearerAuth: []
|
||||
tags:
|
||||
- admins
|
||||
summary: Change admin password
|
||||
description: Changes the password for the logged in admin. Please use '/admin/changepwd' instead
|
||||
operationId: change_admin_password_deprecated
|
||||
deprecated: true
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PwdChange'
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/admin/changepwd:
|
||||
put:
|
||||
security:
|
||||
|
@ -896,107 +865,6 @@ paths:
|
|||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/defender/bantime:
|
||||
get:
|
||||
deprecated: true
|
||||
tags:
|
||||
- defender
|
||||
summary: Get ban time
|
||||
description: Deprecated, please use '/defender/hosts', '/defender/hosts/{id}' instead
|
||||
operationId: get_ban_time
|
||||
parameters:
|
||||
- in: query
|
||||
name: ip
|
||||
required: true
|
||||
description: IPv4/IPv6 address
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/BanStatus'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/defender/unban:
|
||||
post:
|
||||
deprecated: true
|
||||
tags:
|
||||
- defender
|
||||
summary: Unban
|
||||
description: Deprecated, please use '/defender/hosts/{id}' instead
|
||||
operationId: unban_host
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
ip:
|
||||
type: string
|
||||
description: IPv4/IPv6 address to remove
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/defender/score:
|
||||
get:
|
||||
deprecated: true
|
||||
tags:
|
||||
- defender
|
||||
summary: Get score
|
||||
description: Deprecated, please use '/defender/hosts', '/defender/hosts/{id}' instead
|
||||
operationId: get_score
|
||||
parameters:
|
||||
- in: query
|
||||
name: ip
|
||||
required: true
|
||||
description: IPv4/IPv6 address
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ScoreStatus'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/metadata/users/checks:
|
||||
get:
|
||||
tags:
|
||||
|
@ -1447,230 +1315,6 @@ paths:
|
|||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/quota-scans:
|
||||
get:
|
||||
deprecated: true
|
||||
tags:
|
||||
- quota
|
||||
summary: Get quota scans
|
||||
description: Deprecated, please use '/quotas/users/scans' instead
|
||||
operationId: get_users_quota_scans_deprecated
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/QuotaScan'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
post:
|
||||
deprecated: true
|
||||
tags:
|
||||
- quota
|
||||
summary: Start user quota scan
|
||||
description: Deprecated, please use '/quotas/users/{username}/scan' instead
|
||||
operationId: start_user_quota_scan_deprecated
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/User'
|
||||
responses:
|
||||
'202':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiResponse'
|
||||
example:
|
||||
message: Scan started
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'409':
|
||||
$ref: '#/components/responses/Conflict'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/quota-update:
|
||||
put:
|
||||
deprecated: true
|
||||
tags:
|
||||
- quota
|
||||
summary: Update quota usage limits
|
||||
description: Deprecated, please use '/quotas/users/{username}/usage' instead
|
||||
operationId: user_quota_update_usage_deprecated
|
||||
parameters:
|
||||
- in: query
|
||||
name: mode
|
||||
required: false
|
||||
description: the update mode specifies if the given quota usage values should be added or replace the current ones
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- add
|
||||
- reset
|
||||
description: |
|
||||
Update type:
|
||||
* `add` - add the specified quota limits to the current used ones
|
||||
* `reset` - reset the values to the specified ones. This is the default
|
||||
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, this means that if mode is "add" the current value will remain unchanged, if mode is "reset" the missing field is set to 0'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/User'
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiResponse'
|
||||
example:
|
||||
message: Quota updated
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/folder-quota-update:
|
||||
put:
|
||||
deprecated: true
|
||||
tags:
|
||||
- quota
|
||||
summary: Update folder quota limits
|
||||
description: Deprecated, please use '/quotas/folders/{name}/usage' instead
|
||||
operationId: folder_quota_update_usage_deprecated
|
||||
parameters:
|
||||
- in: query
|
||||
name: mode
|
||||
required: false
|
||||
description: the update mode specifies if the given quota usage values should be added or replace the current ones
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- add
|
||||
- reset
|
||||
description: |
|
||||
Update type:
|
||||
* `add` - add the specified quota limits to the current used ones
|
||||
* `reset` - reset the values to the specified ones. This is the default
|
||||
example: reset
|
||||
requestBody:
|
||||
required: true
|
||||
description: 'The only folder mandatory fields are mapped_path,used_quota_size and used_quota_files. Please note that if the used quota fields are missing they will default to 0, this means that if mode is "add" the current value will remain unchanged, if mode is "reset" the missing field is set to 0'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/BaseVirtualFolder'
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiResponse'
|
||||
example:
|
||||
message: Quota updated
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/folder-quota-scans:
|
||||
get:
|
||||
deprecated: true
|
||||
tags:
|
||||
- quota
|
||||
summary: Get folders quota scans
|
||||
description: Deprecated, please use '/quotas/folders/scans' instead
|
||||
operationId: get_folders_quota_scans_deprecated
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/FolderQuotaScan'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
post:
|
||||
deprecated: true
|
||||
tags:
|
||||
- quota
|
||||
summary: Start a folder quota scan
|
||||
description: Deprecated, please use '/quotas/folders/{name}/scan' instead
|
||||
operationId: start_folder_quota_scan_deprecated
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/BaseVirtualFolder'
|
||||
responses:
|
||||
'202':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiResponse'
|
||||
example:
|
||||
message: Scan started
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'409':
|
||||
$ref: '#/components/responses/Conflict'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/folders:
|
||||
get:
|
||||
tags:
|
||||
|
@ -3291,71 +2935,6 @@ paths:
|
|||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/user/publickeys:
|
||||
get:
|
||||
security:
|
||||
- BearerAuth: []
|
||||
tags:
|
||||
- user APIs
|
||||
deprecated: true
|
||||
summary: Get the user's public keys
|
||||
description: 'Returns the public keys for the logged in user. Deprecated please use "/user/profile" instead'
|
||||
operationId: get_user_public_keys
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
put:
|
||||
security:
|
||||
- BearerAuth: []
|
||||
tags:
|
||||
- user APIs
|
||||
deprecated: true
|
||||
summary: Set the user's public keys
|
||||
description: 'Sets the public keys for the logged in user. Public keys must be in OpenSSH format. Deprecated please use "/user/profile" instead'
|
||||
operationId: set_user_public_keys
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Public key in OpenSSH format
|
||||
example: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPVILdH2u3yV5SAeE6XksD1z1vXRg0E4hJUov8ITDAZ2 user@host
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/user/profile:
|
||||
get:
|
||||
security:
|
||||
|
@ -3799,39 +3378,6 @@ paths:
|
|||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/user/folder:
|
||||
get:
|
||||
tags:
|
||||
- user APIs
|
||||
summary: Read folders contents
|
||||
description: Returns the contents of the specified folder for the logged in user. Please use '/user/dirs' instead
|
||||
operationId: get_user_folder_contents
|
||||
deprecated: true
|
||||
parameters:
|
||||
- in: query
|
||||
name: path
|
||||
description: Path to the folder to read. It must be URL encoded, for example the path "my dir/àdir" must be sent as "my%20dir%2F%C3%A0dir". If empty or missing the user's start directory is assumed. If relative, the user's start directory is used as the base
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/DirEntry'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/user/dirs:
|
||||
get:
|
||||
tags:
|
||||
|
@ -3972,46 +3518,6 @@ paths:
|
|||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/user/file:
|
||||
get:
|
||||
tags:
|
||||
- user APIs
|
||||
summary: Download a single file
|
||||
description: Returns the file contents as response body. Please use '/user/files' instead
|
||||
operationId: get_user_file
|
||||
deprecated: true
|
||||
parameters:
|
||||
- in: query
|
||||
name: path
|
||||
required: true
|
||||
description: Path to the file to download. It must be URL encoded, for example the path "my dir/àdir/file.txt" must be sent as "my%20dir%2F%C3%A0dir%2Ffile.txt"
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
content:
|
||||
'*/*':
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
'206':
|
||||
description: successful operation
|
||||
content:
|
||||
'*/*':
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
default:
|
||||
$ref: '#/components/responses/DefaultResponse'
|
||||
/user/files:
|
||||
get:
|
||||
tags:
|
||||
|
|
Loading…
Reference in a new issue