Simplify handling of Indieauth
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Peter Stuifzand 2019-08-06 21:27:40 +02:00
parent ef2daea15b
commit ab673a0f2d
Signed by: peter
GPG Key ID: 374322D56E5209E8
2 changed files with 63 additions and 19 deletions

View File

@ -491,25 +491,12 @@ func (h *mainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// redirect to endpoint // redirect to endpoint
me := r.Form.Get("url") me := r.Form.Get("url")
log.Println(me)
meURL, err := url.Parse(me) endpoints, err := getEndpoints(me)
if err != nil { if err != nil {
http.Error(w, fmt.Sprintf("Bad Request: %s, %s", err.Error(), me), 400) http.Error(w, fmt.Sprintf("Bad Request: %s, %s", err.Error(), me), 400)
return return
} }
endpoints, err := indieauth.GetEndpoints(meURL)
if err != nil {
http.Error(w, fmt.Sprintf("Bad Request: %s %s", err.Error(), me), 400)
return
}
log.Println(endpoints)
authURL, err := url.Parse(endpoints.AuthorizationEndpoint)
if err != nil {
http.Error(w, fmt.Sprintf("Bad Request: %s %s", err.Error(), me), 400)
return
}
log.Println(authURL)
state := util.RandStringBytes(16) state := util.RandStringBytes(16)
redirectURI := fmt.Sprintf("%s/session/callback", h.BaseURL) redirectURI := fmt.Sprintf("%s/session/callback", h.BaseURL)
@ -521,8 +508,8 @@ func (h *mainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return return
} }
sess.AuthorizationEndpoint = endpoints.AuthorizationEndpoint sess.AuthorizationEndpoint = endpoints.AuthorizationEndpoint.String()
sess.Me = meURL.String() sess.Me = endpoints.Me.String()
sess.State = state sess.State = state
sess.RedirectURI = redirectURI sess.RedirectURI = redirectURI
sess.LoggedIn = false sess.LoggedIn = false
@ -533,7 +520,7 @@ func (h *mainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return return
} }
authenticationURL := indieauth.CreateAuthenticationURL(*authURL, meURL.String(), ClientID, redirectURI, state) authenticationURL := indieauth.CreateAuthenticationURL(*endpoints.AuthorizationEndpoint, endpoints.Me.String(), ClientID, redirectURI, state)
http.Redirect(w, r, authenticationURL, 302) http.Redirect(w, r, authenticationURL, 302)
return return
@ -682,3 +669,52 @@ func httpSessionLogout(r *http.Request, w http.ResponseWriter, conn redis.Conn)
} }
http.Redirect(w, r, "/", 302) http.Redirect(w, r, "/", 302)
} }
type parsedEndpoints struct {
Me *url.URL
AuthorizationEndpoint *url.URL
TokenEndpoint *url.URL
MicrosubEndpoint *url.URL
MicropubEndpoint *url.URL
}
func getEndpoints(me string) (parsedEndpoints, error) {
endpoints := parsedEndpoints{}
meURL, err := url.Parse(me)
if err != nil {
return endpoints, err
}
endpoints.Me = meURL
eps, err := indieauth.GetEndpoints(meURL)
if err != nil {
return endpoints, err
}
authURL, err := url.Parse(eps.AuthorizationEndpoint)
if err != nil {
return endpoints, err
}
endpoints.AuthorizationEndpoint = authURL
tokenURL, err := url.Parse(eps.TokenEndpoint)
if err != nil {
return endpoints, err
}
endpoints.TokenEndpoint = tokenURL
microsubEndpoint, err := url.Parse(eps.MicrosubEndpoint)
if err != nil {
return endpoints, err
}
endpoints.MicrosubEndpoint = microsubEndpoint
micropubEndpoint, err := url.Parse(eps.MicropubEndpoint)
if err != nil {
return endpoints, err
}
endpoints.MicropubEndpoint = micropubEndpoint
return endpoints, err
}

View File

@ -17,13 +17,16 @@ import (
"willnorris.com/go/microformats" "willnorris.com/go/microformats"
) )
// Endpoints contain the endpoints used by Ekster
type Endpoints struct { type Endpoints struct {
Me string `json:"me"`
AuthorizationEndpoint string `json:"authorization_endpoint"` AuthorizationEndpoint string `json:"authorization_endpoint"`
TokenEndpoint string `json:"token_endpoint"` TokenEndpoint string `json:"token_endpoint"`
MicropubEndpoint string `json:"micropub_endpoint"` MicropubEndpoint string `json:"micropub_endpoint"`
MicrosubEndpoint string `json:"microsub_endpoint"` MicrosubEndpoint string `json:"microsub_endpoint"`
} }
// TokenResponse contains the response from a token request to an IndieAuth server
type TokenResponse struct { type TokenResponse struct {
Me string `json:"me"` Me string `json:"me"`
AccessToken string `json:"access_token"` AccessToken string `json:"access_token"`
@ -33,8 +36,10 @@ type TokenResponse struct {
ErrorDescription string `json:"error_description"` ErrorDescription string `json:"error_description"`
} }
// GetEndpoints returns the endpoints for the me url
func GetEndpoints(me *url.URL) (Endpoints, error) { func GetEndpoints(me *url.URL) (Endpoints, error) {
var endpoints Endpoints var endpoints Endpoints
endpoints.Me = me.String()
baseURL := me baseURL := me
@ -89,6 +94,7 @@ func GetEndpoints(me *url.URL) (Endpoints, error) {
return endpoints, nil return endpoints, nil
} }
// Authorize allows you to get the token from Indieauth through the command line
func Authorize(me *url.URL, endpoints Endpoints, clientID, scope string) (TokenResponse, error) { func Authorize(me *url.URL, endpoints Endpoints, clientID, scope string) (TokenResponse, error) {
var tokenResponse TokenResponse var tokenResponse TokenResponse
@ -188,7 +194,7 @@ func Authorize(me *url.URL, endpoints Endpoints, clientID, scope string) (TokenR
values, err := url.ParseQuery(string(body)) values, err := url.ParseQuery(string(body))
if err != nil { if err != nil {
return tokenResponse, fmt.Errorf("error while parsing response body with content-type %s as application/x-www-form-urlencoded: %s\nbody was: %q\n", res.Header.Get("content-type"), err, body) return tokenResponse, fmt.Errorf("error while parsing response body with content-type %s as application/x-www-form-urlencoded: %s; body was: %q", res.Header.Get("content-type"), err, body)
} }
if values.Get("me") == "" { if values.Get("me") == "" {
@ -205,6 +211,7 @@ func Authorize(me *url.URL, endpoints Endpoints, clientID, scope string) (TokenR
return tokenResponse, nil return tokenResponse, nil
} }
// CreateAuthenticationURL builds the url for authentication
func CreateAuthenticationURL(authURL url.URL, meURL, clientID, redirectURI, state string) string { func CreateAuthenticationURL(authURL url.URL, meURL, clientID, redirectURI, state string) string {
q := authURL.Query() q := authURL.Query()
@ -219,6 +226,7 @@ func CreateAuthenticationURL(authURL url.URL, meURL, clientID, redirectURI, stat
return authURL.String() return authURL.String()
} }
// CreateAuthorizationURL builds the url for authorization
func CreateAuthorizationURL(authURL url.URL, meURL, clientID, redirectURI, state, scope string) string { func CreateAuthorizationURL(authURL url.URL, meURL, clientID, redirectURI, state, scope string) string {
q := authURL.Query() q := authURL.Query()
q.Add("response_type", "code") q.Add("response_type", "code")