Skip to content
Snippets Groups Projects
templates.go 2.65 KiB
Newer Older
  • Learn to ignore specific revisions
  • Eric Chiang's avatar
    Eric Chiang committed
    package server
    
    import (
    	"log"
    	"net/http"
    	"text/template"
    
    
    Eric Chiang's avatar
    Eric Chiang committed
    	"github.com/coreos/dex/storage"
    
    Eric Chiang's avatar
    Eric Chiang committed
    )
    
    type connectorInfo struct {
    	DisplayName string
    	URL         string
    }
    
    var loginTmpl = template.Must(template.New("login-template").Parse(`<html>
    <head></head>
    <body>
    <p>Login options</p>
    {{ range $i, $connector := .Connectors }}
    <a href="{{ $connector.URL }}?state={{ $.State }}">{{ $connector.DisplayName }}</a>
    {{ end }}
    </body>
    </html>`))
    
    func renderLoginOptions(w http.ResponseWriter, connectors []connectorInfo, state string) {
    	data := struct {
    		Connectors []connectorInfo
    		State      string
    	}{connectors, state}
    	renderTemplate(w, loginTmpl, data)
    }
    
    var passwordTmpl = template.Must(template.New("password-template").Parse(`<html>
    <body>
    <p>Login</p>
    <form action="{{ .Callback }}" method="POST">
    Login: <input type="text" name="login"/><br/>
    Password: <input type="password" name="password"/><br/>
    <input type="hidden" name="state" value="{{ .State }}"/>
    <input type="submit"/>
    {{ if .Message }}
    <p>Error: {{ .Message }}</p>
    {{ end }}
    </form>
    </body>
    </html>`))
    
    func renderPasswordTmpl(w http.ResponseWriter, state, callback, message string) {
    	data := struct {
    		State    string
    		Callback string
    		Message  string
    	}{state, callback, message}
    	renderTemplate(w, passwordTmpl, data)
    }
    
    var approvalTmpl = template.Must(template.New("approval-template").Parse(`<html>
    <body>
    <p>User: {{ .User }}</p>
    <p>Client: {{ .ClientName }}</p>
    <form method="post">
    <input type="hidden" name="state" value="{{ .State }}"/>
    <input type="hidden" name="approval" value="approve">
    <button type="submit">Approve</button>
    </form>
    <form method="post">
    <input type="hidden" name="state" value="{{ .State }}"/>
    <input type="hidden" name="approval" value="reject">
    <button type="submit">Reject</button>
    </form>
    </body>
    </html>`))
    
    
    Eric Chiang's avatar
    Eric Chiang committed
    func renderApprovalTmpl(w http.ResponseWriter, state string, identity storage.Claims, client storage.Client, scopes []string) {
    
    Eric Chiang's avatar
    Eric Chiang committed
    	data := struct {
    		User       string
    		ClientName string
    		State      string
    	}{identity.Email, client.Name, state}
    	renderTemplate(w, approvalTmpl, data)
    }
    
    func renderTemplate(w http.ResponseWriter, tmpl *template.Template, data interface{}) {
    	err := tmpl.Execute(w, data)
    	if err == nil {
    		return
    	}
    
    	switch err := err.(type) {
    	case template.ExecError:
    		// An ExecError guarentees that Execute has not written to the underlying reader.
    		log.Printf("Error rendering template %s: %s", tmpl.Name(), err)
    
    		// TODO(ericchiang): replace with better internal server error.
    		http.Error(w, "Internal server error", http.StatusInternalServerError)
    	default:
    		// An error with the underlying write, such as the connection being
    		// dropped. Ignore for now.
    	}
    }