Push to new goutils version
Some checks are pending
/ test (push) Waiting to run

This commit is contained in:
Melody Becker 2025-03-26 16:50:44 +01:00
parent 8ee314b0bb
commit daf401a2f7
Signed by: mstar
SSH key fingerprint: SHA256:9VAo09aaVNTWKzPW7Hq2LW+ox9OdwmTSHRoD4mlz1yI
9 changed files with 73 additions and 61 deletions

2
go.mod
View file

@ -5,7 +5,7 @@ go 1.23
toolchain go1.23.0
require (
git.mstar.dev/mstar/goutils v1.5.4
git.mstar.dev/mstar/goutils v1.9.1
github.com/BurntSushi/toml v1.4.0
github.com/dgraph-io/ristretto v0.2.0
github.com/eko/gocache/lib/v4 v4.1.6

2
go.sum
View file

@ -33,6 +33,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
git.mstar.dev/mstar/goutils v1.5.4 h1:l/4oQe/fBk9zyXplQkGXbmQndnm0aRdHuy4wgQfNrFo=
git.mstar.dev/mstar/goutils v1.5.4/go.mod h1:juxY0eZEMnA95fedRp2LVXvUBgEjz66nE8SEdGKcxMA=
git.mstar.dev/mstar/goutils v1.9.1 h1:B4km2Xj0Yq8GHIlAYo45NGMRQRdkr+hV9qdvhTJKuuA=
git.mstar.dev/mstar/goutils v1.9.1/go.mod h1:juxY0eZEMnA95fedRp2LVXvUBgEjz66nE8SEdGKcxMA=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=

View file

@ -3,10 +3,11 @@ package server
import (
"net/http"
httputil "git.mstar.dev/mstar/goutils/http"
"git.mstar.dev/mstar/goutils/sliceutils"
"github.com/google/jsonapi"
"github.com/rs/zerolog/hlog"
"git.mstar.dev/mstar/goutils/other"
"git.mstar.dev/mstar/goutils/sliceutils"
"git.mstar.dev/mstar/linstrom/storage"
)
@ -22,11 +23,11 @@ func linstromGetAccount(w http.ResponseWriter, r *http.Request) {
case nil:
// Ok, do nothing
case storage.ErrEntryNotFound:
other.HttpErr(w, HttpErrIdNotFound, "account not found", http.StatusNotFound)
httputil.HttpErr(w, HttpErrIdNotFound, "account not found", http.StatusNotFound)
return
default:
log.Error().Err(err).Str("account-id", accId).Msg("Failed to get account from storage")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to get account from storage",
@ -43,7 +44,7 @@ func linstromGetAccount(w http.ResponseWriter, r *http.Request) {
Err(err).
Strs("role-names", acc.Roles).
Msg("Failed to get roles from storage")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to get roles of target account",
@ -54,7 +55,7 @@ func linstromGetAccount(w http.ResponseWriter, r *http.Request) {
collapsedRole := storage.CollapseRolesIntoOne(roles...)
if sliceutils.Contains(collapsedRole.BlockedUsers, actorId) {
// Actor account is in list of blocked accounts, deny access
other.HttpErr(w, HttpErrIdNotAuthenticated, "Access forbidden", http.StatusForbidden)
httputil.HttpErr(w, HttpErrIdNotAuthenticated, "Access forbidden", http.StatusForbidden)
return
}
}
@ -64,7 +65,7 @@ func linstromGetAccount(w http.ResponseWriter, r *http.Request) {
log.Error().
Err(err).
Msg("Failed to convert storage account (and attached data) into linstrom API representation")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdConversionFailure,
"Failed to convert storage account and attached data into API representation",
@ -86,12 +87,12 @@ func linstromUpdateAccount(w http.ResponseWriter, r *http.Request) {
apiTarget := linstromAccount{}
err := jsonapi.UnmarshalPayload(r.Body, &apiTarget)
if err != nil {
other.HttpErr(w, HttpErrIdBadRequest, "bad body", http.StatusBadRequest)
httputil.HttpErr(w, HttpErrIdBadRequest, "bad body", http.StatusBadRequest)
return
}
targetAccId := AccountIdFromRequest(r)
if apiTarget.Id != targetAccId {
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdBadRequest,
"Provided entity's id doesn't match path id",
@ -100,7 +101,7 @@ func linstromUpdateAccount(w http.ResponseWriter, r *http.Request) {
return
}
if !(actorId == apiTarget.Id) {
other.HttpErr(w, HttpErrIdNotAuthenticated, "Invalid permissions", http.StatusForbidden)
httputil.HttpErr(w, HttpErrIdNotAuthenticated, "Invalid permissions", http.StatusForbidden)
return
}
dbTarget, err := store.FindAccountById(apiTarget.Id)
@ -112,7 +113,7 @@ func linstromUpdateAccount(w http.ResponseWriter, r *http.Request) {
Err(err).
Str("account-id", actorId).
Msg("Failed to get account from db despite valid session")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to get account despite valid session",
@ -140,7 +141,7 @@ func linstromUpdateAccount(w http.ResponseWriter, r *http.Request) {
err = store.UpdateAccount(dbTarget)
if err != nil {
log.Error().Err(err).Msg("Failed to update account in db")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to update db entries",
@ -152,7 +153,7 @@ func linstromUpdateAccount(w http.ResponseWriter, r *http.Request) {
newAccData, err := convertAccountStorageToLinstrom(dbTarget, store)
if err != nil {
log.Error().Err(err).Msg("Failed to convert updated account back into api form")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdConversionFailure,
"Failed to convert updated account back into api form",
@ -176,14 +177,14 @@ func linstromDeleteAccount(w http.ResponseWriter, r *http.Request) {
Str("actor-id", actorId).
Str("target-id", targetAccountId).
Msg("Invalid attempt to delete account")
other.HttpErr(w, HttpErrIdNotAuthenticated, "Action forbidden", http.StatusForbidden)
httputil.HttpErr(w, HttpErrIdNotAuthenticated, "Action forbidden", http.StatusForbidden)
return
}
log.Info().Str("account-id", actorId).Msg("Deleting account")
acc, err := store.FindAccountById(targetAccountId)
if err != nil {
log.Error().Err(err).Str("account-id", actorId).Msg("Failed to get account for deletion")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to get account from db",
@ -204,7 +205,7 @@ func linstromDeleteAccount(w http.ResponseWriter, r *http.Request) {
Err(err).
Str("role-name", acc.ID).
Msg("Failed to delete user role for account deletion request")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to delete user role",
@ -218,7 +219,7 @@ func linstromDeleteAccount(w http.ResponseWriter, r *http.Request) {
Err(err).
Str("account-id", acc.ID).
Msg("Failed to delete custom info fields for account deletion")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to delete custom info fields",
@ -229,7 +230,7 @@ func linstromDeleteAccount(w http.ResponseWriter, r *http.Request) {
err = store.DeleteAccount(actorId)
if err != nil {
log.Error().Err(err).Str("account-id", acc.ID).Msg("Failed to delete account")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to delete account from db",
@ -275,7 +276,7 @@ func linstromIsFollowingToAccount(w http.ResponseWriter, r *http.Request) {
Str("from-id", actorId).
Str("to-id", targetId).
Msg("Failed to get follow relation")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to get relation",
@ -286,7 +287,7 @@ func linstromIsFollowingToAccount(w http.ResponseWriter, r *http.Request) {
err = jsonapi.MarshalPayload(w, outData)
if err != nil {
log.Warn().Err(err).Msg("Failed to marshal response")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdJsonMarshalFail,
"Failed to marshal response",
@ -330,7 +331,7 @@ func linstromIsFollowingFromAccount(w http.ResponseWriter, r *http.Request) {
Str("from-id", targetId).
Str("to-id", actorId).
Msg("Failed to get follow relation")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to get relation",
@ -341,7 +342,7 @@ func linstromIsFollowingFromAccount(w http.ResponseWriter, r *http.Request) {
err = jsonapi.MarshalPayload(w, outData)
if err != nil {
log.Warn().Err(err).Msg("Failed to marshal response")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdJsonMarshalFail,
"Failed to marshal response",

View file

@ -4,11 +4,12 @@ import (
"net/http"
"time"
"git.mstar.dev/mstar/goutils/other"
"git.mstar.dev/mstar/linstrom/storage"
"git.mstar.dev/mstar/linstrom/util"
httputil "git.mstar.dev/mstar/goutils/http"
"github.com/google/jsonapi"
"github.com/rs/zerolog/hlog"
"git.mstar.dev/mstar/linstrom/storage"
"git.mstar.dev/mstar/linstrom/util"
)
// Notes
@ -21,11 +22,11 @@ func linstromGetNote(w http.ResponseWriter, r *http.Request) {
case nil:
// Found, progress past switch statement
case storage.ErrEntryNotFound:
other.HttpErr(w, HttpErrIdNotFound, "Note not found", http.StatusNotFound)
httputil.HttpErr(w, HttpErrIdNotFound, "Note not found", http.StatusNotFound)
return
default:
log.Error().Err(err).Str("note-id", noteId).Msg("Failed to get note from db")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to get note from db",
@ -39,7 +40,7 @@ func linstromGetNote(w http.ResponseWriter, r *http.Request) {
Err(err).
Str("note-id", noteId).
Msg("Failed to convert note into linstrom api form")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdConversionFailure,
"Failed to convert note",
@ -50,7 +51,7 @@ func linstromGetNote(w http.ResponseWriter, r *http.Request) {
err = jsonapi.MarshalPayload(w, note)
if err != nil {
log.Error().Err(err).Any("note", note).Msg("Failed to marshal and send note")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdJsonMarshalFail,
"Failed to convert note",
@ -66,7 +67,7 @@ func linstromNewNote(w http.ResponseWriter, r *http.Request) {
log := hlog.FromRequest(r)
if !ok {
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdNotAuthenticated,
"Needs a valid session to create new notes",
@ -79,7 +80,7 @@ func linstromNewNote(w http.ResponseWriter, r *http.Request) {
err := jsonapi.UnmarshalPayload(r.Body, &newNote)
if err != nil {
log.Warn().Err(err).Msg("Failed to unmarshal body")
other.HttpErr(w, HttpErrIdBadRequest, "bad body", http.StatusBadRequest)
httputil.HttpErr(w, HttpErrIdBadRequest, "bad body", http.StatusBadRequest)
return
}
@ -88,7 +89,7 @@ func linstromNewNote(w http.ResponseWriter, r *http.Request) {
Str("actor-id", actorId).
Str("target-id", newNote.AuthorId).
Msg("Blocking attempt at creating a note for a different account")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdNotAllowed,
"creating a note for someone else is not allowed",
@ -114,7 +115,7 @@ func linstromNewNote(w http.ResponseWriter, r *http.Request) {
)
if err != nil {
log.Error().Err(err).Any("note", newNote).Msg("Failed to insert new note into storage")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to insert new note into db",

View file

@ -9,7 +9,7 @@ import (
"runtime/debug"
"time"
"git.mstar.dev/mstar/goutils/other"
httputil "git.mstar.dev/mstar/goutils/http"
)
// Mounted at /profiling
@ -65,7 +65,7 @@ func metricMemoryStatsHandler(w http.ResponseWriter, r *http.Request) {
jsonData, err := json.Marshal(&outData)
if err != nil {
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdJsonMarshalFail,
"Failed to encode return data",

View file

@ -8,8 +8,8 @@ import (
"strings"
"time"
httputil "git.mstar.dev/mstar/goutils/http"
"github.com/rs/zerolog/hlog"
"git.mstar.dev/mstar/goutils/other"
"git.mstar.dev/mstar/linstrom/storage"
)
@ -63,7 +63,12 @@ func fuckWithRegisterRequest(
log.Debug().Bytes("body", body).Msg("Body of auth begin request")
err := json.Unmarshal(body, &username)
if err != nil {
other.HttpErr(w, HttpErrIdBadRequest, "Not a username json object", http.StatusBadRequest)
httputil.HttpErr(
w,
HttpErrIdBadRequest,
"Not a username json object",
http.StatusBadRequest,
)
return
}
if cookieErr == nil {
@ -73,7 +78,7 @@ func fuckWithRegisterRequest(
session, ok := store.GetSession(cookie.Value)
if !ok {
log.Error().Str("session-id", cookie.Value).Msg("Passkey session missing")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Passkey session missing",
@ -85,7 +90,7 @@ func fuckWithRegisterRequest(
// Assume account must exist if a session for it exists
if err != nil {
log.Error().Err(err).Msg("Failed to get account from passkey id from session")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to get authenticated account",
@ -110,7 +115,7 @@ func fuckWithRegisterRequest(
log.Info().
Str("username", username.Username).
Msg("Account with same name already exists, preventing login")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdAlreadyExists,
"Account with that name already exists",
@ -131,7 +136,7 @@ func fuckWithRegisterRequest(
Err(err).
Str("username", username.Username).
Msg("Failed to check if account with username already exists")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to check if account with that name already exists",
@ -165,7 +170,7 @@ func fuckWithLoginRequest(
log.Debug().Bytes("body", body).Msg("Body of auth begin request")
err := json.Unmarshal(body, &username)
if err != nil {
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdBadRequest,
"Not a username json object",
@ -176,7 +181,7 @@ func fuckWithLoginRequest(
session, ok := store.GetSession(cookie.Value)
if !ok {
log.Error().Str("session-id", cookie.Value).Msg("Passkey session missing")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Passkey session missing",
@ -188,7 +193,7 @@ func fuckWithLoginRequest(
// Assume account must exist if a session for it exists
if err != nil {
log.Error().Err(err).Msg("Failed to get account from passkey id from session")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to get authenticated account",
@ -209,7 +214,7 @@ func fuckWithLoginRequest(
log.Debug().Bytes("body", body).Msg("Body of auth begin request")
err := json.Unmarshal(body, &username)
if err != nil {
other.HttpErr(w, HttpErrIdBadRequest, "Not a username json object", http.StatusBadRequest)
httputil.HttpErr(w, HttpErrIdBadRequest, "Not a username json object", http.StatusBadRequest)
return
}
_, err = store.FindLocalAccountByUsername(username.Username)
@ -219,12 +224,12 @@ func fuckWithLoginRequest(
// Do nothing in this branch
case storage.ErrEntryNotFound:
// Account doesn't exist, catch it
other.HttpErr(w, HttpErrIdNotFound, "Username not found", http.StatusNotFound)
httputil.HttpErr(w, HttpErrIdNotFound, "Username not found", http.StatusNotFound)
return
default:
// catch db failures
log.Error().Err(err).Str("username", username.Username).Msg("Db failure while getting account")
other.HttpErr(w, HttpErrIdDbFailure, "Failed to check for account in db", http.StatusInternalServerError)
httputil.HttpErr(w, HttpErrIdDbFailure, "Failed to check for account in db", http.StatusInternalServerError)
return
}
// Restore body as new reader of the same content

View file

@ -7,9 +7,10 @@ import (
"strings"
"time"
httputil "git.mstar.dev/mstar/goutils/http"
"github.com/rs/zerolog/hlog"
"github.com/rs/zerolog/log"
"git.mstar.dev/mstar/goutils/other"
"git.mstar.dev/mstar/linstrom/config"
"git.mstar.dev/mstar/linstrom/storage"
)
@ -68,7 +69,7 @@ func passkeyIdToAccountIdTransformerMiddleware(handler http.Handler) http.Handle
log := hlog.FromRequest(r)
passkeyId, ok := r.Context().Value(ContextKeyPasskeyUsername).(string)
if !ok {
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdMissingContextValue,
"Actor name missing",
@ -79,7 +80,7 @@ func passkeyIdToAccountIdTransformerMiddleware(handler http.Handler) http.Handle
log.Debug().Bytes("passkey-bytes", []byte(passkeyId)).Msg("Id from passkey auth")
acc, err := s.FindAccountByPasskeyId([]byte(passkeyId))
if err != nil {
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to get account from storage",
@ -95,7 +96,7 @@ func passkeyIdToAccountIdTransformerMiddleware(handler http.Handler) http.Handle
func profilingAuthenticationMiddleware(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.FormValue("password") != config.GlobalConfig.Admin.ProfilingPassword {
other.HttpErr(w, HttpErrIdNotAuthenticated, "Bad password", http.StatusUnauthorized)
httputil.HttpErr(w, HttpErrIdNotAuthenticated, "Bad password", http.StatusUnauthorized)
return
}
handler.ServeHTTP(w, r)
@ -166,7 +167,7 @@ func requireValidSessionMiddleware(
return func(w http.ResponseWriter, r *http.Request) {
_, ok := r.Context().Value(ContextKeyActorId).(string)
if !ok {
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdNotAuthenticated,
"Not authenticated",
@ -183,7 +184,7 @@ func buildRequirePermissionsMiddleware(permissionRole *storage.Role) HandlerBuil
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
accId, ok := r.Context().Value(ContextKeyActorId).(string)
if !ok {
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdNotAuthenticated,
"Not authenticated",
@ -201,7 +202,7 @@ func buildRequirePermissionsMiddleware(permissionRole *storage.Role) HandlerBuil
Err(err).
Str("account-id", accId).
Msg("Error while getting account from session")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Error while getting account from session",
@ -212,7 +213,7 @@ func buildRequirePermissionsMiddleware(permissionRole *storage.Role) HandlerBuil
roles, err := store.FindRolesByNames(acc.Roles)
// Assumption: There will always be at least two roles per user, default user and user-specific one
if err != nil {
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdDbFailure,
"Failed to get roles for account",
@ -222,7 +223,7 @@ func buildRequirePermissionsMiddleware(permissionRole *storage.Role) HandlerBuil
}
collapsedRole := storage.CollapseRolesIntoOne(roles...)
if !storage.CompareRoles(&collapsedRole, permissionRole) {
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdNotAuthenticated,
"Insufficient permisions",

View file

@ -5,9 +5,10 @@ import (
"io/fs"
"net/http"
httputil "git.mstar.dev/mstar/goutils/http"
"github.com/mstarongithub/passkey"
"github.com/rs/zerolog/log"
"git.mstar.dev/mstar/goutils/other"
"git.mstar.dev/mstar/linstrom/storage"
)
@ -67,7 +68,7 @@ func buildRootHandler(
ContextKeyPasskeyUsername,
nil,
func(w http.ResponseWriter, r *http.Request) {
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdNotAuthenticated,
"Not authenticated",

View file

@ -3,14 +3,15 @@ package server
import (
"net/http"
httputil "git.mstar.dev/mstar/goutils/http"
"github.com/rs/zerolog/hlog"
"git.mstar.dev/mstar/goutils/other"
"git.mstar.dev/mstar/linstrom/storage"
)
func placeholderEndpoint(w http.ResponseWriter, r *http.Request) {
hlog.FromRequest(r).Error().Stringer("url", r.URL).Msg("Placeholder endpoint accessed")
other.HttpErr(
httputil.HttpErr(
w,
HttpErrIdPlaceholder,
"Endpoint not implemented yet, this is a placeholder",