tavern/web/handler_wellknown.go

107 lines
2.6 KiB
Go

package web
import (
"fmt"
"net/http"
"strings"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"github.com/ngerakines/tavern/errors"
"github.com/ngerakines/tavern/g"
"github.com/ngerakines/tavern/storage"
)
func (h handler) nodeInfo(c *gin.Context) {
c.JSON(http.StatusOK, map[string]interface{}{
"links": []interface{}{
map[string]interface{}{
"rel": "http://nodeinfo.diaspora.software/ns/schema/2.0",
"href": fmt.Sprintf("https://%s/nodeinfo/2.0", h.domain),
},
},
})
}
func (h handler) nodeInfoDetails(c *gin.Context) {
c.JSON(http.StatusOK, map[string]interface{}{
"version": "2.0",
"software": map[string]interface{}{
"name": "tavern",
"version": g.Version(),
},
"protocols": []string{"activitypub"},
"usage": map[string]interface{}{
"users": map[string]interface{}{
"total": 1,
"activeMonth": 1,
"activeHalfyear": 1,
},
"localPosts": 1,
},
"openRegistrations": false,
})
}
func (h handler) webFinger(c *gin.Context) {
username, domain, err := fingerUserDomain(c.Query("resource"), h.domain)
if err != nil {
h.logger.Error("error parsing resource", zap.Error(err))
c.AbortWithStatus(http.StatusNotFound)
return
}
h.logger.Info("webfinger request", zap.String("resource", c.Query("resource")))
user, err := h.storage.GetUserByName(c.Request.Context(), username)
if err != nil {
// TODO: Handle not found
h.logger.Error("error getting user", zap.Error(err))
c.AbortWithStatus(http.StatusInternalServerError)
return
}
j := storage.EmptyPayload()
j["subject"] = fmt.Sprintf("acct:%s@%s", user.Name, domain)
j["aliases"] = []string{
fmt.Sprintf("https://%s/users/%s", domain, user.Name),
}
l := storage.EmptyPayload()
l["rel"] = "self"
l["type"] = `application/activity+json`
l["href"] = fmt.Sprintf("https://%s/users/%s", domain, user.Name)
j["links"] = []storage.Payload{l}
h.WriteJRD(c, j)
}
func fingerUserDomain(input, domain string) (string, string, error) {
input = strings.TrimPrefix(input, "acct:")
domainPrefix := fmt.Sprintf("https://%s/users/", domain)
if strings.HasPrefix(input, domainPrefix) {
user := strings.TrimPrefix(input, domainPrefix)
return user, domain, nil
}
if input == fmt.Sprintf("https://%s/users/%s") {
}
parts := strings.FieldsFunc(input, func(r rune) bool {
return r == '@'
})
if len(parts) != 2 {
return "", "", errors.New("malformed resource parameter")
}
if parts[1] != domain {
return "", "", errors.New("malformed resource parameter")
}
user := strings.TrimSpace(parts[0])
if len(user) == 0 {
return "", "", errors.New("malformed resource parameter")
}
return user, domain, nil
}