feat: custom branding

License: MIT
Signed-off-by: Henrique Dias <hacdias@gmail.com>
This commit is contained in:
Henrique Dias 2018-12-29 10:13:04 +00:00
parent c585ef92fe
commit 1e163bce84
5 changed files with 72 additions and 11 deletions

View File

@ -38,6 +38,10 @@ func addConfigFlags(cmd *cobra.Command) {
cmd.Flags().String("recaptcha.host", "https://www.google.com", "Use another host for ReCAPTCHA. recaptcha.net might be useful in China")
cmd.Flags().String("recaptcha.key", "", "ReCaptcha site key")
cmd.Flags().String("recaptcha.secret", "", "ReCaptcha secret")
cmd.Flags().String("branding.name", "", "Replace 'File Browser' by this name")
cmd.Flags().String("branding.files", "", "Path to directory with images and custom styles")
cmd.Flags().Bool("branding.disableExternal", false, "Disable external links such as GitHub links")
}
func getAuthentication(cmd *cobra.Command) (types.AuthMethod, types.Auther) {
@ -87,6 +91,10 @@ func printSettings(s *types.Settings, auther types.Auther) {
fmt.Fprintf(w, "\nBase URL:\t%s\n", s.BaseURL)
fmt.Fprintf(w, "Sign up:\t%t\n", s.Signup)
fmt.Fprintf(w, "Auth method:\t%s\n", s.AuthMethod)
fmt.Fprintln(w, "\nBranding:")
fmt.Fprintf(w, "\tName:\t%s\n", s.Branding.Name)
fmt.Fprintf(w, "\tFiles override:\t%s\n", s.Branding.Files)
fmt.Fprintf(w, "\tDisable external links:\t%t\n", s.Branding.DisableExternal)
fmt.Fprintln(w, "\nDefaults:")
fmt.Fprintf(w, "\tScope:\t%s\n", s.Defaults.Scope)
fmt.Fprintf(w, "\tLocale:\t%s\n", s.Defaults.Locale)

View File

@ -28,12 +28,19 @@ you want to change.`,
auth := false
cmd.Flags().Visit(func(flag *pflag.Flag) {
if flag.Name == "baseURL" {
switch flag.Name {
case "baseURL":
s.BaseURL = mustGetString(cmd, "baseURL")
} else if flag.Name == "signup" {
case "signup":
s.Signup = mustGetBool(cmd, "signup")
} else if flag.Name == "auth.method" {
case "auth.method":
auth = true
case "branding.name":
s.Branding.Name = mustGetString(cmd, "branding.name")
case "branding.disableExternal":
s.Branding.DisableExternal = mustGetBool(cmd, "branding.disableExternal")
case "branding.files":
s.Branding.Files = mustGetString(cmd, "branding.files")
}
})

@ -1 +1 @@
Subproject commit b9dc7e02e718b39c6b12e6946c7ce01b1b08890f
Subproject commit 82abdaf3900aae349f172cc1f5494fa5b6e72a02

View File

@ -1,7 +1,11 @@
package http
import (
"encoding/json"
"log"
"net/http"
"os"
"path/filepath"
"strings"
"text/template"
@ -16,16 +20,34 @@ func (e *Env) getStaticHandlers() (http.Handler, http.Handler) {
baseURL := strings.TrimSuffix(e.Settings.BaseURL, "/")
staticURL := strings.TrimPrefix(baseURL+"/static", "/")
cssFile := ""
// TODO: baseurl must always not have the trailing slash
data := map[string]interface{}{
"Name": e.Settings.Branding.Name,
"DisableExternal": e.Settings.Branding.DisableExternal,
"BaseURL": baseURL,
"Version": types.Version,
"StaticURL": staticURL,
"Signup": e.Settings.Signup,
"CSS": false,
"ReCaptcha": false,
}
if e.Settings.Branding.Files != "" {
path := filepath.Join(e.Settings.Branding.Files, "custom.css")
_, err := os.Stat(path)
if err != nil && !os.IsNotExist(err) {
log.Printf("couldn't load custom styles: %v", err)
}
if err == nil {
cssFile = path
data["CSS"] = true
}
}
if e.Settings.AuthMethod == auth.MethodJSONAuth {
auther := e.Auther.(*auth.JSONAuth)
@ -36,6 +58,9 @@ func (e *Env) getStaticHandlers() (http.Handler, http.Handler) {
}
}
b, _ := json.MarshalIndent(data, "", " ")
data["Json"] = string(b)
handleWithData := func(w http.ResponseWriter, r *http.Request, file string, contentType string) {
w.Header().Set("Content-Type", contentType)
index := template.Must(template.New("index").Delims("[{[", "]}]").Parse(box.MustString(file)))
@ -58,13 +83,26 @@ func (e *Env) getStaticHandlers() (http.Handler, http.Handler) {
handleWithData(w, r, "index.html", "text/html; charset=utf-8")
})
static := http.StripPrefix("/static", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
static := http.StripPrefix("/static/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if e.Settings.Branding.Files != "" {
if strings.HasPrefix(r.URL.Path, "img/") {
path := filepath.Join(e.Settings.Branding.Files, r.URL.Path)
if _, err := os.Stat(path); err == nil {
http.ServeFile(w, r, path)
return
}
} else if r.URL.Path == "custom.css" && cssFile != "" {
http.ServeFile(w, r, cssFile)
return
}
}
if !strings.HasSuffix(r.URL.Path, ".js") {
handler.ServeHTTP(w, r)
return
}
handleWithData(w, r, strings.TrimPrefix(r.URL.Path, "/"), "application/javascript; charset=utf-8")
handleWithData(w, r, r.URL.Path, "application/javascript; charset=utf-8")
}))
return index, static

View File

@ -10,6 +10,14 @@ type Settings struct {
Signup bool `json:"signup"`
Defaults UserDefaults `json:"defaults"`
AuthMethod AuthMethod `json:"authMethod"`
Branding Branding `json:"Branding"`
}
// Branding contains the branding settings of the app.
type Branding struct {
Name string `json:"name"`
DisableExternal bool `json:"disableExternal"`
Files string `json:"string"`
}
// UserDefaults is a type that holds the default values