-
Notifications
You must be signed in to change notification settings - Fork 66
/
web_server.go
111 lines (96 loc) · 2.5 KB
/
web_server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package main
import (
"html/template"
"io/ioutil"
"net/http"
"path/filepath"
"strings"
"github.com/arrikto/oidc-authservice/common"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
)
const (
tmplLanding = "homepage.html"
tmplAfterLogout = "after_logout.html"
)
var (
ThemesPath = "/site/themes"
)
type WebServer struct {
TemplatePaths []string
// Frontend-related values for context
ProviderURL string
ClientName string
ThemeURL string
Frontend map[string]string
}
func (s *WebServer) Start(addr string) error {
// Start web server
// Load templates
filenames := []string{}
for _, p := range s.TemplatePaths {
tmpls, err := listTemplates(p)
if err != nil {
return err
}
filenames = append(filenames, tmpls...)
}
// Add functions to context
funcs := map[string]interface{}{
"resolve_url_ref": func(url, ref string) string {
return common.MustParseURL(url).ResolveReference(common.MustParseURL(ref)).String()
},
}
templates, err := template.New("").Funcs(funcs).ParseFiles(filenames...)
if err != nil {
return err
}
router := mux.NewRouter()
data := struct {
// Frontend-related values for context
Frontend map[string]string
// OIDC-related settings
ProviderURL string
ThemeURL string
ClientName string
}{
Frontend: s.Frontend,
ProviderURL: s.ProviderURL,
ThemeURL: s.ThemeURL,
ClientName: s.ClientName,
}
router.HandleFunc(common.HomepagePath, siteHandler(templates.Lookup(tmplLanding), data)).Methods(http.MethodGet)
router.HandleFunc(common.AfterLogoutPath, siteHandler(templates.Lookup(tmplAfterLogout), data)).Methods(http.MethodGet)
// Themes
router.
PathPrefix(ThemesPath).
Handler(
http.StripPrefix(
ThemesPath,
http.FileServer(http.Dir("web/themes")),
),
)
return http.ListenAndServe(addr, handlers.CORS()(router))
}
// siteHandler returns an http.HandlerFunc that serves a given template
func siteHandler(tmpl *template.Template, data interface{}) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
logger := common.RequestLogger(r, "web server")
if err := tmpl.Execute(w, data); err != nil {
logger.Errorf("Error executing template: %v", err)
}
}
}
func listTemplates(dir string) ([]string, error) {
tmplPaths := []string{}
files, err := ioutil.ReadDir(dir)
if err != nil {
return nil, err
}
for _, f := range files {
if !f.IsDir() && strings.HasSuffix(f.Name(), ".html") {
tmplPaths = append(tmplPaths, filepath.Join(dir, f.Name()))
}
}
return tmplPaths, err
}