116 lines
3.1 KiB
Go
116 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/x509"
|
|
"encoding/json"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
func hostMetaHandler(w http.ResponseWriter, r *http.Request) {
|
|
headers := w.Header()
|
|
headers.Add("Content-Type", "application/xrd+xml")
|
|
headers.Add("Content-Type", "charset=utf-8")
|
|
fmt.Fprintf(w, `<?xml version="1.0" encoding="UTF-8"?><XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"><Link rel="lrdd" template="https://%s/.well-known/webfinger?resource={uri}" type="application/xrd+xml" /></XRD>`, host)
|
|
}
|
|
|
|
func handlerUserPage(w http.ResponseWriter, r *http.Request) {
|
|
parts := strings.SplitN(strings.Trim(r.URL.Path, " /"), "/", 2)
|
|
if len(parts) < 2 {
|
|
http.Error(w, "page not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
name := parts[1]
|
|
app, ok := apps[name]
|
|
if !ok {
|
|
http.Error(w, "page not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
userURL := fmt.Sprintf("%s/u/%s", fullhost, name)
|
|
|
|
contextes := []string{
|
|
"https://www.w3.org/ns/activitystreams",
|
|
}
|
|
|
|
var pubkey *pubKeyBlock = nil
|
|
if app.PublicKey != nil {
|
|
pubKeyBytes := x509.MarshalPKCS1PublicKey(app.PublicKey)
|
|
pubKeyPem := string(pem.EncodeToMemory(&pem.Block{
|
|
Type: "PUBLIC KEY",
|
|
Bytes: pubKeyBytes,
|
|
}))
|
|
contextes = append(contextes, "https://w3id.org/security/v1")
|
|
pubkey = &pubKeyBlock{
|
|
ID: userURL + "#main-key",
|
|
Owner: userURL,
|
|
PEM: pubKeyPem,
|
|
}
|
|
}
|
|
headers := w.Header()
|
|
headers.Add("Content-Type", "application/activity+json")
|
|
headers.Add("Content-Type", "charset=utf-8")
|
|
err := json.NewEncoder(w).Encode(profilePage{
|
|
Context: contextes,
|
|
ID: userURL,
|
|
Type: "Person",
|
|
PreferredUsername: name,
|
|
Name: app.Name,
|
|
Inbox: fmt.Sprintf("%s/inbox", fullhost),
|
|
Followers: fmt.Sprintf("%s/followers", userURL),
|
|
PublicKey: pubkey,
|
|
})
|
|
if err != nil {
|
|
http.Error(w, "Error encoding page: "+err.Error(), http.StatusInternalServerError)
|
|
}
|
|
}
|
|
|
|
func handlerWebFinger(w http.ResponseWriter, r *http.Request) {
|
|
params := r.URL.Query()
|
|
resource := params.Get("resource")
|
|
if resource == "" {
|
|
http.Error(w, "must include a valid resource", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
parts := strings.SplitN(resource, ":", 2)
|
|
if len(parts) < 2 {
|
|
http.Error(w, "invalid resource specified", http.StatusBadRequest)
|
|
return
|
|
}
|
|
switch parts[0] {
|
|
case "acct":
|
|
// Split user by host
|
|
userParts := strings.SplitN(parts[1], "@", 2)
|
|
if len(userParts) < 2 || strings.ToLower(userParts[1]) != host {
|
|
http.Error(w, "Invalid user specified", http.StatusBadRequest)
|
|
return
|
|
}
|
|
// Check if user is a registered app
|
|
_, ok := apps[userParts[0]]
|
|
if !ok {
|
|
http.Error(w, "user not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
headers := w.Header()
|
|
headers.Add("Content-Type", "application/json")
|
|
headers.Add("Content-Type", "charset=utf-8")
|
|
|
|
err := json.NewEncoder(w).Encode(profileWebFingerData{
|
|
Subject: resource,
|
|
Links: []profileLink{
|
|
{
|
|
Rel: "self",
|
|
Type: "application/activity+json",
|
|
Href: fmt.Sprintf("%s/u/%s", fullhost, userParts[0]),
|
|
},
|
|
},
|
|
})
|
|
|
|
if err != nil {
|
|
http.Error(w, "Error encoding webfinger: "+err.Error(), http.StatusInternalServerError)
|
|
}
|
|
}
|
|
}
|