mirror of
https://github.com/drakkan/sftpgo.git
synced 2025-12-07 14:50:55 +03:00
REST API v2
- add JWT authentication - admins are now stored inside the data provider - admin access can be restricted based on the source IP: both proxy header and connection IP are checked - deprecate REST API CLI: it is not relevant anymore Some other changes to the REST API can still happen before releasing SFTPGo 2.0.0 Fixes #197
This commit is contained in:
@@ -1,33 +1,31 @@
|
||||
package httpd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/jwtauth"
|
||||
"github.com/lestrrat-go/jwx/jwt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/drakkan/sftpgo/common"
|
||||
"github.com/drakkan/sftpgo/dataprovider"
|
||||
"github.com/drakkan/sftpgo/kms"
|
||||
"github.com/drakkan/sftpgo/utils"
|
||||
"github.com/drakkan/sftpgo/vfs"
|
||||
)
|
||||
|
||||
const (
|
||||
invalidURL = "http://foo\x7f.com/"
|
||||
inactiveURL = "http://127.0.0.1:12345"
|
||||
)
|
||||
|
||||
func TestShouldBind(t *testing.T) {
|
||||
@@ -55,455 +53,6 @@ func TestGetRespStatus(t *testing.T) {
|
||||
assert.Equal(t, http.StatusInternalServerError, respStatus)
|
||||
}
|
||||
|
||||
func TestCheckResponse(t *testing.T) {
|
||||
err := checkResponse(http.StatusOK, http.StatusCreated)
|
||||
assert.Error(t, err)
|
||||
err = checkResponse(http.StatusBadRequest, http.StatusBadRequest)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestCheckFolder(t *testing.T) {
|
||||
expected := &vfs.BaseVirtualFolder{}
|
||||
actual := &vfs.BaseVirtualFolder{}
|
||||
err := checkFolder(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.ID = 1
|
||||
actual.ID = 2
|
||||
err = checkFolder(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.ID = 2
|
||||
actual.ID = 2
|
||||
expected.MappedPath = "path"
|
||||
err = checkFolder(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.MappedPath = ""
|
||||
expected.LastQuotaUpdate = 1
|
||||
err = checkFolder(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.LastQuotaUpdate = 0
|
||||
expected.UsedQuotaFiles = 1
|
||||
err = checkFolder(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.UsedQuotaFiles = 0
|
||||
expected.UsedQuotaSize = 1
|
||||
err = checkFolder(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.UsedQuotaSize = 0
|
||||
expected.Users = append(expected.Users, "user1")
|
||||
err = checkFolder(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.Users = append(actual.Users, "user2")
|
||||
err = checkFolder(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.Users = nil
|
||||
actual.Users = nil
|
||||
}
|
||||
|
||||
func TestCheckUser(t *testing.T) {
|
||||
expected := &dataprovider.User{}
|
||||
actual := &dataprovider.User{}
|
||||
actual.Password = "password"
|
||||
err := checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.Password = ""
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.ID = 1
|
||||
actual.ID = 2
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.ID = 2
|
||||
actual.ID = 2
|
||||
expected.Permissions = make(map[string][]string)
|
||||
expected.Permissions["/"] = []string{dataprovider.PermCreateDirs, dataprovider.PermDelete, dataprovider.PermDownload}
|
||||
actual.Permissions = make(map[string][]string)
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.Permissions["/"] = []string{dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks}
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.Permissions["/"] = append(expected.Permissions["/"], dataprovider.PermRename)
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.Permissions = make(map[string][]string)
|
||||
expected.Permissions["/somedir"] = []string{dataprovider.PermAny}
|
||||
actual.Permissions = make(map[string][]string)
|
||||
actual.Permissions["/otherdir"] = []string{dataprovider.PermCreateDirs, dataprovider.PermCreateSymlinks}
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.Permissions = make(map[string][]string)
|
||||
actual.Permissions = make(map[string][]string)
|
||||
actual.FsConfig.Provider = dataprovider.S3FilesystemProvider
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.FsConfig.Provider = dataprovider.LocalFilesystemProvider
|
||||
expected.VirtualFolders = append(expected.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
MappedPath: os.TempDir(),
|
||||
},
|
||||
VirtualPath: "/vdir",
|
||||
})
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.VirtualFolders = append(actual.VirtualFolders, vfs.VirtualFolder{
|
||||
BaseVirtualFolder: vfs.BaseVirtualFolder{
|
||||
MappedPath: os.TempDir(),
|
||||
},
|
||||
VirtualPath: "/vdir1",
|
||||
})
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestCompareUserFilters(t *testing.T) {
|
||||
expected := &dataprovider.User{}
|
||||
actual := &dataprovider.User{}
|
||||
actual.ID = 1
|
||||
expected.ID = 1
|
||||
expected.Filters.AllowedIP = []string{}
|
||||
actual.Filters.AllowedIP = []string{"192.168.1.2/32"}
|
||||
err := checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.Filters.AllowedIP = []string{"192.168.1.3/32"}
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.Filters.AllowedIP = []string{}
|
||||
actual.Filters.AllowedIP = []string{}
|
||||
expected.Filters.DeniedIP = []string{}
|
||||
actual.Filters.DeniedIP = []string{"192.168.1.2/32"}
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.Filters.DeniedIP = []string{"192.168.1.3/32"}
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.Filters.DeniedIP = []string{}
|
||||
actual.Filters.DeniedIP = []string{}
|
||||
expected.Filters.DeniedLoginMethods = []string{}
|
||||
actual.Filters.DeniedLoginMethods = []string{dataprovider.SSHLoginMethodPublicKey}
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.Filters.DeniedLoginMethods = []string{dataprovider.LoginMethodPassword}
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.Filters.DeniedLoginMethods = []string{}
|
||||
actual.Filters.DeniedLoginMethods = []string{}
|
||||
actual.Filters.DeniedProtocols = []string{common.ProtocolFTP}
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.Filters.DeniedProtocols = []string{common.ProtocolWebDAV}
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.Filters.DeniedProtocols = []string{}
|
||||
actual.Filters.DeniedProtocols = []string{}
|
||||
expected.Filters.MaxUploadFileSize = 0
|
||||
actual.Filters.MaxUploadFileSize = 100
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.Filters.MaxUploadFileSize = 0
|
||||
expected.Filters.FileExtensions = append(expected.Filters.FileExtensions, dataprovider.ExtensionsFilter{
|
||||
Path: "/",
|
||||
AllowedExtensions: []string{".jpg", ".png"},
|
||||
DeniedExtensions: []string{".zip", ".rar"},
|
||||
})
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.Filters.FileExtensions = append(actual.Filters.FileExtensions, dataprovider.ExtensionsFilter{
|
||||
Path: "/sub",
|
||||
AllowedExtensions: []string{".jpg", ".png"},
|
||||
DeniedExtensions: []string{".zip", ".rar"},
|
||||
})
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.Filters.FileExtensions[0] = dataprovider.ExtensionsFilter{
|
||||
Path: "/",
|
||||
AllowedExtensions: []string{".jpg"},
|
||||
DeniedExtensions: []string{".zip", ".rar"},
|
||||
}
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.Filters.FileExtensions[0] = dataprovider.ExtensionsFilter{
|
||||
Path: "/",
|
||||
AllowedExtensions: []string{".tiff", ".png"},
|
||||
DeniedExtensions: []string{".zip", ".rar"},
|
||||
}
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.Filters.FileExtensions[0] = dataprovider.ExtensionsFilter{
|
||||
Path: "/",
|
||||
AllowedExtensions: []string{".jpg", ".png"},
|
||||
DeniedExtensions: []string{".tar.gz", ".rar"},
|
||||
}
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.Filters.FileExtensions = nil
|
||||
actual.Filters.FilePatterns = nil
|
||||
expected.Filters.FileExtensions = nil
|
||||
expected.Filters.FilePatterns = nil
|
||||
expected.Filters.FilePatterns = append(expected.Filters.FilePatterns, dataprovider.PatternsFilter{
|
||||
Path: "/",
|
||||
AllowedPatterns: []string{"*.jpg", "*.png"},
|
||||
DeniedPatterns: []string{"*.zip", "*.rar"},
|
||||
})
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.Filters.FilePatterns = append(actual.Filters.FilePatterns, dataprovider.PatternsFilter{
|
||||
Path: "/sub",
|
||||
AllowedPatterns: []string{"*.jpg", "*.png"},
|
||||
DeniedPatterns: []string{"*.zip", "*.rar"},
|
||||
})
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.Filters.FilePatterns[0] = dataprovider.PatternsFilter{
|
||||
Path: "/",
|
||||
AllowedPatterns: []string{"*.jpg"},
|
||||
DeniedPatterns: []string{"*.zip", "*.rar"},
|
||||
}
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.Filters.FilePatterns[0] = dataprovider.PatternsFilter{
|
||||
Path: "/",
|
||||
AllowedPatterns: []string{"*.tiff", "*.png"},
|
||||
DeniedPatterns: []string{"*.zip", "*.rar"},
|
||||
}
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.Filters.FilePatterns[0] = dataprovider.PatternsFilter{
|
||||
Path: "/",
|
||||
AllowedPatterns: []string{"*.jpg", "*.png"},
|
||||
DeniedPatterns: []string{"*.tar.gz", "*.rar"},
|
||||
}
|
||||
err = checkUser(expected, actual)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestCompareUserFields(t *testing.T) {
|
||||
expected := &dataprovider.User{}
|
||||
actual := &dataprovider.User{}
|
||||
expected.Permissions = make(map[string][]string)
|
||||
actual.Permissions = make(map[string][]string)
|
||||
expected.Username = "test"
|
||||
err := compareEqualsUserFields(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.Username = ""
|
||||
expected.HomeDir = "homedir"
|
||||
err = compareEqualsUserFields(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.HomeDir = ""
|
||||
expected.UID = 1
|
||||
err = compareEqualsUserFields(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.UID = 0
|
||||
expected.GID = 1
|
||||
err = compareEqualsUserFields(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.GID = 0
|
||||
expected.MaxSessions = 2
|
||||
err = compareEqualsUserFields(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.MaxSessions = 0
|
||||
expected.QuotaSize = 4096
|
||||
err = compareEqualsUserFields(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.QuotaSize = 0
|
||||
expected.QuotaFiles = 2
|
||||
err = compareEqualsUserFields(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.QuotaFiles = 0
|
||||
expected.Permissions["/"] = []string{dataprovider.PermCreateDirs}
|
||||
err = compareEqualsUserFields(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.Permissions = nil
|
||||
expected.UploadBandwidth = 64
|
||||
err = compareEqualsUserFields(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.UploadBandwidth = 0
|
||||
expected.DownloadBandwidth = 128
|
||||
err = compareEqualsUserFields(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.DownloadBandwidth = 0
|
||||
expected.Status = 1
|
||||
err = compareEqualsUserFields(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.Status = 0
|
||||
expected.ExpirationDate = 123
|
||||
err = compareEqualsUserFields(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.ExpirationDate = 0
|
||||
expected.AdditionalInfo = "info"
|
||||
err = compareEqualsUserFields(expected, actual)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestCompareUserFsConfig(t *testing.T) {
|
||||
secretString := "access secret"
|
||||
expected := &dataprovider.User{}
|
||||
actual := &dataprovider.User{}
|
||||
expected.SetEmptySecretsIfNil()
|
||||
actual.SetEmptySecretsIfNil()
|
||||
expected.FsConfig.Provider = dataprovider.S3FilesystemProvider
|
||||
err := compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.Provider = dataprovider.LocalFilesystemProvider
|
||||
expected.FsConfig.S3Config.Bucket = "bucket"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.S3Config.Bucket = ""
|
||||
expected.FsConfig.S3Config.Region = "region"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.S3Config.Region = ""
|
||||
expected.FsConfig.S3Config.AccessKey = "access key"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.S3Config.AccessKey = ""
|
||||
actual.FsConfig.S3Config.AccessSecret = kms.NewPlainSecret(secretString)
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
secret, err := utils.EncryptData(secretString)
|
||||
assert.NoError(t, err)
|
||||
actual.FsConfig.S3Config.AccessSecret = kms.NewEmptySecret()
|
||||
kmsSecret, err := kms.GetSecretFromCompatString(secret)
|
||||
assert.NoError(t, err)
|
||||
expected.FsConfig.S3Config.AccessSecret = kmsSecret
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.S3Config.AccessSecret = kms.NewPlainSecret(secretString)
|
||||
actual.FsConfig.S3Config.AccessSecret = kms.NewEmptySecret()
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.S3Config.AccessSecret = kms.NewPlainSecret(secretString)
|
||||
actual.FsConfig.S3Config.AccessSecret = kms.NewSecret(kms.SecretStatusSecretBox, "", "", "")
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.FsConfig.S3Config.AccessSecret = kms.NewSecret(kms.SecretStatusSecretBox, secretString, "", "data")
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.FsConfig.S3Config.AccessSecret = kms.NewSecret(kms.SecretStatusSecretBox, secretString, "key", "")
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.S3Config.AccessSecret = nil
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.S3Config.AccessSecret = kms.NewEmptySecret()
|
||||
actual.FsConfig.S3Config.AccessSecret = kms.NewEmptySecret()
|
||||
expected.FsConfig.S3Config.Endpoint = "http://127.0.0.1:9000/"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.S3Config.Endpoint = ""
|
||||
expected.FsConfig.S3Config.StorageClass = "Standard"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.S3Config.StorageClass = ""
|
||||
expected.FsConfig.S3Config.KeyPrefix = "somedir/subdir"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.S3Config.KeyPrefix = ""
|
||||
expected.FsConfig.S3Config.UploadPartSize = 10
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.S3Config.UploadPartSize = 0
|
||||
expected.FsConfig.S3Config.UploadConcurrency = 3
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.S3Config.UploadConcurrency = 0
|
||||
expected.FsConfig.CryptConfig.Passphrase = kms.NewPlainSecret("payload")
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.CryptConfig.Passphrase = kms.NewEmptySecret()
|
||||
expected.FsConfig.SFTPConfig.Endpoint = "endpoint"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.SFTPConfig.Endpoint = ""
|
||||
expected.FsConfig.SFTPConfig.Username = "user"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.SFTPConfig.Username = ""
|
||||
expected.FsConfig.SFTPConfig.Password = kms.NewPlainSecret("sftppwd")
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.SFTPConfig.Password = kms.NewEmptySecret()
|
||||
expected.FsConfig.SFTPConfig.PrivateKey = kms.NewPlainSecret("fake key")
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.SFTPConfig.PrivateKey = kms.NewEmptySecret()
|
||||
expected.FsConfig.SFTPConfig.Prefix = "/home"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.SFTPConfig.Prefix = ""
|
||||
expected.FsConfig.SFTPConfig.Fingerprints = []string{"sha256:..."}
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
actual.FsConfig.SFTPConfig.Fingerprints = []string{"sha256:different"}
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestCompareUserGCSConfig(t *testing.T) {
|
||||
expected := &dataprovider.User{}
|
||||
actual := &dataprovider.User{}
|
||||
expected.FsConfig.GCSConfig.KeyPrefix = "somedir/subdir"
|
||||
err := compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.GCSConfig.KeyPrefix = ""
|
||||
expected.FsConfig.GCSConfig.Bucket = "bucket"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.GCSConfig.Bucket = ""
|
||||
expected.FsConfig.GCSConfig.StorageClass = "Standard"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.GCSConfig.StorageClass = ""
|
||||
expected.FsConfig.GCSConfig.AutomaticCredentials = 1
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.GCSConfig.AutomaticCredentials = 0
|
||||
}
|
||||
|
||||
func TestCompareUserAzureConfig(t *testing.T) {
|
||||
expected := &dataprovider.User{}
|
||||
actual := &dataprovider.User{}
|
||||
expected.FsConfig.AzBlobConfig.Container = "a"
|
||||
err := compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.AzBlobConfig.Container = ""
|
||||
expected.FsConfig.AzBlobConfig.AccountName = "aname"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.AzBlobConfig.AccountName = ""
|
||||
expected.FsConfig.AzBlobConfig.AccountKey = kms.NewSecret(kms.SecretStatusAWS, "payload", "", "")
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.AzBlobConfig.AccountKey = kms.NewEmptySecret()
|
||||
expected.FsConfig.AzBlobConfig.Endpoint = "endpt"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.AzBlobConfig.Endpoint = ""
|
||||
expected.FsConfig.AzBlobConfig.SASURL = "url"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.AzBlobConfig.SASURL = ""
|
||||
expected.FsConfig.AzBlobConfig.UploadPartSize = 1
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.AzBlobConfig.UploadPartSize = 0
|
||||
expected.FsConfig.AzBlobConfig.UploadConcurrency = 1
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.AzBlobConfig.UploadConcurrency = 0
|
||||
expected.FsConfig.AzBlobConfig.KeyPrefix = "prefix/"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.AzBlobConfig.KeyPrefix = ""
|
||||
expected.FsConfig.AzBlobConfig.UseEmulator = true
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.AzBlobConfig.UseEmulator = false
|
||||
expected.FsConfig.AzBlobConfig.AccessTier = "Hot"
|
||||
err = compareUserFsConfig(expected, actual)
|
||||
assert.Error(t, err)
|
||||
expected.FsConfig.AzBlobConfig.AccessTier = ""
|
||||
}
|
||||
|
||||
func TestGCSWebInvalidFormFile(t *testing.T) {
|
||||
form := make(url.Values)
|
||||
form.Set("username", "test_username")
|
||||
@@ -516,170 +65,313 @@ func TestGCSWebInvalidFormFile(t *testing.T) {
|
||||
assert.EqualError(t, err, http.ErrNotMultipart.Error())
|
||||
}
|
||||
|
||||
func TestApiCallsWithBadURL(t *testing.T) {
|
||||
oldBaseURL := httpBaseURL
|
||||
oldAuthUsername := authUsername
|
||||
oldAuthPassword := authPassword
|
||||
SetBaseURLAndCredentials(invalidURL, oldAuthUsername, oldAuthPassword)
|
||||
folder := vfs.BaseVirtualFolder{
|
||||
MappedPath: os.TempDir(),
|
||||
func TestInvalidToken(t *testing.T) {
|
||||
admin := dataprovider.Admin{
|
||||
Username: "admin",
|
||||
}
|
||||
u := dataprovider.User{}
|
||||
_, _, err := UpdateUser(u, http.StatusBadRequest, "")
|
||||
assert.Error(t, err)
|
||||
_, err = RemoveUser(u, http.StatusNotFound)
|
||||
assert.Error(t, err)
|
||||
_, err = RemoveFolder(folder, http.StatusNotFound)
|
||||
assert.Error(t, err)
|
||||
_, _, err = GetUsers(1, 0, "", http.StatusBadRequest)
|
||||
assert.Error(t, err)
|
||||
_, _, err = GetFolders(1, 0, "", http.StatusBadRequest)
|
||||
assert.Error(t, err)
|
||||
_, err = UpdateQuotaUsage(u, "", http.StatusNotFound)
|
||||
assert.Error(t, err)
|
||||
_, err = UpdateFolderQuotaUsage(folder, "", http.StatusNotFound)
|
||||
assert.Error(t, err)
|
||||
_, err = CloseConnection("non_existent_id", http.StatusNotFound)
|
||||
assert.Error(t, err)
|
||||
_, _, err = Dumpdata("backup.json", "", http.StatusBadRequest)
|
||||
assert.Error(t, err)
|
||||
_, _, err = Loaddata("/tmp/backup.json", "", "", http.StatusBadRequest)
|
||||
assert.Error(t, err)
|
||||
_, _, err = GetBanTime("", http.StatusBadRequest)
|
||||
assert.Error(t, err)
|
||||
_, _, err = GetScore("", http.StatusBadRequest)
|
||||
assert.Error(t, err)
|
||||
SetBaseURLAndCredentials(oldBaseURL, oldAuthUsername, oldAuthPassword)
|
||||
errFake := errors.New("fake error")
|
||||
asJSON, err := json.Marshal(admin)
|
||||
assert.NoError(t, err)
|
||||
req, _ := http.NewRequest(http.MethodPut, path.Join(adminPath, admin.Username), bytes.NewBuffer(asJSON))
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("username", admin.Username)
|
||||
req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, rctx))
|
||||
req = req.WithContext(context.WithValue(req.Context(), jwtauth.ErrorCtxKey, errFake))
|
||||
rr := httptest.NewRecorder()
|
||||
updateAdmin(rr, req)
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
rr = httptest.NewRecorder()
|
||||
deleteAdmin(rr, req)
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
|
||||
adminPwd := adminPwd{
|
||||
CurrentPassword: "old",
|
||||
NewPassword: "new",
|
||||
}
|
||||
asJSON, err = json.Marshal(adminPwd)
|
||||
assert.NoError(t, err)
|
||||
req, _ = http.NewRequest(http.MethodPut, "", bytes.NewBuffer(asJSON))
|
||||
req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, rctx))
|
||||
req = req.WithContext(context.WithValue(req.Context(), jwtauth.ErrorCtxKey, errFake))
|
||||
rr = httptest.NewRecorder()
|
||||
changeAdminPassword(rr, req)
|
||||
assert.Equal(t, http.StatusInternalServerError, rr.Code)
|
||||
adm := getAdminFromToken(req)
|
||||
assert.Empty(t, adm.Username)
|
||||
}
|
||||
|
||||
func TestApiCallToNotListeningServer(t *testing.T) {
|
||||
oldBaseURL := httpBaseURL
|
||||
oldAuthUsername := authUsername
|
||||
oldAuthPassword := authPassword
|
||||
SetBaseURLAndCredentials(inactiveURL, oldAuthUsername, oldAuthPassword)
|
||||
u := dataprovider.User{}
|
||||
_, _, err := AddUser(u, http.StatusBadRequest)
|
||||
assert.Error(t, err)
|
||||
_, _, err = UpdateUser(u, http.StatusNotFound, "")
|
||||
assert.Error(t, err)
|
||||
_, err = RemoveUser(u, http.StatusNotFound)
|
||||
assert.Error(t, err)
|
||||
_, _, err = GetUserByID(-1, http.StatusNotFound)
|
||||
assert.Error(t, err)
|
||||
_, _, err = GetUsers(100, 0, "", http.StatusOK)
|
||||
assert.Error(t, err)
|
||||
_, err = UpdateQuotaUsage(u, "", http.StatusNotFound)
|
||||
assert.Error(t, err)
|
||||
_, _, err = GetQuotaScans(http.StatusOK)
|
||||
assert.Error(t, err)
|
||||
_, err = StartQuotaScan(u, http.StatusNotFound)
|
||||
assert.Error(t, err)
|
||||
folder := vfs.BaseVirtualFolder{
|
||||
MappedPath: os.TempDir(),
|
||||
}
|
||||
_, err = StartFolderQuotaScan(folder, http.StatusNotFound)
|
||||
assert.Error(t, err)
|
||||
_, _, err = AddFolder(folder, http.StatusOK)
|
||||
assert.Error(t, err)
|
||||
_, err = RemoveFolder(folder, http.StatusOK)
|
||||
assert.Error(t, err)
|
||||
_, _, err = GetFolders(0, 0, "", http.StatusOK)
|
||||
assert.Error(t, err)
|
||||
_, err = UpdateFolderQuotaUsage(folder, "", http.StatusNotFound)
|
||||
assert.Error(t, err)
|
||||
_, _, err = GetFoldersQuotaScans(http.StatusOK)
|
||||
assert.Error(t, err)
|
||||
_, _, err = GetConnections(http.StatusOK)
|
||||
assert.Error(t, err)
|
||||
_, err = CloseConnection("non_existent_id", http.StatusNotFound)
|
||||
assert.Error(t, err)
|
||||
_, _, err = GetVersion(http.StatusOK)
|
||||
assert.Error(t, err)
|
||||
_, _, err = GetStatus(http.StatusOK)
|
||||
assert.Error(t, err)
|
||||
_, _, err = Dumpdata("backup.json", "0", http.StatusOK)
|
||||
assert.Error(t, err)
|
||||
_, _, err = Loaddata("/tmp/backup.json", "", "", http.StatusOK)
|
||||
assert.Error(t, err)
|
||||
_, _, err = GetBanTime("", http.StatusBadRequest)
|
||||
assert.Error(t, err)
|
||||
_, _, err = GetScore("", http.StatusBadRequest)
|
||||
assert.Error(t, err)
|
||||
err = UnbanIP("", http.StatusBadRequest)
|
||||
assert.Error(t, err)
|
||||
func TestUpdateWebAdminInvalidClaims(t *testing.T) {
|
||||
server := httpdServer{}
|
||||
server.initializeRouter()
|
||||
|
||||
SetBaseURLAndCredentials(oldBaseURL, oldAuthUsername, oldAuthPassword)
|
||||
rr := httptest.NewRecorder()
|
||||
admin := dataprovider.Admin{
|
||||
Username: "",
|
||||
Password: "password",
|
||||
}
|
||||
c := jwtTokenClaims{
|
||||
Username: admin.Username,
|
||||
Permissions: admin.Permissions,
|
||||
Signature: admin.GetSignature(),
|
||||
}
|
||||
token, err := c.createTokenResponse(server.tokenAuth)
|
||||
assert.NoError(t, err)
|
||||
|
||||
form := make(url.Values)
|
||||
form.Set("status", "1")
|
||||
req, _ := http.NewRequest(http.MethodPost, path.Join(webAdminPath, "admin"), bytes.NewBuffer([]byte(form.Encode())))
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("username", "admin")
|
||||
req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, rctx))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Set("Cookie", fmt.Sprintf("jwt=%v", token["access_token"]))
|
||||
handleWebUpdateAdminPost(rr, req)
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
assert.Contains(t, rr.Body.String(), "Invalid token claims")
|
||||
}
|
||||
|
||||
func TestBasicAuth(t *testing.T) {
|
||||
oldAuthUsername := authUsername
|
||||
oldAuthPassword := authPassword
|
||||
authUserFile := filepath.Join(os.TempDir(), "http_users.txt")
|
||||
authUserData := []byte("test1:$2y$05$bcHSED7aO1cfLto6ZdDBOOKzlwftslVhtpIkRhAtSa4GuLmk5mola\n")
|
||||
err := ioutil.WriteFile(authUserFile, authUserData, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
httpAuth, _ = common.NewBasicAuthProvider(authUserFile)
|
||||
_, _, err = GetVersion(http.StatusUnauthorized)
|
||||
assert.NoError(t, err)
|
||||
SetBaseURLAndCredentials(httpBaseURL, "test1", "password1")
|
||||
_, _, err = GetVersion(http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
SetBaseURLAndCredentials(httpBaseURL, "test1", "wrong_password")
|
||||
resp, _ := sendHTTPRequest(http.MethodGet, buildURLRelativeToBase(metricsPath), nil, "")
|
||||
defer resp.Body.Close()
|
||||
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
|
||||
authUserData = append(authUserData, []byte("test2:$1$OtSSTL8b$bmaCqEksI1e7rnZSjsIDR1\n")...)
|
||||
err = ioutil.WriteFile(authUserFile, authUserData, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
SetBaseURLAndCredentials(httpBaseURL, "test2", "password2")
|
||||
_, _, err = GetVersion(http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
SetBaseURLAndCredentials(httpBaseURL, "test2", "wrong_password")
|
||||
_, _, err = GetVersion(http.StatusOK)
|
||||
assert.Error(t, err)
|
||||
authUserData = append(authUserData, []byte("test2:$apr1$gLnIkRIf$Xr/6aJfmIrihP4b2N2tcs/\n")...)
|
||||
err = ioutil.WriteFile(authUserFile, authUserData, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
SetBaseURLAndCredentials(httpBaseURL, "test2", "password2")
|
||||
_, _, err = GetVersion(http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
SetBaseURLAndCredentials(httpBaseURL, "test2", "wrong_password")
|
||||
_, _, err = GetVersion(http.StatusOK)
|
||||
assert.Error(t, err)
|
||||
authUserData = append(authUserData, []byte("test3:$apr1$gLnIkRIf$Xr/6$aJfmIr$ihP4b2N2tcs/\n")...)
|
||||
err = ioutil.WriteFile(authUserFile, authUserData, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
SetBaseURLAndCredentials(httpBaseURL, "test3", "wrong_password")
|
||||
_, _, err = GetVersion(http.StatusUnauthorized)
|
||||
assert.NoError(t, err)
|
||||
authUserData = append(authUserData, []byte("test4:$invalid$gLnIkRIf$Xr/6$aJfmIr$ihP4b2N2tcs/\n")...)
|
||||
err = ioutil.WriteFile(authUserFile, authUserData, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
SetBaseURLAndCredentials(httpBaseURL, "test3", "password2")
|
||||
_, _, err = GetVersion(http.StatusUnauthorized)
|
||||
assert.NoError(t, err)
|
||||
if runtime.GOOS != osWindows {
|
||||
authUserData = append(authUserData, []byte("test5:$apr1$gLnIkRIf$Xr/6aJfmIrihP4b2N2tcs/\n")...)
|
||||
err = ioutil.WriteFile(authUserFile, authUserData, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
err = os.Chmod(authUserFile, 0001)
|
||||
assert.NoError(t, err)
|
||||
SetBaseURLAndCredentials(httpBaseURL, "test5", "password2")
|
||||
_, _, err = GetVersion(http.StatusUnauthorized)
|
||||
assert.NoError(t, err)
|
||||
err = os.Chmod(authUserFile, os.ModePerm)
|
||||
assert.NoError(t, err)
|
||||
func TestCreateTokenError(t *testing.T) {
|
||||
server := httpdServer{
|
||||
tokenAuth: jwtauth.New("PS256", utils.GenerateRandomBytes(32), nil),
|
||||
}
|
||||
authUserData = append(authUserData, []byte("\"foo\"bar\"\r\n")...)
|
||||
err = ioutil.WriteFile(authUserFile, authUserData, os.ModePerm)
|
||||
rr := httptest.NewRecorder()
|
||||
admin := dataprovider.Admin{
|
||||
Username: "admin",
|
||||
Password: "password",
|
||||
}
|
||||
req, _ := http.NewRequest(http.MethodGet, tokenPath, nil)
|
||||
|
||||
server.checkAddrAndSendToken(rr, req, admin)
|
||||
assert.Equal(t, http.StatusInternalServerError, rr.Code)
|
||||
|
||||
rr = httptest.NewRecorder()
|
||||
form := make(url.Values)
|
||||
form.Set("username", admin.Username)
|
||||
form.Set("password", admin.Password)
|
||||
req, _ = http.NewRequest(http.MethodPost, webLoginPath, bytes.NewBuffer([]byte(form.Encode())))
|
||||
req.RemoteAddr = "127.0.0.1:1234"
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
server.handleWebLoginPost(rr, req)
|
||||
assert.Equal(t, http.StatusOK, rr.Code, rr.Body.String())
|
||||
// req with no content type
|
||||
req, _ = http.NewRequest(http.MethodPost, webLoginPath, nil)
|
||||
rr = httptest.NewRecorder()
|
||||
server.handleWebLoginPost(rr, req)
|
||||
assert.Equal(t, http.StatusOK, rr.Code, rr.Body.String())
|
||||
// req with no POST body
|
||||
req, _ = http.NewRequest(http.MethodGet, webLoginPath+"?a=a%C3%AO%GG", nil)
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
rr = httptest.NewRecorder()
|
||||
server.handleWebLoginPost(rr, req)
|
||||
assert.Equal(t, http.StatusOK, rr.Code, rr.Body.String())
|
||||
req, _ = http.NewRequest(http.MethodGet, webLoginPath+"?a=a%C3%A1%G2", nil)
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
rr = httptest.NewRecorder()
|
||||
handleWebAdminChangePwdPost(rr, req)
|
||||
assert.Equal(t, http.StatusOK, rr.Code, rr.Body.String())
|
||||
|
||||
req, _ = http.NewRequest(http.MethodGet, webLoginPath+"?a=a%C3%A2%G3", nil)
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
_, err := getAdminFromPostFields(req)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestJWTTokenValidation(t *testing.T) {
|
||||
tokenAuth := jwtauth.New("HS256", utils.GenerateRandomBytes(32), nil)
|
||||
claims := make(map[string]interface{})
|
||||
claims["username"] = "admin"
|
||||
claims[jwt.ExpirationKey] = time.Now().UTC().Add(-1 * time.Hour)
|
||||
token, _, err := tokenAuth.Encode(claims)
|
||||
assert.NoError(t, err)
|
||||
SetBaseURLAndCredentials(httpBaseURL, "test2", "password2")
|
||||
_, _, err = GetVersion(http.StatusUnauthorized)
|
||||
|
||||
r := GetHTTPRouter()
|
||||
fn := jwtAuthenticator(r)
|
||||
rr := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(http.MethodGet, userPath, nil)
|
||||
ctx := jwtauth.NewContext(req.Context(), token, nil)
|
||||
fn.ServeHTTP(rr, req.WithContext(ctx))
|
||||
assert.Equal(t, http.StatusUnauthorized, rr.Code)
|
||||
|
||||
fn = jwtAuthenticatorWeb(r)
|
||||
rr = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest(http.MethodGet, webUserPath, nil)
|
||||
ctx = jwtauth.NewContext(req.Context(), token, nil)
|
||||
|
||||
fn.ServeHTTP(rr, req.WithContext(ctx))
|
||||
assert.Equal(t, http.StatusFound, rr.Code)
|
||||
|
||||
errTest := errors.New("test error")
|
||||
permFn := checkPerm(dataprovider.PermAdminAny)
|
||||
fn = permFn(r)
|
||||
rr = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest(http.MethodGet, userPath, nil)
|
||||
ctx = jwtauth.NewContext(req.Context(), token, errTest)
|
||||
fn.ServeHTTP(rr, req.WithContext(ctx))
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
|
||||
permFn = checkPerm(dataprovider.PermAdminAny)
|
||||
fn = permFn(r)
|
||||
rr = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest(http.MethodGet, webUserPath, nil)
|
||||
req.RequestURI = webUserPath
|
||||
ctx = jwtauth.NewContext(req.Context(), token, errTest)
|
||||
fn.ServeHTTP(rr, req.WithContext(ctx))
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
}
|
||||
|
||||
func TestAdminAllowListConnAddr(t *testing.T) {
|
||||
server := httpdServer{}
|
||||
admin := dataprovider.Admin{
|
||||
Filters: dataprovider.AdminFilters{
|
||||
AllowList: []string{"192.168.1.0/24"},
|
||||
},
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(http.MethodGet, tokenPath, nil)
|
||||
ctx := context.WithValue(req.Context(), connAddrKey, "127.0.0.1:4567")
|
||||
req.RemoteAddr = "192.168.1.16:1234"
|
||||
server.checkAddrAndSendToken(rr, req.WithContext(ctx), admin)
|
||||
assert.Equal(t, http.StatusForbidden, rr.Code, rr.Body.String())
|
||||
}
|
||||
|
||||
func TestUpdateContextFromCookie(t *testing.T) {
|
||||
server := httpdServer{
|
||||
tokenAuth: jwtauth.New("HS256", utils.GenerateRandomBytes(32), nil),
|
||||
}
|
||||
req, _ := http.NewRequest(http.MethodGet, tokenPath, nil)
|
||||
claims := make(map[string]interface{})
|
||||
claims["a"] = "b"
|
||||
token, _, err := server.tokenAuth.Encode(claims)
|
||||
assert.NoError(t, err)
|
||||
err = os.Remove(authUserFile)
|
||||
|
||||
ctx := jwtauth.NewContext(req.Context(), token, nil)
|
||||
server.updateContextFromCookie(req.WithContext(ctx))
|
||||
}
|
||||
|
||||
func TestCookieExpiration(t *testing.T) {
|
||||
server := httpdServer{
|
||||
tokenAuth: jwtauth.New("HS256", utils.GenerateRandomBytes(32), nil),
|
||||
}
|
||||
err := errors.New("test error")
|
||||
rr := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(http.MethodGet, tokenPath, nil)
|
||||
ctx := jwtauth.NewContext(req.Context(), nil, err)
|
||||
server.checkCookieExpiration(rr, req.WithContext(ctx))
|
||||
cookie := rr.Header().Get("Set-Cookie")
|
||||
assert.Empty(t, cookie)
|
||||
|
||||
req, _ = http.NewRequest(http.MethodGet, tokenPath, nil)
|
||||
claims := make(map[string]interface{})
|
||||
claims["a"] = "b"
|
||||
token, _, err := server.tokenAuth.Encode(claims)
|
||||
assert.NoError(t, err)
|
||||
SetBaseURLAndCredentials(httpBaseURL, oldAuthUsername, oldAuthPassword)
|
||||
httpAuth, _ = common.NewBasicAuthProvider("")
|
||||
ctx = jwtauth.NewContext(req.Context(), token, nil)
|
||||
server.checkCookieExpiration(rr, req.WithContext(ctx))
|
||||
cookie = rr.Header().Get("Set-Cookie")
|
||||
assert.Empty(t, cookie)
|
||||
|
||||
admin := dataprovider.Admin{
|
||||
Username: "newtestadmin",
|
||||
Password: "password",
|
||||
Permissions: []string{dataprovider.PermAdminAny},
|
||||
}
|
||||
claims = make(map[string]interface{})
|
||||
claims[claimUsernameKey] = admin.Username
|
||||
claims[claimPermissionsKey] = admin.Permissions
|
||||
claims[jwt.SubjectKey] = admin.GetSignature()
|
||||
claims[jwt.ExpirationKey] = time.Now().Add(1 * time.Minute)
|
||||
token, _, err = server.tokenAuth.Encode(claims)
|
||||
assert.NoError(t, err)
|
||||
req, _ = http.NewRequest(http.MethodGet, tokenPath, nil)
|
||||
ctx = jwtauth.NewContext(req.Context(), token, nil)
|
||||
server.checkCookieExpiration(rr, req.WithContext(ctx))
|
||||
cookie = rr.Header().Get("Set-Cookie")
|
||||
assert.Empty(t, cookie)
|
||||
|
||||
admin.Status = 0
|
||||
err = dataprovider.AddAdmin(&admin)
|
||||
assert.NoError(t, err)
|
||||
req, _ = http.NewRequest(http.MethodGet, tokenPath, nil)
|
||||
ctx = jwtauth.NewContext(req.Context(), token, nil)
|
||||
server.checkCookieExpiration(rr, req.WithContext(ctx))
|
||||
cookie = rr.Header().Get("Set-Cookie")
|
||||
assert.Empty(t, cookie)
|
||||
|
||||
admin.Status = 1
|
||||
admin.Filters.AllowList = []string{"172.16.1.0/24"}
|
||||
err = dataprovider.UpdateAdmin(&admin)
|
||||
assert.NoError(t, err)
|
||||
req, _ = http.NewRequest(http.MethodGet, tokenPath, nil)
|
||||
ctx = jwtauth.NewContext(req.Context(), token, nil)
|
||||
server.checkCookieExpiration(rr, req.WithContext(ctx))
|
||||
cookie = rr.Header().Get("Set-Cookie")
|
||||
assert.Empty(t, cookie)
|
||||
|
||||
admin, err = dataprovider.AdminExists(admin.Username)
|
||||
assert.NoError(t, err)
|
||||
claims = make(map[string]interface{})
|
||||
claims[claimUsernameKey] = admin.Username
|
||||
claims[claimPermissionsKey] = admin.Permissions
|
||||
claims[jwt.SubjectKey] = admin.GetSignature()
|
||||
claims[jwt.ExpirationKey] = time.Now().Add(1 * time.Minute)
|
||||
token, _, err = server.tokenAuth.Encode(claims)
|
||||
assert.NoError(t, err)
|
||||
req, _ = http.NewRequest(http.MethodGet, tokenPath, nil)
|
||||
req.RemoteAddr = "192.168.8.1:1234"
|
||||
ctx = jwtauth.NewContext(req.Context(), token, nil)
|
||||
server.checkCookieExpiration(rr, req.WithContext(ctx))
|
||||
cookie = rr.Header().Get("Set-Cookie")
|
||||
assert.Empty(t, cookie)
|
||||
|
||||
req, _ = http.NewRequest(http.MethodGet, tokenPath, nil)
|
||||
req.RemoteAddr = "172.16.1.2:1234"
|
||||
ctx = jwtauth.NewContext(req.Context(), token, nil)
|
||||
ctx = context.WithValue(ctx, connAddrKey, "10.9.9.9")
|
||||
server.checkCookieExpiration(rr, req.WithContext(ctx))
|
||||
cookie = rr.Header().Get("Set-Cookie")
|
||||
assert.Empty(t, cookie)
|
||||
|
||||
req, _ = http.NewRequest(http.MethodGet, tokenPath, nil)
|
||||
req.RemoteAddr = "172.16.1.12:4567"
|
||||
ctx = jwtauth.NewContext(req.Context(), token, nil)
|
||||
server.checkCookieExpiration(rr, req.WithContext(ctx))
|
||||
cookie = rr.Header().Get("Set-Cookie")
|
||||
assert.True(t, strings.HasPrefix(cookie, "jwt="))
|
||||
|
||||
err = dataprovider.DeleteAdmin(admin.Username)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestGetURLParam(t *testing.T) {
|
||||
req, _ := http.NewRequest(http.MethodGet, adminPwdPath, nil)
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("val", "testuser%C3%A0")
|
||||
rctx.URLParams.Add("inval", "testuser%C3%AO%GG")
|
||||
req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, rctx))
|
||||
escaped := getURLParam(req, "val")
|
||||
assert.Equal(t, "testuserà", escaped)
|
||||
escaped = getURLParam(req, "inval")
|
||||
assert.Equal(t, "testuser%C3%AO%GG", escaped)
|
||||
}
|
||||
|
||||
func TestChangePwdValidationErrors(t *testing.T) {
|
||||
err := doChangeAdminPassword(nil, "", "", "")
|
||||
require.Error(t, err)
|
||||
err = doChangeAdminPassword(nil, "a", "b", "c")
|
||||
require.Error(t, err)
|
||||
err = doChangeAdminPassword(nil, "a", "a", "a")
|
||||
require.Error(t, err)
|
||||
|
||||
req, _ := http.NewRequest(http.MethodPut, adminPwdPath, nil)
|
||||
err = doChangeAdminPassword(req, "currentpwd", "newpwd", "newpwd")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestRenderUnexistingFolder(t *testing.T) {
|
||||
rr := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(http.MethodPost, folderPath, nil)
|
||||
renderFolder(rr, req, "path not mapped")
|
||||
assert.Equal(t, http.StatusNotFound, rr.Code)
|
||||
}
|
||||
|
||||
func TestCloseConnectionHandler(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user