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.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.key", "", "ReCaptcha site key")
cmd.Flags().String("recaptcha.secret", "", "ReCaptcha secret") 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) { 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, "\nBase URL:\t%s\n", s.BaseURL)
fmt.Fprintf(w, "Sign up:\t%t\n", s.Signup) fmt.Fprintf(w, "Sign up:\t%t\n", s.Signup)
fmt.Fprintf(w, "Auth method:\t%s\n", s.AuthMethod) 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.Fprintln(w, "\nDefaults:")
fmt.Fprintf(w, "\tScope:\t%s\n", s.Defaults.Scope) fmt.Fprintf(w, "\tScope:\t%s\n", s.Defaults.Scope)
fmt.Fprintf(w, "\tLocale:\t%s\n", s.Defaults.Locale) fmt.Fprintf(w, "\tLocale:\t%s\n", s.Defaults.Locale)

View File

@ -28,12 +28,19 @@ you want to change.`,
auth := false auth := false
cmd.Flags().Visit(func(flag *pflag.Flag) { cmd.Flags().Visit(func(flag *pflag.Flag) {
if flag.Name == "baseURL" { switch flag.Name {
case "baseURL":
s.BaseURL = mustGetString(cmd, "baseURL") s.BaseURL = mustGetString(cmd, "baseURL")
} else if flag.Name == "signup" { case "signup":
s.Signup = mustGetBool(cmd, "signup") s.Signup = mustGetBool(cmd, "signup")
} else if flag.Name == "auth.method" { case "auth.method":
auth = true 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 package http
import ( import (
"encoding/json"
"log"
"net/http" "net/http"
"os"
"path/filepath"
"strings" "strings"
"text/template" "text/template"
@ -16,14 +20,32 @@ func (e *Env) getStaticHandlers() (http.Handler, http.Handler) {
baseURL := strings.TrimSuffix(e.Settings.BaseURL, "/") baseURL := strings.TrimSuffix(e.Settings.BaseURL, "/")
staticURL := strings.TrimPrefix(baseURL+"/static", "/") staticURL := strings.TrimPrefix(baseURL+"/static", "/")
cssFile := ""
// TODO: baseurl must always not have the trailing slash // TODO: baseurl must always not have the trailing slash
data := map[string]interface{}{ data := map[string]interface{}{
"BaseURL": baseURL, "Name": e.Settings.Branding.Name,
"Version": types.Version, "DisableExternal": e.Settings.Branding.DisableExternal,
"StaticURL": staticURL, "BaseURL": baseURL,
"Signup": e.Settings.Signup, "Version": types.Version,
"ReCaptcha": false, "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 { if e.Settings.AuthMethod == auth.MethodJSONAuth {
@ -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) { handleWithData := func(w http.ResponseWriter, r *http.Request, file string, contentType string) {
w.Header().Set("Content-Type", contentType) w.Header().Set("Content-Type", contentType)
index := template.Must(template.New("index").Delims("[{[", "]}]").Parse(box.MustString(file))) 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") 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") { if !strings.HasSuffix(r.URL.Path, ".js") {
handler.ServeHTTP(w, r) handler.ServeHTTP(w, r)
return 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 return index, static

View File

@ -10,6 +10,14 @@ type Settings struct {
Signup bool `json:"signup"` Signup bool `json:"signup"`
Defaults UserDefaults `json:"defaults"` Defaults UserDefaults `json:"defaults"`
AuthMethod AuthMethod `json:"authMethod"` 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 // UserDefaults is a type that holds the default values