add some works
This commit is contained in:
parent
cd9ec0c774
commit
8807e5aaab
22 changed files with 1074 additions and 3 deletions
6
handlers/README.md
Normal file
6
handlers/README.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Handlers
|
||||
|
||||
This folder contains [Mux](https://github.com/gorilla/mux) route handlers. If you've worked in webservers in other languages, it's similar to the concept of controllers.
|
||||
|
||||
It's common to see a handler take some information and spit it to something in `lib`. This is because handlers convert web-server knowledge to buisness-logic rather than do everything at once.
|
||||
|
41
handlers/groups/get.go
Normal file
41
handlers/groups/get.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
package groups
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.macaw.me/inhosin/subhub/activitypub"
|
||||
"git.macaw.me/inhosin/subhub/data"
|
||||
"git.macaw.me/inhosin/subhub/data/models"
|
||||
"git.macaw.me/inhosin/subhub/handlers"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Get returns a Group
|
||||
//
|
||||
// Expects a `{name}` url variable
|
||||
// in the route: `/api/group/:name`
|
||||
func Get(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
if name == "" {
|
||||
c.String(http.StatusBadRequest, "Bad request! No name in URL")
|
||||
return
|
||||
}
|
||||
group, err := models.GetGroup(data.GetDB(), name)
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if group == nil {
|
||||
c.String(http.StatusNotFound, fmt.Sprintf("%s does not exits on server", name))
|
||||
return
|
||||
}
|
||||
|
||||
url := handlers.GetFullHostName() + "/activity/group/" + group.Slug
|
||||
actor := activitypub.NewPerson(url)
|
||||
actor.PreferredUsername = group.Name
|
||||
actor.Name = group.Name
|
||||
actor.Summary = group.Note
|
||||
|
||||
c.JSON(http.StatusOK, actor)
|
||||
}
|
32
handlers/groups/post.go
Normal file
32
handlers/groups/post.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package groups
|
||||
|
||||
import (
|
||||
"git.macaw.me/inhosin/subhub/data"
|
||||
"git.macaw.me/inhosin/subhub/data/models"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type createGroupRequest struct {
|
||||
Name string `json:"name"`
|
||||
Note string `json:"note"`
|
||||
}
|
||||
|
||||
type createGroupResponse struct {
|
||||
Slug string `json:"slug"`
|
||||
}
|
||||
|
||||
// Create adds an group to the database
|
||||
func Create(c *gin.Context) {
|
||||
var body createGroupRequest
|
||||
c.BindJSON(&body)
|
||||
|
||||
db := data.GetDB()
|
||||
slug, err := models.PutGroup(db, body.Name, body.Note)
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
resp := createGroupResponse{Slug: slug}
|
||||
c.JSON(http.StatusOK, resp)
|
||||
}
|
7
handlers/path.go
Normal file
7
handlers/path.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package handlers
|
||||
|
||||
// GetFullHostName return string
|
||||
func GetFullHostName() string {
|
||||
// TODO make it at config
|
||||
return "http://" + "localhost" + ":8090"
|
||||
}
|
23
handlers/webfinder/README.md
Normal file
23
handlers/webfinder/README.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
# What's Webfinger?
|
||||
|
||||
[Webfinger](https://en.wikipedia.org/wiki/WebFinger), a protocol for discovering objects on the server. It's used by Mastodon and is important for interop'ing with Mastodon (and most ActivityPub servers).
|
||||
|
||||
It lives at a special route: `GET /.well-known/webfinger`.
|
||||
|
||||
We can expect a webfinger response to always looks something like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"subject": "acct:alice@my-example.com",
|
||||
|
||||
"links": [
|
||||
{
|
||||
"rel": "self",
|
||||
"type": "application/activity+json",
|
||||
"href": "https://my-example.com/actor"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
In this case, `alice` is the ActivityPub Organization slug, and `my-example.com` is the domain of the server.
|
40
handlers/webfinder/address.go
Normal file
40
handlers/webfinder/address.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
package webfinder
|
||||
|
||||
import (
|
||||
"git.macaw.me/inhosin/subhub/handlers"
|
||||
"net/mail"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func newBadAddressError(address string) *badAddressError {
|
||||
return &badAddressError{address: address}
|
||||
}
|
||||
|
||||
func slugOf(address string) string {
|
||||
fragment := strings.Split(address, "@")
|
||||
return fragment[0]
|
||||
}
|
||||
|
||||
func atAddress(address string) (*Resource, error) {
|
||||
// foo@bar.org => foo
|
||||
parser := mail.AddressParser{}
|
||||
_, err := parser.Parse(address)
|
||||
if err != nil {
|
||||
return nil, newBadAddressError(address)
|
||||
}
|
||||
|
||||
// foo@bar.org => foo
|
||||
slug := slugOf(address)
|
||||
domain := handlers.GetFullHostName()
|
||||
|
||||
return &Resource{
|
||||
Subject: address,
|
||||
Links: []Link{
|
||||
{
|
||||
Rel: "self",
|
||||
Type: "application/activity+json",
|
||||
HRef: domain + "/api/group/" + slug,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
26
handlers/webfinder/models.go
Normal file
26
handlers/webfinder/models.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package webfinder
|
||||
|
||||
type Resource struct {
|
||||
Subject string `json:"subject,omitempty"`
|
||||
Aliases []string `json:"aliases,omitempty"`
|
||||
Properties map[string]string `json:"properties,omitempty"`
|
||||
Links []Link `json:"links"`
|
||||
}
|
||||
|
||||
type Link struct {
|
||||
HRef string `json:"href"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Rel string `json:"rel"`
|
||||
Properties map[string]*string `json:"properties,omitempty"`
|
||||
Titles map[string]string `json:"titles,omitempty"`
|
||||
}
|
||||
|
||||
type Rel string
|
||||
|
||||
type badAddressError struct {
|
||||
address string
|
||||
}
|
||||
|
||||
func (e *badAddressError) Error() string {
|
||||
return "badly formatted address: " + e.address
|
||||
}
|
50
handlers/webfinder/webfinger.go
Normal file
50
handlers/webfinder/webfinger.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
package webfinder
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Get(c *gin.Context) {
|
||||
res := c.Query("resource")
|
||||
if res == "" {
|
||||
c.String(http.StatusBadRequest, "Missing 'resouce' query parameter in webfinger")
|
||||
return
|
||||
}
|
||||
|
||||
address, err := getAddress(res)
|
||||
if err != nil {
|
||||
c.String(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
// TODO find group???
|
||||
actor, err := atAddress(address)
|
||||
if err != nil {
|
||||
if _, ok := err.(*badAddressError); ok {
|
||||
c.String(http.StatusBadRequest, "Incorrect address format")
|
||||
return
|
||||
}
|
||||
|
||||
c.String(http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
if actor == nil {
|
||||
c.String(http.StatusBadRequest, "Account not found")
|
||||
}
|
||||
|
||||
// bytes, err := json.Marshal(actor)
|
||||
// if err != nil {
|
||||
// http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
// return
|
||||
// }
|
||||
c.JSON(http.StatusOK, actor)
|
||||
}
|
||||
|
||||
func getAddress(res string) (string, error) {
|
||||
args := strings.Split(res, ":")
|
||||
if args[0] != "acct" {
|
||||
return "", errors.New("Resource didn`t start with acct")
|
||||
}
|
||||
return args[1], nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue