u
Anirudh Oppiliappan x@icyphox.sh
Thu, 25 Jan 2024 20:53:53 +0200
3 files changed,
58 insertions(+),
0 deletions(-)
M
database.go
→
database.go
@@ -1186,6 +1186,25 @@ }
return true } +func getMastoAppFromAuthToken(authtoken string) *MastoApp { + var clientID string + err := stmtGetClientIDWithAuthToken.Get(&clientID, authtoken) + if err == sql.ErrNoRows { + elog.Printf("masto: invalid authtoken: %s\n", authtoken) + return nil + } + + app := MastoApp{} + row := stmtGetMastoApp.QueryRowx(clientID) + err = row.StructScan(&app) + if err != nil { + elog.Printf("%w: scanning masto app", err) + return nil + } + + return &app +} + var stmtHonkers, stmtDubbers, stmtNamedDubbers, stmtSaveHonker, stmtUpdateFlavor, stmtUpdateHonker *sql.Stmt var stmtDeleteHonker *sql.Stmt var stmtAnyXonk, stmtOneXonk, stmtPublicHonks, stmtUserHonks, stmtHonksByCombo, stmtHonksByConvoy *sql.Stmt@@ -1214,6 +1233,7 @@ var stmtCheckClient *sql.Stmt
var stmtSaveMastoAppToken *sql.Stmt var stmtSaveMastoAccessToken *sql.Stmt var stmtGetMastoApp *sqlx.Stmt +var stmtGetClientIDWithAuthToken *sqlx.Stmt func preparetodie(db *sql.DB, s string) *sql.Stmt { stmt, err := db.Prepare(s)@@ -1323,4 +1343,5 @@ }
func prepareStatementsx(dbx *sqlx.DB) { stmtGetMastoApp = preparetodiex(dbx, "select * from masto where clientid = ?") + stmtGetClientIDWithAuthToken = preparetodie(dbx, "select clientid from mastokens where authtoken = ?") }
M
masto.go
→
masto.go
@@ -247,3 +247,12 @@ goodjunk(rw, j)
return } + +// https://docs.joinmastodon.org/methods/apps/#verify_credentials +func verifycreds(rw http.ResponseWriter, r *http.Request) { + app := r.Context().Value("app").(MastoApp) + j := junk.New() + j["name"] = app.Name + j["vapid_key"] = app.VapidKey + goodjunk(rw, j) +}
M
web.go
→
web.go
@@ -17,6 +17,7 @@ package main
import ( "bytes" + "context" "database/sql" "fmt" "html/template"@@ -2992,6 +2993,7 @@ mastopost.HandleFunc("/oauth/authorize", oauthorize)
mastopost.HandleFunc("/oauth/token", oauthtoken) mastoget.HandleFunc("/api/v1/instance", instance) mastopost.HandleFunc("/api/v1/apps", apiapps) + mastoget.HandleFunc("/api/v1/apps/verify_credentials", injectapp(verifycreds)) loggedmux := handlers.LoggingHandler(os.Stdout, mux) err = http.Serve(listener, loggedmux)@@ -2999,3 +3001,29 @@ if err != nil {
elog.Fatal(err) } } + +// Verifies that authtoken is valid and injects the associated +// MastoApp in the request context +func injectapp(h http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + authHeader := r.Header.Get("Authorization") + split := strings.Split(authHeader, "Bearer") + if len(split) != 2 { + elog.Println("masto: bad api token format or lack thereof") + w.WriteHeader(http.StatusBadRequest) + return + } + + token := split[1] + app := getMastoAppFromAuthToken(token) + if app == nil { + elog.Println("masto: invalid auth token") + w.WriteHeader(http.StatusUnauthorized) + return + } + + ctx := context.WithValue(r.Context(), "app", app) + r = r.WithContext(ctx) + h(w, r) + } +}