mirror of https://github.com/dexidp/dex.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
2.7 KiB
101 lines
2.7 KiB
package server |
|
|
|
import ( |
|
"log" |
|
"net/http" |
|
"text/template" |
|
|
|
"github.com/coreos/dex/storage" |
|
) |
|
|
|
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>`)) |
|
|
|
func renderApprovalTmpl(w http.ResponseWriter, state string, identity storage.Claims, client storage.Client, scopes []string) { |
|
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. |
|
} |
|
}
|
|
|