linstrom/web/debug/users.go
mStar f8b3a6ff06
All checks were successful
/ docker (push) Successful in 3m59s
Add debug handler for fetching a remote actor
Will be used later to add to internal db
2025-04-12 11:47:01 +02:00

190 lines
4.7 KiB
Go

package webdebug
import (
"crypto/rand"
"database/sql"
"encoding/json"
"net/http"
"strconv"
"time"
webutils "git.mstar.dev/mstar/goutils/http"
"git.mstar.dev/mstar/goutils/other"
"git.mstar.dev/mstar/goutils/sliceutils"
"github.com/rs/zerolog/hlog"
"git.mstar.dev/mstar/linstrom/activitypub"
"git.mstar.dev/mstar/linstrom/shared"
"git.mstar.dev/mstar/linstrom/storage-new/dbgen"
"git.mstar.dev/mstar/linstrom/storage-new/models"
webshared "git.mstar.dev/mstar/linstrom/web/shared"
)
func getNonDeletedUsers(w http.ResponseWriter, r *http.Request) {
log := hlog.FromRequest(r)
pageStr := r.FormValue("page")
page := 0
if pageStr != "" {
var err error
page, err = strconv.Atoi(pageStr)
if err != nil {
webutils.ProblemDetails(
w,
http.StatusBadRequest,
"/errors/bad-page",
"bad page number",
other.IntoPointer("page number must be an uint"),
nil,
)
return
}
if page < 0 {
webutils.ProblemDetails(
w,
http.StatusBadRequest,
"/errors/bad-page",
"bad page number",
other.IntoPointer("page number must be >= 0"),
nil,
)
return
}
}
users, err := dbgen.User.GetPagedAllNonDeleted(uint(page))
if err != nil {
log.Error().Err(err).Int("page", page).Msg("Failed to get non-deleted users")
webutils.ProblemDetails(
w,
http.StatusInternalServerError,
"/errors/db-failure",
"database failure",
nil,
nil,
)
return
}
webutils.SendJson(w, sliceutils.Map(users, func(t models.User) webshared.User {
u := webshared.User{}
u.FromModel(&t)
return u
}))
}
func createLocalUser(w http.ResponseWriter, r *http.Request) {
type Inbound struct {
Username string `json:"username"`
Displayname string `json:"displayname"`
Description string `json:"description"`
Birthday *time.Time `json:"birthday"`
Location *string `json:"location"`
IsBot bool `json:"is_bot"`
}
log := hlog.FromRequest(r)
jsonDecoder := json.NewDecoder(r.Body)
data := Inbound{}
err := jsonDecoder.Decode(&data)
if err != nil {
webutils.ProblemDetails(
w,
http.StatusBadRequest,
"/errors/bad-request-data",
"bad request data",
nil,
map[string]any{
"sample": Inbound{
Username: "bob",
Displayname: "Bob Bobbington",
Description: "Bobbing Bobs bop to Bobs bobbing beats",
Birthday: other.IntoPointer(time.Now()),
Location: nil,
IsBot: false,
},
},
)
return
}
publicKeyEdBytes, privateKeyEdBytes, err := shared.GenerateKeypair(true)
if err != nil {
log.Error().Err(err).Msg("Failed to generate and marshal public key")
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
return
}
publicKeyRsaBytes, privateKeyRsaBytes, err := shared.GenerateKeypair(false)
if err != nil {
log.Error().Err(err).Msg("Failed to generate and marshal public key")
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
return
}
pkeyId := make([]byte, 64)
_, err = rand.Read(pkeyId)
if err != nil {
log.Error().Err(err).Msg("Failed to generate passkey id")
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
return
}
u := dbgen.User
query := u.Select(
u.Username,
u.DisplayName,
u.Description,
u.IsBot,
u.ServerId,
u.PrivateKeyEd,
u.PublicKeyEd,
u.PrivateKeyRsa,
u.PublicKeyRsa,
u.PasskeyId,
)
if data.Birthday != nil {
query = query.Select(u.Birthday)
}
if data.Location != nil {
query = query.Select(u.Location)
}
user := models.User{
Username: data.Username,
DisplayName: data.Displayname,
Description: data.Description,
IsBot: data.IsBot,
ServerId: 1, // Hardcoded, Self is always first ID
PublicKeyRsa: publicKeyRsaBytes,
PublicKeyEd: publicKeyEdBytes,
PrivateKeyRsa: privateKeyRsaBytes,
PrivateKeyEd: privateKeyEdBytes,
PasskeyId: pkeyId,
}
if data.Birthday != nil {
user.Birthday = sql.NullTime{Valid: true, Time: *data.Birthday}
}
if data.Location != nil {
user.Location = sql.NullString{Valid: true, String: *data.Location}
}
if err = u.Create(&user); err != nil {
log.Error().Err(err).Msg("failed to create new local user")
webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
}
}
func deleteUser(w http.ResponseWriter, r *http.Request) {
id := r.FormValue("id")
dbgen.User.Where(dbgen.User.ID.Eq(id)).Delete()
w.WriteHeader(http.StatusOK)
}
func issueUserImport(w http.ResponseWriter, r *http.Request) {
target := r.FormValue("target")
_, err := activitypub.ImportRemoteAccount(target)
hlog.FromRequest(r).Info().Err(err).Msg("Err from import request")
}
func kickoffFollow(w http.ResponseWriter, r *http.Request) {
type Inbound struct {
Id string
Target string
}
var data Inbound
dec := json.NewDecoder(r.Body)
dec.Decode(&data)
}