From d458e882aa21e6937fba70fd9f2e9248babd501c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc-Andr=C3=A9=20Dufresne?=
 <marc-andre.dufresne@elementai.com>
Date: Tue, 6 Aug 2019 13:14:53 -0400
Subject: [PATCH] Allow arbitrary data to be passed to templates

---
 Documentation/templates.md | 24 ++++++++++++++++++++++++
 cmd/dex/config_test.go     | 13 +++++++++++++
 server/server.go           |  4 ++++
 server/templates.go        |  2 ++
 4 files changed, 43 insertions(+)
 create mode 100644 Documentation/templates.md

diff --git a/Documentation/templates.md b/Documentation/templates.md
new file mode 100644
index 00000000..7906363b
--- /dev/null
+++ b/Documentation/templates.md
@@ -0,0 +1,24 @@
+# Templates
+
+## Using your own templates
+
+Dex supports using your own templates and passing arbitrary data to them to help customize your installation.
+
+Steps:
+
+1. Copy contents of the `web` directory over to a new directory.
+2. Customize the templates as needed, be sure to retain all the existing variables so Dex continues working correctly.
+  a. Use this syntax `{{ "your_key" | extra }}` to use values from `frontend.extra`.
+3. Write a theme for your templates in the `themes` directory.
+4. Add your custom data to the Dex configuration `frontend.extra`.
+   ```yaml
+   frontend:
+     dir: /path/to/custom/web
+     extra:
+       tos_footer_link: "https://example.com/terms"
+       client_logo_url: "../theme/client-logo.png"
+       foo: "bar"
+   ```
+5. Set the `frontend.dir` value to your own `web` directory.
+
+To test your templates simply run Dex with a valid configuration and go through a login flow.
\ No newline at end of file
diff --git a/cmd/dex/config_test.go b/cmd/dex/config_test.go
index 06a8e429..1e5697bf 100644
--- a/cmd/dex/config_test.go
+++ b/cmd/dex/config_test.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"github.com/dexidp/dex/server"
 	"testing"
 
 	"github.com/ghodss/yaml"
@@ -69,6 +70,12 @@ storage:
     connectionTimeout: 3
 web:
   http: 127.0.0.1:5556
+
+frontend:
+  dir: ./web
+  extra:
+    foo: bar
+
 staticClients:
 - id: example-app
   redirectURIs:
@@ -130,6 +137,12 @@ logger:
 		Web: Web{
 			HTTP: "127.0.0.1:5556",
 		},
+		Frontend: server.WebConfig{
+			Dir: "./web",
+			Extra: map[string]string{
+				"foo": "bar",
+			},
+		},
 		StaticClients: []storage.Client{
 			{
 				ID:     "example-app",
diff --git a/server/server.go b/server/server.go
index e1258151..aa1352c1 100644
--- a/server/server.go
+++ b/server/server.go
@@ -107,6 +107,9 @@ type WebConfig struct {
 
 	// Defaults to "coreos"
 	Theme string
+
+	// Map of extra values passed into the templates
+	Extra map[string]string
 }
 
 func value(val, defaultValue time.Duration) time.Duration {
@@ -181,6 +184,7 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy)
 		issuerURL: c.Issuer,
 		issuer:    c.Web.Issuer,
 		theme:     c.Web.Theme,
+		extra:     c.Web.Extra,
 	}
 
 	static, theme, tmpls, err := loadWebConfig(web)
diff --git a/server/templates.go b/server/templates.go
index ab9e5802..89d41371 100644
--- a/server/templates.go
+++ b/server/templates.go
@@ -42,6 +42,7 @@ type webConfig struct {
 	issuer    string
 	theme     string
 	issuerURL string
+	extra     map[string]string
 }
 
 func join(base, path string) string {
@@ -140,6 +141,7 @@ func loadTemplates(c webConfig, templatesDir string) (*templates, error) {
 		"logo":   func() string { return c.logoURL },
 		"url":    func(s string) string { return join(c.issuerURL, s) },
 		"lower":  strings.ToLower,
+		"extra":  func(k string) string { return c.extra[k] },
 	}
 
 	tmpls, err := template.New("").Funcs(funcs).ParseFiles(filenames...)
-- 
GitLab