You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
2.4 KiB
Go

package main
// Small generic oauth authentication server to retrieve oauth tokens
// from mastodon instances.
import (
"encoding/json"
"fmt"
"net/http"
"os"
"github.com/gorilla/websocket"
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
"github.com/labstack/gommon/log"
"go.etcd.io/bbolt"
)
var (
upgrader = websocket.Upgrader{}
)
type Instance struct {
Secret string `json:"client_secret"`
ID string `json:"client_id"`
}
type App struct {
AuthMap *AuthenticationMap
Logger *echo.Logger
DB *bbolt.DB
}
func (a *App) authRequestWebSocket(c echo.Context) error {
ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil)
if err != nil {
return err
}
client := &AuthRequestClient{
conn: ws,
app: a,
}
req, err := client.ReceiveRequest()
if err != nil {
return err
}
(*a.Logger).Info("Queueing AuthRequest")
a.AuthMap.QueueRequest(req)
return nil
}
func (a *App) authRequestRedirect(c echo.Context) error {
requestId := c.Param("request_id")
authRequest := a.AuthMap.GetRequestByID(requestId)
if authRequest == nil {
return c.String(http.StatusNotFound, "No authentication request found by this ID")
}
var instance *Instance
a.DB.View(func(t *bbolt.Tx) error {
instanceJson := t.Bucket([]byte("instances")).Get([]byte(authRequest.Instance))
if instanceJson == nil {
instance = nil
return nil
}
instance = &Instance{}
err := json.Unmarshal(instanceJson, instance)
return err
})
return c.String(http.StatusOK, "BLAAT")
//return c.Redirect(http.StatusTemporaryRedirect, )
}
func main() {
arguments := os.Args[1:]
if len(arguments) != 2 {
fmt.Fprintln(os.Stderr, "Expected 2 command line argumens, but got : ", len(arguments))
fmt.Fprintln(os.Stderr, "Usage: generic-mastodon-authenticator APP_NAME DB_PATH")
os.Exit(1)
}
database := arguments[1]
db, err := bbolt.Open(database, 0600, nil)
if err != nil {
log.Fatal(err)
}
db.Update(func(t *bbolt.Tx) error {
_, err := t.CreateBucketIfNotExists([]byte("instances"))
return err
})
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.Static("/", "../public")
e.Logger.SetLevel(log.INFO)
a := &App{
Logger: &e.Logger,
DB: db,
}
m := &AuthenticationMap{
app: a,
}
m.Init()
a.AuthMap = m
e.GET("/ws", a.authRequestWebSocket)
e.GET("/auth/:request_id", a.authRequestRedirect)
e.Logger.Fatal(e.Start(":1323"))
}