@@ 66,39 66,29 @@ func manageClient(w http.ResponseWriter, req *http.Request) {
return
}
- client.ClientName = req.PostFormValue("client_name")
- client.ClientURI = req.PostFormValue("client_uri")
- client.RedirectURIs = req.PostFormValue("redirect_uris")
- isPublic := req.PostFormValue("client_type") == "public"
+ _, rotate := req.PostForm["rotate"]
- for _, s := range strings.Split(client.RedirectURIs, "\n") {
- if s == "" {
- continue
- }
- u, err := url.Parse(s)
- if err != nil {
+ var isPublic bool
+ if client.ID != 0 {
+ isPublic = client.IsPublic()
+ } else {
+ isPublic = req.PostFormValue("client_type") == "public"
+ }
+
+ if !rotate {
+ client.ClientName = req.PostFormValue("client_name")
+ client.ClientURI = req.PostFormValue("client_uri")
+ client.RedirectURIs = req.PostFormValue("redirect_uris")
+
+ if err := validateAllowedRedirectURIs(client.RedirectURIs); err != nil {
// TODO: nicer error message
- http.Error(w, fmt.Sprintf("Invalid redirect URI %q: %v", s, err), http.StatusBadRequest)
+ http.Error(w, err.Error(), http.StatusBadRequest)
return
}
- switch u.Scheme {
- case "https":
- // ok
- case "http":
- if u.Host != "localhost" {
- http.Error(w, "Only http://localhost is allowed for insecure HTTP URIs", http.StatusBadRequest)
- return
- }
- default:
- if !strings.Contains(u.Scheme, ".") {
- http.Error(w, "Only private-use URIs referring to domain names are allowed", http.StatusBadRequest)
- return
- }
- }
}
var clientSecret string
- if client.ID == 0 {
+ if client.ID == 0 || rotate {
clientSecret, err = client.Generate(isPublic)
if err != nil {
httpError(w, err)
@@ 128,6 118,32 @@ func manageClient(w http.ResponseWriter, req *http.Request) {
}
}
+func validateAllowedRedirectURIs(rawRedirectURIs string) error {
+ for _, s := range strings.Split(rawRedirectURIs, "\n") {
+ if s == "" {
+ continue
+ }
+ u, err := url.Parse(s)
+ if err != nil {
+ // TODO: nicer error message
+ return fmt.Errorf("Invalid redirect URI %q: %v", s, err)
+ }
+ switch u.Scheme {
+ case "https":
+ // ok
+ case "http":
+ if u.Host != "localhost" {
+ return fmt.Errorf("Only http://localhost is allowed for insecure HTTP URIs")
+ }
+ default:
+ if !strings.Contains(u.Scheme, ".") {
+ return fmt.Errorf("Only private-use URIs referring to domain names are allowed")
+ }
+ }
+ }
+ return nil
+}
+
func revokeClient(w http.ResponseWriter, req *http.Request) {
ctx := req.Context()
db := dbFromContext(ctx)
@@ 46,6 46,9 @@
{{ end }}
</button>
{{ if .Client.ID }}
+ {{ if not .Client.IsPublic }}
+ <button type="submit" name="rotate">Rotate client secret</button>
+ {{ end }}
<button type="submit" name="delete">Delete client</button>
{{ end }}
</form>