meow
More progress. Fixed storage bug. Need to get media stuff going
This commit is contained in:
parent
1bb6cd8a70
commit
83f47d17be
11 changed files with 209 additions and 27 deletions
|
@ -42,6 +42,7 @@ func setupLinstromApiV1Router() http.Handler {
|
|||
router.HandleFunc("GET /accounts/{accountId}", linstromGetAccount)
|
||||
// Technically also requires authenticated account to also be owner or correct admin perms,
|
||||
// but that's annoying to handle in a general sense. So leaving that to the function
|
||||
// though figuring out a nice generic-ish way to handle those checks would be nice too
|
||||
router.HandleFunc(
|
||||
"PATCH /accounts/{accountId}",
|
||||
requireValidSessionMiddleware(linstromUpdateAccount),
|
||||
|
|
|
@ -81,6 +81,89 @@ func linstromGetAccount(w http.ResponseWriter, r *http.Request) {
|
|||
func linstromUpdateAccount(w http.ResponseWriter, r *http.Request) {
|
||||
store := StorageFromRequest(r)
|
||||
log := hlog.FromRequest(r)
|
||||
// Assumption: There must be a valid session once this function is called due to middlewares
|
||||
actorId, _ := ActorIdFromRequest(r)
|
||||
apiTarget := linstromAccount{}
|
||||
err := jsonapi.UnmarshalPayload(r.Body, &apiTarget)
|
||||
if err != nil {
|
||||
other.HttpErr(w, HttpErrIdBadRequest, "bad body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
targetAccId := AccountIdFromRequest(r)
|
||||
if apiTarget.Id != targetAccId {
|
||||
other.HttpErr(
|
||||
w,
|
||||
HttpErrIdBadRequest,
|
||||
"Provided entity's id doesn't match path id",
|
||||
http.StatusConflict,
|
||||
)
|
||||
return
|
||||
}
|
||||
if !(actorId == apiTarget.Id) {
|
||||
other.HttpErr(w, HttpErrIdNotAuthenticated, "Invalid permissions", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
dbTarget, err := store.FindAccountById(apiTarget.Id)
|
||||
// Assumption: The only sort of errors that can be returned are db failures.
|
||||
// The account not existing is not possible anymore since this is in a valid session
|
||||
// and a session is only injected if the actor account can be found
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Err(err).
|
||||
Str("account-id", actorId).
|
||||
Msg("Failed to get account from db despite valid session")
|
||||
other.HttpErr(
|
||||
w,
|
||||
HttpErrIdDbFailure,
|
||||
"Failed to get account despite valid session",
|
||||
http.StatusInternalServerError,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// location, birthday, icon, banner, background, custom fields
|
||||
// bluesky federation, uhhh
|
||||
|
||||
dbTarget.DisplayName = apiTarget.DisplayName
|
||||
dbTarget.Indexable = apiTarget.Indexable
|
||||
dbTarget.Description = apiTarget.Description
|
||||
// TODO: Figure out how to properly update custom fields
|
||||
dbTarget.Gender = apiTarget.Pronouns
|
||||
dbTarget.IdentifiesAs = sliceutils.Map(
|
||||
sliceutils.Filter(apiTarget.IdentifiesAs, func(t string) bool {
|
||||
return storage.IsValidBeing(t)
|
||||
}),
|
||||
func(t string) storage.Being { return storage.Being(t) },
|
||||
)
|
||||
dbTarget.Indexable = apiTarget.Indexable
|
||||
dbTarget.RestrictedFollow = apiTarget.RestrictedFollow
|
||||
err = store.UpdateAccount(dbTarget)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to update account in db")
|
||||
other.HttpErr(
|
||||
w,
|
||||
HttpErrIdDbFailure,
|
||||
"Failed to update db entries",
|
||||
http.StatusInternalServerError,
|
||||
)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
newAccData, err := convertAccountStorageToLinstrom(dbTarget, store)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to convert updated account back into api form")
|
||||
other.HttpErr(
|
||||
w,
|
||||
HttpErrIdConverionFailure,
|
||||
"Failed to convert updated account back into api form",
|
||||
http.StatusInternalServerError,
|
||||
)
|
||||
return
|
||||
}
|
||||
err = jsonapi.MarshalPayload(w, newAccData)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to marshal and write updated account")
|
||||
}
|
||||
}
|
||||
func linstromDeleteAccount(w http.ResponseWriter, r *http.Request) {}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gitlab.com/mstarongitlab/goutils/sliceutils"
|
||||
"gitlab.com/mstarongitlab/linstrom/storage"
|
||||
)
|
||||
|
@ -11,23 +13,23 @@ func convertAccountStorageToLinstrom(
|
|||
) (*linstromAccount, error) {
|
||||
storageServer, err := store.FindRemoteServerById(acc.ServerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("remote server: %w", err)
|
||||
}
|
||||
apiServer, err := convertServerStorageToLinstrom(storageServer, store)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("remote server conversion: %w", err)
|
||||
}
|
||||
storageIcon, err := store.GetMediaMetadataById(acc.Icon)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("icon: %w", err)
|
||||
}
|
||||
storageBanner, err := store.GetMediaMetadataById(acc.Banner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("banner: %w", err)
|
||||
}
|
||||
storageFields, err := store.FindMultipleUserFieldsById(acc.CustomFields)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("customFields: %w", err)
|
||||
}
|
||||
|
||||
return &linstromAccount{
|
||||
|
@ -68,7 +70,7 @@ func convertServerStorageToLinstrom(
|
|||
) (*linstromOriginServer, error) {
|
||||
storageMeta, err := store.GetMediaMetadataById(server.Icon)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("icon metadata: %w", err)
|
||||
}
|
||||
return &linstromOriginServer{
|
||||
Id: server.ID,
|
||||
|
|
|
@ -5,7 +5,7 @@ import "net/http"
|
|||
// Mounted at /api
|
||||
func setupApiRouter() http.Handler {
|
||||
router := http.NewServeMux()
|
||||
router.Handle("/linstrom/", setupLinstromApiRouter())
|
||||
router.Handle("/linstrom/", http.StripPrefix("/linstrom", setupLinstromApiRouter()))
|
||||
|
||||
// Section MastoApi
|
||||
// First segment are endpoints that will need to be moved to primary router since at top route
|
||||
|
|
|
@ -103,6 +103,7 @@ func fuckWithRegisterRequest(
|
|||
} else {
|
||||
// Not authenticated, ensure that no existing name is registered with
|
||||
_, err = store.FindLocalAccountByUsername(username.Username)
|
||||
log.Debug().Bool("err-equals-not_found", err == storage.ErrEntryNotFound).Send()
|
||||
switch err {
|
||||
case nil:
|
||||
// No error while getting account means account exists, refuse access
|
||||
|
|
|
@ -27,6 +27,11 @@ func StorageFromRequest(r *http.Request) *storage.Storage {
|
|||
return store
|
||||
}
|
||||
|
||||
func ActorIdFromRequest(r *http.Request) (string, bool) {
|
||||
id, ok := r.Context().Value(ContextKeyActorId).(string)
|
||||
return id, ok
|
||||
}
|
||||
|
||||
func NoteIdFromRequest(r *http.Request) string {
|
||||
return r.PathValue("noteId")
|
||||
}
|
||||
|
@ -34,3 +39,16 @@ func NoteIdFromRequest(r *http.Request) string {
|
|||
func AccountIdFromRequest(r *http.Request) string {
|
||||
return r.PathValue("accountId")
|
||||
}
|
||||
|
||||
func CheckIfAccountIdHasPermissions(accId string, perms storage.Role, store *storage.Storage) bool {
|
||||
acc, err := store.FindAccountById(accId)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
roles, err := store.FindRolesByNames(acc.Roles)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
collapsed := storage.CollapseRolesIntoOne(roles...)
|
||||
return storage.CompareRoles(&collapsed, &perms)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue