indieauth-metadata

This commit is contained in:
Niko Abeler 2022-11-07 19:44:10 +01:00
parent 9389cc0266
commit 37936a450f
5 changed files with 71 additions and 0 deletions

View File

@ -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())
}

View File

@ -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)

View File

@ -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))

View File

@ -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 }}

View File

@ -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