IndieAuth #25
|
@ -399,3 +399,29 @@ func TestAccessTokenWithIncorrectCode(t *testing.T) {
|
||||||
|
|
||||||
assertions.AssertStatus(t, rr, http.StatusUnauthorized)
|
assertions.AssertStatus(t, rr, http.StatusUnauthorized)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIndieauthMetadata(t *testing.T) {
|
||||||
|
repo, user := getSingleUserTestRepo()
|
||||||
|
user.ResetPassword("testpassword")
|
||||||
|
req, _ := http.NewRequest("GET", user.IndieauthMetadataUrl(), nil)
|
||||||
|
rr := httptest.NewRecorder()
|
||||||
|
router := main.SingleUserRouter(&repo)
|
||||||
|
router.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
assertions.AssertStatus(t, rr, http.StatusOK)
|
||||||
|
// parse response as json
|
||||||
|
type responseType struct {
|
||||||
|
Issuer string `json:"issuer"`
|
||||||
|
AuthorizationEndpoint string `json:"authorization_endpoint"`
|
||||||
|
TokenEndpoint string `json:"token_endpoint"`
|
||||||
|
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"`
|
||||||
|
ScopesSupported []string `json:"scopes_supported"`
|
||||||
|
ResponseTypesSupported []string `json:"response_types_supported"`
|
||||||
|
GrantTypesSupported []string `json:"grant_types_supported"`
|
||||||
|
}
|
||||||
|
var response responseType
|
||||||
|
json.Unmarshal(rr.Body.Bytes(), &response)
|
||||||
|
assertions.AssertEqual(t, response.Issuer, user.FullUrl())
|
||||||
|
assertions.AssertEqual(t, response.AuthorizationEndpoint, user.AuthUrl())
|
||||||
|
assertions.AssertEqual(t, response.TokenEndpoint, user.TokenUrl())
|
||||||
|
}
|
||||||
|
|
|
@ -60,6 +60,43 @@ func userIndexHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Requ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func userAuthMetadataHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Request, httprouter.Params) {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||||
|
user, err := getUserFromRepo(repo, ps)
|
||||||
|
if err != nil {
|
||||||
|
println("Error getting user: ", err.Error())
|
||||||
|
notFoundHandler(repo)(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type Response struct {
|
||||||
|
Issuer string `json:"issuer"`
|
||||||
|
AuthorizationEndpoint string `json:"authorization_endpoint"`
|
||||||
|
TokenEndpoint string `json:"token_endpoint"`
|
||||||
|
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"`
|
||||||
|
ScopesSupported []string `json:"scopes_supported"`
|
||||||
|
ResponseTypesSupported []string `json:"response_types_supported"`
|
||||||
|
GrantTypesSupported []string `json:"grant_types_supported"`
|
||||||
|
}
|
||||||
|
response := Response{
|
||||||
|
Issuer: user.FullUrl(),
|
||||||
|
AuthorizationEndpoint: user.AuthUrl(),
|
||||||
|
TokenEndpoint: user.TokenUrl(),
|
||||||
|
CodeChallengeMethodsSupported: []string{"S256", "plain"},
|
||||||
|
ScopesSupported: []string{"profile"},
|
||||||
|
ResponseTypesSupported: []string{"code"},
|
||||||
|
GrantTypesSupported: []string{"authorization_code"},
|
||||||
|
}
|
||||||
|
jsonData, err := json.Marshal(response)
|
||||||
|
if err != nil {
|
||||||
|
println("Error marshalling json: ", err.Error())
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
w.Write([]byte("Internal server error"))
|
||||||
|
}
|
||||||
|
w.Write(jsonData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func userAuthHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Request, httprouter.Params) {
|
func userAuthHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Request, httprouter.Params) {
|
||||||
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||||
user, err := getUserFromRepo(repo, ps)
|
user, err := getUserFromRepo(repo, ps)
|
||||||
|
|
|
@ -18,6 +18,7 @@ func Router(repo *owl.Repository) http.Handler {
|
||||||
router.POST("/user/:user/auth/", userAuthProfileHandler(repo))
|
router.POST("/user/:user/auth/", userAuthProfileHandler(repo))
|
||||||
router.POST("/user/:user/auth/verify/", userAuthVerifyHandler(repo))
|
router.POST("/user/:user/auth/verify/", userAuthVerifyHandler(repo))
|
||||||
router.POST("/user/:user/auth/token/", userAuthTokenHandler(repo))
|
router.POST("/user/:user/auth/token/", userAuthTokenHandler(repo))
|
||||||
|
router.GET("/user/:user/auth/indieauth-metadata", userAuthMetadataHandler(repo))
|
||||||
router.GET("/user/:user/media/*filepath", userMediaHandler(repo))
|
router.GET("/user/:user/media/*filepath", userMediaHandler(repo))
|
||||||
router.GET("/user/:user/index.xml", userRSSHandler(repo))
|
router.GET("/user/:user/index.xml", userRSSHandler(repo))
|
||||||
router.GET("/user/:user/posts/:post/", postHandler(repo))
|
router.GET("/user/:user/posts/:post/", postHandler(repo))
|
||||||
|
@ -35,6 +36,7 @@ func SingleUserRouter(repo *owl.Repository) http.Handler {
|
||||||
router.POST("/auth/", userAuthProfileHandler(repo))
|
router.POST("/auth/", userAuthProfileHandler(repo))
|
||||||
router.POST("/auth/verify/", userAuthVerifyHandler(repo))
|
router.POST("/auth/verify/", userAuthVerifyHandler(repo))
|
||||||
router.POST("/auth/token/", userAuthTokenHandler(repo))
|
router.POST("/auth/token/", userAuthTokenHandler(repo))
|
||||||
|
router.GET("/auth/indieauth-metadata", userAuthMetadataHandler(repo))
|
||||||
router.GET("/media/*filepath", userMediaHandler(repo))
|
router.GET("/media/*filepath", userMediaHandler(repo))
|
||||||
router.GET("/index.xml", userRSSHandler(repo))
|
router.GET("/index.xml", userRSSHandler(repo))
|
||||||
router.GET("/posts/:post/", postHandler(repo))
|
router.GET("/posts/:post/", postHandler(repo))
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
<link rel="stylesheet" href="/static/pico.min.css">
|
<link rel="stylesheet" href="/static/pico.min.css">
|
||||||
<link rel="webmention" href="{{ .User.WebmentionUrl }}">
|
<link rel="webmention" href="{{ .User.WebmentionUrl }}">
|
||||||
{{ if .User.AuthUrl }}
|
{{ if .User.AuthUrl }}
|
||||||
|
<link rel="indieauth-metadata" href="{{ .User.IndieauthMetadataUrl }}">
|
||||||
<link rel="authorization_endpoint" href="{{ .User.AuthUrl}}">
|
<link rel="authorization_endpoint" href="{{ .User.AuthUrl}}">
|
||||||
<link rel="token_endpoint" href="{{ .User.TokenUrl}}">
|
<link rel="token_endpoint" href="{{ .User.TokenUrl}}">
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
5
user.go
5
user.go
|
@ -78,6 +78,11 @@ func (user User) TokenUrl() string {
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (user User) IndieauthMetadataUrl() string {
|
||||||
|
url, _ := url.JoinPath(user.AuthUrl(), "indieauth-metadata")
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
func (user User) WebmentionUrl() string {
|
func (user User) WebmentionUrl() string {
|
||||||
url, _ := url.JoinPath(user.FullUrl(), "webmention/")
|
url, _ := url.JoinPath(user.FullUrl(), "webmention/")
|
||||||
return url
|
return url
|
||||||
|
|
Loading…
Reference in New Issue