Remove external integrations, they are not supported in the new WIP WebClient

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
Nicola Murino 2023-11-05 11:20:27 +01:00
parent 2ee2098a48
commit b872c423ee
No known key found for this signature in database
GPG key ID: 935D2952DEC4EECF
10 changed files with 25 additions and 245 deletions

View file

@ -321,9 +321,6 @@ The configuration file contains the following sections:
- `client_ip_header_depth`, integer. Some client IP headers such as `X-Forwarded-For` can contain multiple IP address, this setting define the position to trust starting from the right. For example if we have: `10.0.0.1,11.0.0.1,12.0.0.1,13.0.0.1` and the depth is `0`, SFTPGo will use `13.0.0.1` as client IP, if depth is `1`, `12.0.0.1` will be used and so on. Default: `0`.
- `hide_login_url`, integer. If both web admin and web client are enabled each login page will show a link to the other one. This setting allows to hide this link. 0 means that the login links are displayed on both admin and client login page. This is the default. 1 means that the login link to the web client login page is hidden on admin login page. 2 means that the login link to the web admin login page is hidden on client login page. The flags can be combined, for example 3 will disable both login links.
- `render_openapi`, boolean. Set to `false` to disable serving of the OpenAPI schema and renderer. Default `true`.
- `web_client_integrations`, list of struct. The SFTPGo web client allows to send the files with the specified extensions to the configured URL using the [postMessage API](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage). This way you can integrate your own file viewer or editor. Take a look at the commentented example [here](../examples/webclient-integrations/test.html) to understand how to use this feature. Each struct has the following fields:
- `file_extensions`, list of strings. File extensions must be specified with the leading dot, for example `.pdf`.
- `url`, string. URL to open for the configured file extensions. The url will open in a new tab.
- `oidc`, struct. Defines the OpenID connect configuration. OpenID integration allows you to map your identity provider users to SFTPGo users and so you can login to SFTPGo Web Client and Web Admin user interfaces using your identity provider. The following fields are supported:
- `config_url`, string. Identifier for the service. If defined, SFTPGo will add `/.well-known/openid-configuration` to this url and attempt to retrieve the provider configuration on startup. SFTPGo will refuse to start if it fails to connect to the specified URL. Default: blank.
- `client_id`, string. Defines the application's ID. Default: blank.

View file

@ -1,118 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>SFTPGo WebClient - External integration test</title>
</head>
<body>
<textarea id="textarea_test" name="textarea_test" rows="10" cols="80">The text here will be sent to SFTPGo as blob</textarea>
<br>
<button onclick="saveBlob(false);">Save</button>
<br>
<button onclick="saveBlob(true);">Save binary file</button>
<br><br>
<b>Logs</b>
<pre id="log"></pre>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
var fileName;
var sftpgoUser;
// in real world usage set the origin when you call postMessage, we use `*` for testing purpose here
$(document).ready(function () {
if (window.opener == null || window.opener.closed) {
printLog("window opener gone!");
return;
}
// notify SFTPGo that the page is ready to receive the file
window.opener.postMessage({type: 'ready'},"*");
});
window.addEventListener('message', (event) => {
if (window.opener == null || window.opener.closed) {
printLog("window opener gone!");
return;
}
// you should check the origin before continuing
printLog("new message: "+JSON.stringify(event.data));
switch (event.data.type){
case 'readyResponse':
// after sending the ready request SFTPGo will reply with this response
// now you know the file name and the SFTPGo user
fileName = event.data.file_name;
sftpgoUser = event.data.user;
printLog("ready response received, file name: " + fileName+" SFTPGo user: "+sftpgoUser);
// you can initialize your viewer/editor based on the file extension and request the blob
window.opener.postMessage({type: 'sendBlob'}, "*");
break;
case 'blobDownloadStart':
// SFTPGo may take a while to read the file, just before it starts reading it will send this message.
// You can initialize a spinner if required for this file or simply ignore this message
printLog("blob download start received, file name: " + fileName+" SFTPGo user: "+sftpgoUser);
break;
case 'blobDownloadError':
// SFTPGo was unable to download the file and return it as blob
printLog("blob download failed, file name: " + fileName+" SFTPGo user: "+sftpgoUser+" error message: "+event.data.message);
break;
case 'blob':
// we received the file as blob
var extension = fileName.slice((fileName.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
printLog("blob received, file name: " + fileName+" extension: "+extension+" SFTPGo user: "+sftpgoUser);
if (extension == "txt"){
event.data.file.text().then(function(text){
$("#textarea_test").val(text);
});
}
break;
case 'blobSaveResult':
// event.data.status is OK or KO, if KO message is not empty
printLog("blob save status: "+event.data.status+", message: "+event.data.message);
if (event.data.status == "OK"){
printLog("blob saved, I'm useless now, close me");
}
break;
default:
printLog("Unsupported message: " + JSON.stringify(event.data));
}
});
function saveBlob(binary){
if (window.opener == null || window.opener.closed) {
printLog("window opener gone!");
return;
}
// if we have modified the file we can send it back to SFTPGo as a blob for saving
printLog("save blob, binary? "+binary);
if (binary){
// we download and save the SFTPGo logo. In a real application check errors
fetch('https://raw.githubusercontent.com/drakkan/sftpgo/main/docs/howto/img/logo.png')
.then(response => response.blob())
.then(function(responseBlob){
var blob = new File([responseBlob], fileName);
window.opener.postMessage({
type: 'saveBlob',
file: blob
},"*");
});
} else {
var blob = new Blob([$("#textarea_test").val()]);
window.opener.postMessage({
type: 'saveBlob',
file: blob
},"*");
}
}
function printLog(message){
console.log(message);
var logger = document.getElementById('log');
logger.innerHTML += message + '<br>';
}
</script>
</body>

2
go.mod
View file

@ -56,7 +56,7 @@ require (
github.com/sftpgo/sdk v0.1.6-0.20231011150824-e8d35102c725
github.com/shirou/gopsutil/v3 v3.23.10
github.com/spf13/afero v1.10.0
github.com/spf13/cobra v1.7.0
github.com/spf13/cobra v1.8.0
github.com/spf13/viper v1.17.0
github.com/stretchr/testify v1.8.4
github.com/studio-b12/gowebdav v0.9.0

5
go.sum
View file

@ -140,7 +140,6 @@ github.com/coreos/go-oidc/v3 v3.7.0 h1:FTdj0uexT4diYIPlF4yoFVI5MRO1r5+SEcIpEw9vC
github.com/coreos/go-oidc/v3 v3.7.0/go.mod h1:yQzSCqBnK3e6Fs5l+f5i0F8Kwf0zpH9bPEsbY00KanM=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -460,8 +459,8 @@ github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY=
github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI=

View file

@ -118,7 +118,6 @@ var (
ClientIPHeaderDepth: 0,
HideLoginURL: 0,
RenderOpenAPI: true,
WebClientIntegrations: nil,
OIDC: httpd.OIDC{
ClientID: "",
ClientSecret: "",
@ -1707,44 +1706,6 @@ func getHTTPDBrandingFromEnv(idx int) (httpd.Branding, bool) {
return result, isSet
}
func getHTTPDWebClientIntegrationsFromEnv(idx int) []httpd.WebClientIntegration {
var integrations []httpd.WebClientIntegration
if len(globalConf.HTTPDConfig.Bindings) > idx {
integrations = globalConf.HTTPDConfig.Bindings[idx].WebClientIntegrations
}
for subIdx := 0; subIdx < 10; subIdx++ {
var integration httpd.WebClientIntegration
var replace bool
if len(globalConf.HTTPDConfig.Bindings) > idx &&
len(globalConf.HTTPDConfig.Bindings[idx].WebClientIntegrations) > subIdx {
integration = integrations[subIdx]
replace = true
}
url, ok := os.LookupEnv(fmt.Sprintf("SFTPGO_HTTPD__BINDINGS__%v__WEB_CLIENT_INTEGRATIONS__%v__URL", idx, subIdx))
if ok {
integration.URL = url
}
extensions, ok := lookupStringListFromEnv(fmt.Sprintf("SFTPGO_HTTPD__BINDINGS__%v__WEB_CLIENT_INTEGRATIONS__%v__FILE_EXTENSIONS",
idx, subIdx))
if ok {
integration.FileExtensions = extensions
}
if integration.URL != "" && len(integration.FileExtensions) > 0 {
if replace {
integrations[subIdx] = integration
} else {
integrations = append(integrations, integration)
}
}
}
return integrations
}
func getDefaultHTTPBinding(idx int) httpd.Binding {
binding := defaultHTTPDBinding
if len(globalConf.HTTPDConfig.Bindings) > idx {
@ -1756,12 +1717,6 @@ func getDefaultHTTPBinding(idx int) httpd.Binding {
func getHTTPDNestedObjectsFromEnv(idx int, binding *httpd.Binding) bool {
isSet := false
webClientIntegrations := getHTTPDWebClientIntegrationsFromEnv(idx)
if len(webClientIntegrations) > 0 {
binding.WebClientIntegrations = webClientIntegrations
isSet = true
}
oidc, ok := getHTTPDOIDCFromEnv(idx)
if ok {
binding.OIDC = oidc

View file

@ -613,8 +613,6 @@ func TestHTTPDSubObjectsFromEnv(t *testing.T) {
os.Setenv("SFTPGO_HTTPD__BINDINGS__0__SECURITY__HTTPS_PROXY_HEADERS__0__KEY", "X-Forwarded-Proto")
os.Setenv("SFTPGO_HTTPD__BINDINGS__0__SECURITY__HTTPS_PROXY_HEADERS__0__VALUE", "https")
os.Setenv("SFTPGO_HTTPD__BINDINGS__0__WEB_CLIENT_INTEGRATIONS__0__URL", "http://127.0.0.1/")
os.Setenv("SFTPGO_HTTPD__BINDINGS__0__WEB_CLIENT_INTEGRATIONS__0__FILE_EXTENSIONS", ".pdf, .txt")
os.Setenv("SFTPGO_HTTPD__BINDINGS__0__OIDC__CLIENT_ID", "client_id")
os.Setenv("SFTPGO_HTTPD__BINDINGS__0__OIDC__CLIENT_SECRET", "client_secret")
os.Setenv("SFTPGO_HTTPD__BINDINGS__0__OIDC__CONFIG_URL", "config_url")
@ -623,8 +621,6 @@ func TestHTTPDSubObjectsFromEnv(t *testing.T) {
cleanup := func() {
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__0__SECURITY__HTTPS_PROXY_HEADERS__0__KEY")
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__0__SECURITY__HTTPS_PROXY_HEADERS__0__VALUE")
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__0__WEB_CLIENT_INTEGRATIONS__0__URL")
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__0__WEB_CLIENT_INTEGRATIONS__0__FILE_EXTENSIONS")
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__0__OIDC__CLIENT_ID")
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__0__OIDC__CLIENT_SECRET")
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__0__OIDC__CONFIG_URL")
@ -638,7 +634,6 @@ func TestHTTPDSubObjectsFromEnv(t *testing.T) {
httpdConf := config.GetHTTPDConfig()
require.Len(t, httpdConf.Bindings, 1)
require.Len(t, httpdConf.Bindings[0].Security.HTTPSProxyHeaders, 1)
require.Len(t, httpdConf.Bindings[0].WebClientIntegrations, 1)
require.Equal(t, "client_id", httpdConf.Bindings[0].OIDC.ClientID)
require.Equal(t, "client_secret", httpdConf.Bindings[0].OIDC.ClientSecret)
require.Equal(t, "config_url", httpdConf.Bindings[0].OIDC.ConfigURL)
@ -656,7 +651,6 @@ func TestHTTPDSubObjectsFromEnv(t *testing.T) {
assert.NoError(t, err)
os.Setenv("SFTPGO_HTTPD__BINDINGS__0__SECURITY__HTTPS_PROXY_HEADERS__0__VALUE", "http")
os.Setenv("SFTPGO_HTTPD__BINDINGS__0__WEB_CLIENT_INTEGRATIONS__0__URL", "http://127.0.1.1/")
os.Setenv("SFTPGO_HTTPD__BINDINGS__0__OIDC__CLIENT_SECRET", "new_client_secret")
err = config.LoadConfig(configDir, confName)
assert.NoError(t, err)
@ -664,8 +658,6 @@ func TestHTTPDSubObjectsFromEnv(t *testing.T) {
require.Len(t, httpdConf.Bindings, 1)
require.Len(t, httpdConf.Bindings[0].Security.HTTPSProxyHeaders, 1)
require.Equal(t, "http", httpdConf.Bindings[0].Security.HTTPSProxyHeaders[0].Value)
require.Len(t, httpdConf.Bindings[0].WebClientIntegrations, 1)
require.Equal(t, "http://127.0.1.1/", httpdConf.Bindings[0].WebClientIntegrations[0].URL)
require.Equal(t, "client_id", httpdConf.Bindings[0].OIDC.ClientID)
require.Equal(t, "new_client_secret", httpdConf.Bindings[0].OIDC.ClientSecret)
require.Equal(t, "config_url", httpdConf.Bindings[0].OIDC.ConfigURL)
@ -1216,10 +1208,6 @@ func TestHTTPDBindingsFromEnv(t *testing.T) {
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__CLIENT_IP_PROXY_HEADER", "X-Real-IP")
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__CLIENT_IP_HEADER_DEPTH", "2")
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__HIDE_LOGIN_URL", "3")
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__WEB_CLIENT_INTEGRATIONS__1__URL", "http://127.0.0.1/")
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__WEB_CLIENT_INTEGRATIONS__1__FILE_EXTENSIONS", ".pdf, .txt")
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__WEB_CLIENT_INTEGRATIONS__2__URL", "http://127.0.1.1/")
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__WEB_CLIENT_INTEGRATIONS__3__FILE_EXTENSIONS", ".jpg, .txt")
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__OIDC__CLIENT_ID", "client id")
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__OIDC__CLIENT_SECRET", "client secret")
os.Setenv("SFTPGO_HTTPD__BINDINGS__2__OIDC__CONFIG_URL", "config url")
@ -1286,10 +1274,6 @@ func TestHTTPDBindingsFromEnv(t *testing.T) {
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__CLIENT_IP_PROXY_HEADER")
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__CLIENT_IP_HEADER_DEPTH")
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__HIDE_LOGIN_URL")
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__WEB_CLIENT_INTEGRATIONS__1__URL")
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__WEB_CLIENT_INTEGRATIONS__1__FILE_EXTENSIONS")
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__WEB_CLIENT_INTEGRATIONS__2__URL")
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__WEB_CLIENT_INTEGRATIONS__3__FILE_EXTENSIONS")
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__OIDC__CLIENT_ID")
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__OIDC__CLIENT_SECRET")
os.Unsetenv("SFTPGO_HTTPD__BINDINGS__2__OIDC__CONFIG_URL")
@ -1394,9 +1378,6 @@ func TestHTTPDBindingsFromEnv(t *testing.T) {
require.Equal(t, "X-Real-IP", bindings[2].ClientIPProxyHeader)
require.Equal(t, 2, bindings[2].ClientIPHeaderDepth)
require.Equal(t, 3, bindings[2].HideLoginURL)
require.Len(t, bindings[2].WebClientIntegrations, 1)
require.Equal(t, "http://127.0.0.1/", bindings[2].WebClientIntegrations[0].URL)
require.Equal(t, []string{".pdf", ".txt"}, bindings[2].WebClientIntegrations[0].FileExtensions)
require.Equal(t, "client id", bindings[2].OIDC.ClientID)
require.Equal(t, "client secret", bindings[2].OIDC.ClientSecret)
require.Equal(t, "config url", bindings[2].OIDC.ConfigURL)

View file

@ -524,9 +524,6 @@ type Binding struct {
HideLoginURL int `json:"hide_login_url" mapstructure:"hide_login_url"`
// Enable the built-in OpenAPI renderer
RenderOpenAPI bool `json:"render_openapi" mapstructure:"render_openapi"`
// Enabling web client integrations you can render or modify the files with the specified
// extensions using an external tool.
WebClientIntegrations []WebClientIntegration `json:"web_client_integrations" mapstructure:"web_client_integrations"`
// Defining an OIDC configuration the web admin and web client UI will use OpenID to authenticate users.
OIDC OIDC `json:"oidc" mapstructure:"oidc"`
// Security defines security headers to add to HTTP responses and allows to restrict allowed hosts
@ -536,16 +533,6 @@ type Binding struct {
allowHeadersFrom []func(net.IP) bool
}
func (b *Binding) checkWebClientIntegrations() {
var integrations []WebClientIntegration
for _, integration := range b.WebClientIntegrations {
if integration.URL != "" && len(integration.FileExtensions) > 0 {
integrations = append(integrations, integration)
}
}
b.WebClientIntegrations = integrations
}
func (b *Binding) checkBranding() {
b.Branding.WebAdmin.check()
b.Branding.WebClient.check()
@ -973,7 +960,6 @@ func (c *Conf) Initialize(configDir string, isShared int) error {
if err := binding.parseAllowedProxy(); err != nil {
return err
}
binding.checkWebClientIntegrations()
binding.checkBranding()
binding.Security.updateProxyHeaders()

View file

@ -313,8 +313,6 @@ func TestMain(m *testing.M) {
os.Setenv("SFTPGO_DATA_PROVIDER__NAMING_RULES", "0")
os.Setenv("SFTPGO_DEFAULT_ADMIN_USERNAME", "admin")
os.Setenv("SFTPGO_DEFAULT_ADMIN_PASSWORD", "password")
os.Setenv("SFTPGO_HTTPD__BINDINGS__0__WEB_CLIENT_INTEGRATIONS__0__URL", "http://127.0.0.1/test.html")
os.Setenv("SFTPGO_HTTPD__BINDINGS__0__WEB_CLIENT_INTEGRATIONS__0__FILE_EXTENSIONS", ".pdf,.txt")
os.Setenv("SFTPGO_HTTPD__MAX_UPLOAD_FILE_SIZE", "1048576000")
err := config.LoadConfig(configDir, "")
if err != nil {

View file

@ -157,7 +157,6 @@ type filesPage struct {
ShareUploadBaseURL string
Error string
Paths []dirMapping
HasIntegrations bool
QuotaUsage *userQuotaUsage
}
@ -763,7 +762,6 @@ func (s *httpdServer) renderSharedFilesPage(w http.ResponseWriter, r *http.Reque
CanDelete: false,
CanDownload: share.Scope != dataprovider.ShareScopeWrite,
CanShare: false,
HasIntegrations: false,
Paths: getDirMapping(dirName, currentURL),
QuotaUsage: newUserQuotaUsage(&dataprovider.User{}),
}
@ -780,9 +778,7 @@ func (s *httpdServer) renderUploadToSharePage(w http.ResponseWriter, r *http.Req
renderClientTemplate(w, templateUploadToShare, data)
}
func (s *httpdServer) renderFilesPage(w http.ResponseWriter, r *http.Request, dirName, error string, user *dataprovider.User,
hasIntegrations bool,
) {
func (s *httpdServer) renderFilesPage(w http.ResponseWriter, r *http.Request, dirName, error string, user *dataprovider.User) {
data := filesPage{
baseClientPage: s.getBaseClientPageData(pageClientFilesTitle, webClientFilesPath, r),
Error: error,
@ -799,7 +795,6 @@ func (s *httpdServer) renderFilesPage(w http.ResponseWriter, r *http.Request, di
CanDownload: user.HasPerm(dataprovider.PermDownload, dirName),
CanShare: user.CanManageShares(),
ShareUploadBaseURL: "",
HasIntegrations: hasIntegrations,
Paths: getDirMapping(dirName, webClientFilesPath),
QuotaUsage: newUserQuotaUsage(user),
}
@ -1167,17 +1162,6 @@ func (s *httpdServer) handleClientGetDirContents(w http.ResponseWriter, r *http.
if info.Size() < httpdMaxEditFileSize {
res["edit_url"] = strings.Replace(res["url"].(string), webClientFilesPath, webClientEditFilePath, 1)
}
if len(s.binding.WebClientIntegrations) > 0 {
extension := path.Ext(info.Name())
for idx := range s.binding.WebClientIntegrations {
if util.Contains(s.binding.WebClientIntegrations[idx].FileExtensions, extension) {
res["ext_url"] = s.binding.WebClientIntegrations[idx].URL
res["ext_link"] = fmt.Sprintf("%v?path=%v&_=%v", webClientFilePath,
url.QueryEscape(path.Join(name, info.Name())), time.Now().UTC().Unix())
break
}
}
}
}
}
res["meta"] = fmt.Sprintf("%v_%v", res["type"], info.Name())
@ -1229,12 +1213,11 @@ func (s *httpdServer) handleClientGetFiles(w http.ResponseWriter, r *http.Reques
info, err = connection.Stat(name, 0)
}
if err != nil {
s.renderFilesPage(w, r, path.Dir(name), fmt.Sprintf("unable to stat file %q: %v", name, err),
&user, len(s.binding.WebClientIntegrations) > 0)
s.renderFilesPage(w, r, path.Dir(name), fmt.Sprintf("unable to stat file %q: %v", name, err), &user)
return
}
if info.IsDir() {
s.renderFilesPage(w, r, name, "", &user, len(s.binding.WebClientIntegrations) > 0)
s.renderFilesPage(w, r, name, "", &user)
return
}
if status, err := downloadFile(w, r, connection, name, info, false, nil); err != nil && status != 0 {
@ -1243,7 +1226,7 @@ func (s *httpdServer) handleClientGetFiles(w http.ResponseWriter, r *http.Reques
s.renderClientMessagePage(w, r, http.StatusText(status), "", status, err, "")
return
}
s.renderFilesPage(w, r, path.Dir(name), err.Error(), &user, len(s.binding.WebClientIntegrations) > 0)
s.renderFilesPage(w, r, path.Dir(name), err.Error(), &user)
}
}
}

View file

@ -274,7 +274,6 @@
"client_ip_header_depth": 0,
"hide_login_url": 0,
"render_openapi": true,
"web_client_integrations": [],
"oidc": {
"client_id": "",
"client_secret": "",