More work on the api. Also auth middleware stuff
More work on the placeholder functions for the Linstrom API Additionally, started work on a slightly more sophisticated authentication control system And ran `go generate` again
This commit is contained in:
parent
b9c95a0297
commit
873f52d64f
14 changed files with 637 additions and 300 deletions
|
@ -12,30 +12,70 @@ func setupLinstromApiRouter() http.Handler {
|
||||||
func setupLinstromApiV1Router() http.Handler {
|
func setupLinstromApiV1Router() http.Handler {
|
||||||
router := http.NewServeMux()
|
router := http.NewServeMux()
|
||||||
// Notes
|
// Notes
|
||||||
router.HandleFunc("GET /note/{noteId}", linstromGetNote)
|
router.HandleFunc("GET /notes/{noteId}", linstromGetNote)
|
||||||
router.HandleFunc("POST /note", linstromNewNote)
|
router.HandleFunc("POST /notes", linstromNewNote)
|
||||||
router.HandleFunc("PUT /note/{noteId}", linstromUpdateNote)
|
router.HandleFunc("PATCH /notes/{noteId}", linstromUpdateNote)
|
||||||
router.HandleFunc("DELETE /note/{noteId}", linstromDeleteNote)
|
router.HandleFunc("DELETE /notes/{noteId}", linstromDeleteNote)
|
||||||
// Reactions
|
// Reactions
|
||||||
router.HandleFunc("GET /note/{noteId}/reactions", linstromGetReactions)
|
router.HandleFunc("GET /notes/{noteId}/reactions", linstromGetReactions)
|
||||||
router.HandleFunc("POST /note/{noteId}/reactions", linstromAddReaction)
|
router.HandleFunc("POST /notes/{noteId}/reactions", linstromAddReaction)
|
||||||
router.HandleFunc("PUT /note/{noteId}/reactions", linstromUpdateReaction)
|
router.HandleFunc("PATCH /notes/{noteId}/reactions", linstromUpdateReaction)
|
||||||
router.HandleFunc("DELETE /note/{noteId}/reactions", linstromDeleteReaction)
|
router.HandleFunc("DELETE /notes/{noteId}/reactions", linstromDeleteReaction)
|
||||||
// Boosts
|
// Boosts
|
||||||
router.HandleFunc("GET /note/{noteId}/boosts", linstromGetBoosts)
|
router.HandleFunc("GET /notes/{noteId}/boosts", linstromGetBoosts)
|
||||||
router.HandleFunc("POST /note/{noteId}/boosts", linstromAddBoost)
|
router.HandleFunc("POST /notes/{noteId}/boosts", linstromAddBoost)
|
||||||
router.HandleFunc("DELETE /note/{noteId}/boosts", linstromRemoveBoost)
|
router.HandleFunc("DELETE /notes/{noteId}/boosts", linstromRemoveBoost)
|
||||||
// Quotes
|
// Quotes
|
||||||
router.HandleFunc("GET /note/{noteId}/quotes", linstromGetQuotes)
|
router.HandleFunc("GET /notes/{noteId}/quotes", linstromGetQuotes)
|
||||||
router.HandleFunc("POST /note/{noteId}/quotes", linstromAddQuote)
|
router.HandleFunc("POST /notes/{noteId}/quotes", linstromAddQuote)
|
||||||
// Pinning
|
// Pinning
|
||||||
router.HandleFunc("POST /note/{noteId}/pin", linstromPinNote)
|
router.HandleFunc("POST /notes/{noteId}/pin", linstromPinNote)
|
||||||
router.HandleFunc("DELETE /note/{noteId}/pin", linstromUnpinNote)
|
router.HandleFunc("DELETE /notes/{noteId}/pin", linstromUnpinNote)
|
||||||
// Reports
|
// Reports
|
||||||
router.HandleFunc("POST /note/{noteId}/report", linstromReportNote)
|
router.HandleFunc("POST /notes/{noteId}/report", linstromReportNote)
|
||||||
router.HandleFunc("DELETE /note/{noteId}/report", linstromRetractReportNote)
|
router.HandleFunc("DELETE /notes/{noteId}/report", linstromRetractReportNote)
|
||||||
// Admin
|
// Admin
|
||||||
router.HandleFunc("POST /note/{noteId}/admin/cw", linstromForceCWNote)
|
router.HandleFunc("POST /notes/{noteId}/admin/cw", linstromForceCWNote)
|
||||||
|
|
||||||
|
// Accounts
|
||||||
|
// Creating a new account happens either during fetch of a remote one or during registration with a passkey
|
||||||
|
router.HandleFunc("GET /accounts/{accountId}", linstromGetAccount)
|
||||||
|
router.HandleFunc("PATCH /accounts/{accountId}", linstromUpdateAccount)
|
||||||
|
router.HandleFunc("DELETE /accounts/{accountId}", linstromDeleteAccount)
|
||||||
|
// Follow
|
||||||
|
router.HandleFunc("GET /accounts/{accountId}/follow", linstromIsFollowingAccount)
|
||||||
|
router.HandleFunc("POST /accounts/{accountId}/follow", linstromFollowAccount)
|
||||||
|
router.HandleFunc("DELETE /accounts/{accountId}/follow", linstromUnfollowAccount)
|
||||||
|
// Block
|
||||||
|
router.HandleFunc("GET /accounts/{accountId}/block", linstromIsBlockingAccount)
|
||||||
|
router.HandleFunc("POST /accounts/{accountId}/block", linstromBlockAccount)
|
||||||
|
router.HandleFunc("DELETE /accounts/{accountId}/block", linstromUnblockAccount)
|
||||||
|
// Mute
|
||||||
|
router.HandleFunc("GET /accounts/{accountId}/mute", linstromIsMutedAccount)
|
||||||
|
router.HandleFunc("POST /accounts/{accountId}/mute", linstromMuteAccount)
|
||||||
|
router.HandleFunc("DELETE /accounts/{accountId}/mute", linstromUnmuteAccount)
|
||||||
|
// Report
|
||||||
|
router.HandleFunc("POST /accounts/{accountId}/reports", linstromReportAccount)
|
||||||
|
router.HandleFunc("DELETE /accounts/{accountId}/reports", linstromRetractReportAccount)
|
||||||
|
// Admin
|
||||||
|
router.HandleFunc("POST /accounts/{accountId}/admin/roles", linstromAdminAddRoleAccount)
|
||||||
|
router.HandleFunc(
|
||||||
|
"DELETE /accounts/{accountId}/admin/roles/{roleName}",
|
||||||
|
linstromAdminRemoveRoleAccount,
|
||||||
|
)
|
||||||
|
router.HandleFunc("POST /accounts/{accountId}/admin/warn", linstromAdminWarnAccount)
|
||||||
|
|
||||||
|
// Roles
|
||||||
|
router.HandleFunc("GET /roles/{roleId}", linstromGetRole)
|
||||||
|
router.HandleFunc("POST /roles", linstromCreateRole)
|
||||||
|
router.HandleFunc("PATCH /roles/{roleId}", linstromUpdateRole)
|
||||||
|
router.HandleFunc("DELETE /roles/{roleId}", linstromDeleteRole)
|
||||||
|
|
||||||
|
// Media metadata
|
||||||
|
router.HandleFunc("GET /media/{mediaId}", linstromGetMediaMetadata)
|
||||||
|
router.HandleFunc("POST /media", linstromNewMediaMetadata)
|
||||||
|
router.HandleFunc("PATCH /media/{mediaId}", linstromUpdateMediaMetadata)
|
||||||
|
router.HandleFunc("DELETE /media/{mediaId}", linstromDeleteMediaMetadata)
|
||||||
|
|
||||||
// Event streams
|
// Event streams
|
||||||
router.HandleFunc("/streams", linstromEventStream)
|
router.HandleFunc("/streams", linstromEventStream)
|
||||||
|
|
41
server/apiLinstromAccounts.go
Normal file
41
server/apiLinstromAccounts.go
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/hlog"
|
||||||
|
)
|
||||||
|
|
||||||
|
// No create account. That happens during passkey registration
|
||||||
|
// and remote accounts are getting created at fetch time
|
||||||
|
func linstromGetAccount(w http.ResponseWriter, r *http.Request) {
|
||||||
|
store := StorageFromRequest(r)
|
||||||
|
log := hlog.FromRequest(r)
|
||||||
|
|
||||||
|
}
|
||||||
|
func linstromUpdateAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromDeleteAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
|
||||||
|
func linstromIsFollowingAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromFollowAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromUnfollowAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
|
||||||
|
func linstromIsBlockingAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromBlockAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromUnblockAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
|
||||||
|
func linstromIsMutedAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromMuteAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromUnmuteAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
|
||||||
|
func linstromReportAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromRetractReportAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
|
||||||
|
func linstromAdminAddRoleAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromAdminRemoveRoleAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromAdminWarnAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
|
||||||
|
func linstromGetRole(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromCreateRole(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromUpdateRole(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromDeleteRole(w http.ResponseWriter, r *http.Request) {}
|
8
server/apiLinstromMedia.go
Normal file
8
server/apiLinstromMedia.go
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
func linstromGetMediaMetadata(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromNewMediaMetadata(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromUpdateMediaMetadata(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
func linstromDeleteMediaMetadata(w http.ResponseWriter, r *http.Request) {}
|
|
@ -9,6 +9,8 @@ func linstromGetNote(w http.ResponseWriter, r *http.Request) {
|
||||||
store := StorageFromRequest(r)
|
store := StorageFromRequest(r)
|
||||||
noteId := NoteIdFromRequest(r)
|
noteId := NoteIdFromRequest(r)
|
||||||
note, err := store.FindNoteById(noteId)
|
note, err := store.FindNoteById(noteId)
|
||||||
|
_ = note
|
||||||
|
_ = err
|
||||||
}
|
}
|
||||||
func linstromUpdateNote(w http.ResponseWriter, r *http.Request) {}
|
func linstromUpdateNote(w http.ResponseWriter, r *http.Request) {}
|
||||||
func linstromNewNote(w http.ResponseWriter, r *http.Request) {}
|
func linstromNewNote(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
|
|
@ -4,6 +4,15 @@ package server
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ = linstromNote{}
|
||||||
|
_ = linstromOriginServer{}
|
||||||
|
_ = linstromMediaMetadata{}
|
||||||
|
_ = linstromAccount{}
|
||||||
|
_ = linstromCustomAccountField{}
|
||||||
|
_ = linstromRole{}
|
||||||
|
)
|
||||||
|
|
||||||
type linstromNote struct {
|
type linstromNote struct {
|
||||||
Id string `jsonapi:"primary,notes"`
|
Id string `jsonapi:"primary,notes"`
|
||||||
RawContent string `jsonapi:"attr,content"`
|
RawContent string `jsonapi:"attr,content"`
|
||||||
|
@ -29,7 +38,7 @@ type linstromOriginServer struct {
|
||||||
Id int `jsonapi:"primary,origins"`
|
Id int `jsonapi:"primary,origins"`
|
||||||
CreatedAt time.Time `jsonapi:"attr,created_at"`
|
CreatedAt time.Time `jsonapi:"attr,created_at"`
|
||||||
UpdatedAt *time.Time `jsonapi:"attr,updated_at,omitempty"`
|
UpdatedAt *time.Time `jsonapi:"attr,updated_at,omitempty"`
|
||||||
ServerType string `jsonapi:"attr,server_type"` // one of "Linstrom", ""
|
ServerType string `jsonapi:"attr,server_type"` // one of "Linstrom", "Mastodon", "Plemora", "Misskey" or "Wafrn"
|
||||||
Domain string `jsonapi:"attr,domain"`
|
Domain string `jsonapi:"attr,domain"`
|
||||||
DisplayName string `jsonapi:"attr,display_name"`
|
DisplayName string `jsonapi:"attr,display_name"`
|
||||||
Icon *linstromMediaMetadata `jsonapi:"relation,icon"`
|
Icon *linstromMediaMetadata `jsonapi:"relation,icon"`
|
||||||
|
@ -68,10 +77,11 @@ type linstromAccount struct {
|
||||||
RestrictedFollow bool `jsonapi:"attr,restricted_follow"`
|
RestrictedFollow bool `jsonapi:"attr,restricted_follow"`
|
||||||
IdentifiesAs []string `jsonapi:"attr,identifies_as"`
|
IdentifiesAs []string `jsonapi:"attr,identifies_as"`
|
||||||
Pronouns []string `jsonapi:"attr,pronouns"`
|
Pronouns []string `jsonapi:"attr,pronouns"`
|
||||||
|
Roles []string `jsonapi:"attr,roles"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type linstromCustomAccountField struct {
|
type linstromCustomAccountField struct {
|
||||||
Id uint
|
Id uint `jsonapi:"primary,custom_account_fields"`
|
||||||
CreatedAt time.Time `jsonapi:"attr,created_at"`
|
CreatedAt time.Time `jsonapi:"attr,created_at"`
|
||||||
UpdatedAt *time.Time `jsonapi:"attr,updated_at,omitempty"`
|
UpdatedAt *time.Time `jsonapi:"attr,updated_at,omitempty"`
|
||||||
Key string `jsonapi:"attr,key"`
|
Key string `jsonapi:"attr,key"`
|
||||||
|
@ -79,3 +89,86 @@ type linstromCustomAccountField struct {
|
||||||
Verified *bool `jsonapi:"attr,verified,omitempty"`
|
Verified *bool `jsonapi:"attr,verified,omitempty"`
|
||||||
BelongsToId string `jsonapi:"attr,belongs_to_id"`
|
BelongsToId string `jsonapi:"attr,belongs_to_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Role is essentially just a carbon copy of storage/roles.go
|
||||||
|
type linstromRole struct {
|
||||||
|
Id uint `jsonapi:"primary,roles"`
|
||||||
|
CreatedAt time.Time `jsonapi:"attr,created_at"`
|
||||||
|
UpdatedAt *time.Time `jsonapi:"attr,updated_at,omitempty"`
|
||||||
|
|
||||||
|
// Name of the role
|
||||||
|
Name string `jsonapi:"attr,name"`
|
||||||
|
|
||||||
|
// Priority of the role
|
||||||
|
// Lower priority gets applied first and thus overwritten by higher priority ones
|
||||||
|
// If two roles have the same priority, the order is undetermined and may be random
|
||||||
|
// Default priority for new roles is 1 to always overwrite default user
|
||||||
|
// And full admin has max priority possible
|
||||||
|
Priority uint `jsonapi:"attr,priority"`
|
||||||
|
// Whether this role is for a for a single user only (like custom, per user permissions in Discord)
|
||||||
|
// If yes, Name will be the id of the user in question
|
||||||
|
IsUserRole bool `jsonapi:"attr,is_user_role"`
|
||||||
|
|
||||||
|
// Whether this role is one built into Linstrom from the start or not
|
||||||
|
// Note: Built-in roles can't be modified
|
||||||
|
IsBuiltIn bool `jsonapi:"attr,is_builtin"`
|
||||||
|
|
||||||
|
// --- User permissions ---
|
||||||
|
CanSendMedia *bool `jsonapi:"attr,can_send_media"`
|
||||||
|
CanSendCustomEmotes *bool `jsonapi:"attr,can_send_custom_emotes"`
|
||||||
|
CanSendCustomReactions *bool `jsonapi:"attr,can_send_custom_reactions"`
|
||||||
|
CanSendPublicNotes *bool `jsonapi:"attr,can_send_public_notes"`
|
||||||
|
CanSendLocalNotes *bool `jsonapi:"attr,can_send_local_notes"`
|
||||||
|
CanSendFollowerOnlyNotes *bool `jsonapi:"attr,can_send_follower_only_notes"`
|
||||||
|
CanSendPrivateNotes *bool `jsonapi:"attr,can_send_private_notes"`
|
||||||
|
CanSendReplies *bool `jsonapi:"attr,can_send_replies"`
|
||||||
|
CanQuote *bool `jsonapi:"attr,can_quote"`
|
||||||
|
CanBoost *bool `jsonapi:"attr,can_boost"`
|
||||||
|
CanIncludeLinks *bool `jsonapi:"attr,can_include_links"`
|
||||||
|
CanIncludeSurvey *bool `jsonapi:"attr,can_include_survey"`
|
||||||
|
|
||||||
|
CanChangeDisplayName *bool `jsonapi:"attr,can_change_display_name"`
|
||||||
|
|
||||||
|
BlockedUsers []string `jsonapi:"attr,blocked_users"`
|
||||||
|
CanSubmitReports *bool `jsonapi:"attr,can_submit_reports"`
|
||||||
|
CanLogin *bool `jsonapi:"attr,can_login"`
|
||||||
|
|
||||||
|
CanMentionOthers *bool `jsonapi:"attr,can_mention_others"`
|
||||||
|
HasMentionCountLimit *bool `jsonapi:"attr,has_mention_count_limit"`
|
||||||
|
MentionLimit *uint32 `jsonapi:"attr,mention_count_limit"`
|
||||||
|
|
||||||
|
// CanViewBoosts *bool
|
||||||
|
// CanViewQuotes *bool
|
||||||
|
// CanViewMedia *bool
|
||||||
|
// CanViewCustomEmotes *bool
|
||||||
|
|
||||||
|
// --- Automod ---
|
||||||
|
AutoNsfwMedia *bool `jsonapi:"attr,auto_nsfw_media"`
|
||||||
|
AutoCwPosts *bool `jsonapi:"attr,auto_cw_posts"`
|
||||||
|
AutoCwPostsText *string `jsonapi:"attr,auto_cw_posts_text"`
|
||||||
|
ScanCreatedPublicNotes *bool `jsonapi:"attr,scan_created_public_notes"`
|
||||||
|
ScanCreatedLocalNotes *bool `jsonapi:"attr,scan_created_local_notes"`
|
||||||
|
ScanCreatedFollowerOnlyNotes *bool `jsonapi:"attr,scan_created_follower_only_notes"`
|
||||||
|
ScanCreatedPrivateNotes *bool `jsonapi:"attr,scan_created_private_notes"`
|
||||||
|
DisallowInteractionsWith []string `jsonapi:"attr,disallow_interactions_with"`
|
||||||
|
|
||||||
|
WithholdNotesForManualApproval *bool `jsonapi:"attr,withhold_notes_for_manual_approval"`
|
||||||
|
WithholdNotesBasedOnRegex *bool `jsonapi:"attr,withhold_notes_based_on_regex"`
|
||||||
|
WithholdNotesRegexes []string `jsonapi:"attr,withhold_notes_regexes"`
|
||||||
|
|
||||||
|
// --- Admin perms ---
|
||||||
|
// If set, counts as all permissions being set as given and all restrictions being disabled
|
||||||
|
FullAdmin *bool `jsonapi:"attr,full_admin"`
|
||||||
|
CanAffectOtherAdmins *bool `jsonapi:"attr,can_affect_other_admins"`
|
||||||
|
CanDeleteNotes *bool `jsonapi:"attr,can_delete_notes"`
|
||||||
|
CanConfirmWithheldNotes *bool `jsonapi:"attr,can_confirm_withheld_notes"`
|
||||||
|
CanAssignRoles *bool `jsonapi:"attr,can_assign_roles"`
|
||||||
|
CanSupressInteractionsBetweenUsers *bool `jsonapi:"attr,can_supress_interactions_between_users"`
|
||||||
|
CanOverwriteDisplayNames *bool `jsonapi:"attr,can_overwrite_display_names"`
|
||||||
|
CanManageCustomEmotes *bool `jsonapi:"attr,can_manage_custom_emotes"`
|
||||||
|
CanViewDeletedNotes *bool `jsonapi:"attr,can_view_deleted_notes"`
|
||||||
|
CanRecoverDeletedNotes *bool `jsonapi:"attr,can_recover_deleted_notes"`
|
||||||
|
CanManageAvatarDecorations *bool `jsonapi:"attr,can_manage_avatar_decorations"`
|
||||||
|
CanManageAds *bool `jsonapi:"attr,can_manage_ads"`
|
||||||
|
CanSendAnnouncements *bool `jsonapi:"attr,can_send_announcements"`
|
||||||
|
}
|
||||||
|
|
|
@ -8,11 +8,12 @@ func setupApiRouter() http.Handler {
|
||||||
router.Handle("/linstrom/", setupLinstromApiRouter())
|
router.Handle("/linstrom/", setupLinstromApiRouter())
|
||||||
|
|
||||||
// Section MastoApi
|
// Section MastoApi
|
||||||
|
// First segment are endpoints that will need to be moved to primary router since at top route
|
||||||
router.HandleFunc("GET /oauth/authorize", placeholderEndpoint)
|
router.HandleFunc("GET /oauth/authorize", placeholderEndpoint)
|
||||||
router.HandleFunc("POST /oauth/token", placeholderEndpoint)
|
router.HandleFunc("POST /oauth/token", placeholderEndpoint)
|
||||||
router.HandleFunc("POST /oauth/revoke", placeholderEndpoint)
|
router.HandleFunc("POST /oauth/revoke", placeholderEndpoint)
|
||||||
router.HandleFunc("GET /.well-known/oauth-authorization-server", placeholderEndpoint)
|
router.HandleFunc("GET /.well-known/oauth-authorization-server", placeholderEndpoint)
|
||||||
|
// These ones are actually mounted under /api/
|
||||||
router.HandleFunc("POST /v1/apps", placeholderEndpoint)
|
router.HandleFunc("POST /v1/apps", placeholderEndpoint)
|
||||||
router.HandleFunc("GET /v1/apps/verify_credentials", placeholderEndpoint)
|
router.HandleFunc("GET /v1/apps/verify_credentials", placeholderEndpoint)
|
||||||
router.HandleFunc("POST /v1/emails/confirmations", placeholderEndpoint)
|
router.HandleFunc("POST /v1/emails/confirmations", placeholderEndpoint)
|
||||||
|
|
|
@ -51,7 +51,7 @@ func fuckWithRegisterRequest(
|
||||||
) {
|
) {
|
||||||
log := hlog.FromRequest(r)
|
log := hlog.FromRequest(r)
|
||||||
log.Debug().Msg("Messing with register start request")
|
log.Debug().Msg("Messing with register start request")
|
||||||
store := StorageFromRequest(w, r)
|
store := StorageFromRequest(r)
|
||||||
if store == nil {
|
if store == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ func fuckWithLoginRequest(
|
||||||
) {
|
) {
|
||||||
log := hlog.FromRequest(r)
|
log := hlog.FromRequest(r)
|
||||||
log.Debug().Msg("Messing with login start request")
|
log.Debug().Msg("Messing with login start request")
|
||||||
store := StorageFromRequest(w, r)
|
store := StorageFromRequest(r)
|
||||||
if store == nil {
|
if store == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ func LoggingMiddleware(handler http.Handler) http.Handler {
|
||||||
|
|
||||||
func passkeyIdToAccountIdTransformerMiddleware(handler http.Handler) http.Handler {
|
func passkeyIdToAccountIdTransformerMiddleware(handler http.Handler) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
s := StorageFromRequest(w, r)
|
s := StorageFromRequest(r)
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -100,3 +100,55 @@ func profilingAuthenticationMiddleware(handler http.Handler) http.Handler {
|
||||||
handler.ServeHTTP(w, r)
|
handler.ServeHTTP(w, r)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Middleware for inserting a logged in account's id into the request context if a session exists
|
||||||
|
// Does not cancel requests ever. If an error occurs, it's treated as if no session is set
|
||||||
|
func checkSessionMiddleware(handler http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
cookie, err := r.Cookie("sid")
|
||||||
|
log := hlog.FromRequest(r)
|
||||||
|
if err != nil {
|
||||||
|
// No cookie is ok, this function is only for inserting account id into the context
|
||||||
|
// if one exists, not for checking permissions
|
||||||
|
log.Debug().Msg("No session cookie, passing along")
|
||||||
|
handler.ServeHTTP(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
store := StorageFromRequest(r)
|
||||||
|
session, ok := store.GetSession(cookie.Value)
|
||||||
|
if !ok {
|
||||||
|
// Failed to get session from cookie id. Log, then move on as if no session is set
|
||||||
|
log.Warn().
|
||||||
|
Str("session-id", cookie.Value).
|
||||||
|
Msg("Cookie with session id found, but session doesn't exist")
|
||||||
|
handler.ServeHTTP(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if session.Expires.Before(time.Now()) {
|
||||||
|
// Session expired. Move on as if no session was set
|
||||||
|
store.DeleteSession(cookie.Value)
|
||||||
|
handler.ServeHTTP(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
acc, err := store.FindAccountByPasskeyId(session.UserID)
|
||||||
|
if err != nil {
|
||||||
|
// Failed to get account for passkey id. Log, then move on as if no session is set
|
||||||
|
log.Error().
|
||||||
|
Err(err).
|
||||||
|
Bytes("passkey-id", session.UserID).
|
||||||
|
Msg("Failed to get account with passkey id while checking session. Ignoring session")
|
||||||
|
handler.ServeHTTP(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
handler.ServeHTTP(
|
||||||
|
w,
|
||||||
|
r.WithContext(
|
||||||
|
context.WithValue(
|
||||||
|
r.Context(),
|
||||||
|
ContextKeyActorId,
|
||||||
|
acc.ID,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -30,3 +30,7 @@ func StorageFromRequest(r *http.Request) *storage.Storage {
|
||||||
func NoteIdFromRequest(r *http.Request) string {
|
func NoteIdFromRequest(r *http.Request) string {
|
||||||
return r.PathValue("noteId")
|
return r.PathValue("noteId")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AccountIdFromRequest(r *http.Request) string {
|
||||||
|
return r.PathValue("accountId")
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
|
|
||||||
// For pretty printing during debug
|
// For pretty printing during debug
|
||||||
// If `go generate` is run, it'll generate the necessary function and data for pretty printing
|
// If `go generate` is run, it'll generate the necessary function and data for pretty printing
|
||||||
//go:generate stringer -type NoteTarget
|
//go:generate stringer -type NoteAccessLevel
|
||||||
|
|
||||||
// What feed a note is targeting (public, home, followers or dm)
|
// What feed a note is targeting (public, home, followers or dm)
|
||||||
type NoteAccessLevel uint8
|
type NoteAccessLevel uint8
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Code generated by "stringer -type NoteTarget"; DO NOT EDIT.
|
// Code generated by "stringer -type NoteAccessLevel"; DO NOT EDIT.
|
||||||
|
|
||||||
package storage
|
package storage
|
||||||
|
|
||||||
|
@ -15,23 +15,23 @@ func _() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_NoteTarget_name_0 = "NOTE_TARGET_PUBLIC"
|
_NoteAccessLevel_name_0 = "NOTE_TARGET_PUBLIC"
|
||||||
_NoteTarget_name_1 = "NOTE_TARGET_HOME"
|
_NoteAccessLevel_name_1 = "NOTE_TARGET_HOME"
|
||||||
_NoteTarget_name_2 = "NOTE_TARGET_FOLLOWERS"
|
_NoteAccessLevel_name_2 = "NOTE_TARGET_FOLLOWERS"
|
||||||
_NoteTarget_name_3 = "NOTE_TARGET_DM"
|
_NoteAccessLevel_name_3 = "NOTE_TARGET_DM"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (i NoteAccessLevel) String() string {
|
func (i NoteAccessLevel) String() string {
|
||||||
switch {
|
switch {
|
||||||
case i == 0:
|
case i == 0:
|
||||||
return _NoteTarget_name_0
|
return _NoteAccessLevel_name_0
|
||||||
case i == 2:
|
case i == 2:
|
||||||
return _NoteTarget_name_1
|
return _NoteAccessLevel_name_1
|
||||||
case i == 4:
|
case i == 4:
|
||||||
return _NoteTarget_name_2
|
return _NoteAccessLevel_name_2
|
||||||
case i == 8:
|
case i == 8:
|
||||||
return _NoteTarget_name_3
|
return _NoteAccessLevel_name_3
|
||||||
default:
|
default:
|
||||||
return "NoteTarget(" + strconv.FormatInt(int64(i), 10) + ")"
|
return "NoteAccessLevel(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -51,6 +51,8 @@ type Role struct {
|
||||||
CanBoost *bool
|
CanBoost *bool
|
||||||
CanIncludeLinks *bool
|
CanIncludeLinks *bool
|
||||||
CanIncludeSurvey *bool
|
CanIncludeSurvey *bool
|
||||||
|
CanFederateFedi *bool
|
||||||
|
CanFederateBsky *bool
|
||||||
|
|
||||||
CanChangeDisplayName *bool
|
CanChangeDisplayName *bool
|
||||||
|
|
||||||
|
@ -75,6 +77,11 @@ type Role struct {
|
||||||
ScanCreatedLocalNotes *bool
|
ScanCreatedLocalNotes *bool
|
||||||
ScanCreatedFollowerOnlyNotes *bool
|
ScanCreatedFollowerOnlyNotes *bool
|
||||||
ScanCreatedPrivateNotes *bool
|
ScanCreatedPrivateNotes *bool
|
||||||
|
// Blocks all interactions and federation between users with the role and all included ids/handles
|
||||||
|
// TODO: Decide whether this is a list of handles or of account ids
|
||||||
|
// Handles would increase the load due to having to search for them first
|
||||||
|
// while ids would require to store every single account mentioned
|
||||||
|
// which could cause escalating storage costs
|
||||||
DisallowInteractionsWith []string `gorm:"type:bytes;serializer:gob"`
|
DisallowInteractionsWith []string `gorm:"type:bytes;serializer:gob"`
|
||||||
|
|
||||||
WithholdNotesForManualApproval *bool
|
WithholdNotesForManualApproval *bool
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"gitlab.com/mstarongitlab/goutils/other"
|
"gitlab.com/mstarongitlab/goutils/other"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Default role every user has. Defines sane defaults for a normal user
|
||||||
|
// Will get overwritten by just about every other role due to every other role having higher priority
|
||||||
var DefaultUserRole = Role{
|
var DefaultUserRole = Role{
|
||||||
Name: "Default",
|
Name: "Default",
|
||||||
Priority: 0,
|
Priority: 0,
|
||||||
|
@ -19,10 +21,13 @@ var DefaultUserRole = Role{
|
||||||
CanSendLocalNotes: other.IntoPointer(true),
|
CanSendLocalNotes: other.IntoPointer(true),
|
||||||
CanSendFollowerOnlyNotes: other.IntoPointer(true),
|
CanSendFollowerOnlyNotes: other.IntoPointer(true),
|
||||||
CanSendPrivateNotes: other.IntoPointer(true),
|
CanSendPrivateNotes: other.IntoPointer(true),
|
||||||
|
CanSendReplies: other.IntoPointer(true),
|
||||||
CanQuote: other.IntoPointer(true),
|
CanQuote: other.IntoPointer(true),
|
||||||
CanBoost: other.IntoPointer(true),
|
CanBoost: other.IntoPointer(true),
|
||||||
CanIncludeLinks: other.IntoPointer(true),
|
CanIncludeLinks: other.IntoPointer(true),
|
||||||
CanIncludeSurvey: other.IntoPointer(true),
|
CanIncludeSurvey: other.IntoPointer(true),
|
||||||
|
CanFederateFedi: other.IntoPointer(true),
|
||||||
|
CanFederateBsky: other.IntoPointer(true),
|
||||||
|
|
||||||
CanChangeDisplayName: other.IntoPointer(true),
|
CanChangeDisplayName: other.IntoPointer(true),
|
||||||
|
|
||||||
|
@ -32,7 +37,9 @@ var DefaultUserRole = Role{
|
||||||
|
|
||||||
CanMentionOthers: other.IntoPointer(true),
|
CanMentionOthers: other.IntoPointer(true),
|
||||||
HasMentionCountLimit: other.IntoPointer(false),
|
HasMentionCountLimit: other.IntoPointer(false),
|
||||||
MentionLimit: other.IntoPointer(uint32(math.MaxUint32)), // Set this to max, even if not used due to *HasMentionCountLimit == false
|
MentionLimit: other.IntoPointer(
|
||||||
|
uint32(math.MaxUint32),
|
||||||
|
), // Set this to max, even if not used due to *HasMentionCountLimit == false
|
||||||
|
|
||||||
AutoNsfwMedia: other.IntoPointer(false),
|
AutoNsfwMedia: other.IntoPointer(false),
|
||||||
AutoCwPosts: other.IntoPointer(false),
|
AutoCwPosts: other.IntoPointer(false),
|
||||||
|
@ -59,7 +66,8 @@ var DefaultUserRole = Role{
|
||||||
CanSendAnnouncements: other.IntoPointer(false),
|
CanSendAnnouncements: other.IntoPointer(false),
|
||||||
}
|
}
|
||||||
|
|
||||||
var fullAdminRole = Role{
|
// Role providing maximum permissions
|
||||||
|
var FullAdminRole = Role{
|
||||||
Name: "fullAdmin",
|
Name: "fullAdmin",
|
||||||
Priority: math.MaxUint,
|
Priority: math.MaxUint,
|
||||||
IsUserRole: false,
|
IsUserRole: false,
|
||||||
|
@ -85,7 +93,9 @@ var fullAdminRole = Role{
|
||||||
|
|
||||||
CanMentionOthers: other.IntoPointer(true),
|
CanMentionOthers: other.IntoPointer(true),
|
||||||
HasMentionCountLimit: other.IntoPointer(false),
|
HasMentionCountLimit: other.IntoPointer(false),
|
||||||
MentionLimit: other.IntoPointer(uint32(math.MaxUint32)), // Set this to max, even if not used due to *HasMentionCountLimit == false
|
MentionLimit: other.IntoPointer(
|
||||||
|
uint32(math.MaxUint32),
|
||||||
|
), // Set this to max, even if not used due to *HasMentionCountLimit == false
|
||||||
|
|
||||||
AutoNsfwMedia: other.IntoPointer(false),
|
AutoNsfwMedia: other.IntoPointer(false),
|
||||||
AutoCwPosts: other.IntoPointer(false),
|
AutoCwPosts: other.IntoPointer(false),
|
||||||
|
@ -112,7 +122,67 @@ var fullAdminRole = Role{
|
||||||
CanSendAnnouncements: other.IntoPointer(true),
|
CanSendAnnouncements: other.IntoPointer(true),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Role for totally freezing an account, blocking all activity from it
|
||||||
|
var AccountFreezeRole = Role{
|
||||||
|
Name: "accountFreeze",
|
||||||
|
Priority: math.MaxUint - 1,
|
||||||
|
IsUserRole: false,
|
||||||
|
IsBuiltIn: true,
|
||||||
|
|
||||||
|
CanSendMedia: other.IntoPointer(false),
|
||||||
|
CanSendCustomEmotes: other.IntoPointer(false),
|
||||||
|
CanSendCustomReactions: other.IntoPointer(false),
|
||||||
|
CanSendPublicNotes: other.IntoPointer(false),
|
||||||
|
CanSendLocalNotes: other.IntoPointer(false),
|
||||||
|
CanSendFollowerOnlyNotes: other.IntoPointer(false),
|
||||||
|
CanSendPrivateNotes: other.IntoPointer(false),
|
||||||
|
CanSendReplies: other.IntoPointer(false),
|
||||||
|
CanQuote: other.IntoPointer(false),
|
||||||
|
CanBoost: other.IntoPointer(false),
|
||||||
|
CanIncludeLinks: other.IntoPointer(false),
|
||||||
|
CanIncludeSurvey: other.IntoPointer(false),
|
||||||
|
CanFederateBsky: other.IntoPointer(false),
|
||||||
|
CanFederateFedi: other.IntoPointer(false),
|
||||||
|
|
||||||
|
CanChangeDisplayName: other.IntoPointer(false),
|
||||||
|
|
||||||
|
BlockedUsers: []string{},
|
||||||
|
CanSubmitReports: other.IntoPointer(false),
|
||||||
|
CanLogin: other.IntoPointer(false),
|
||||||
|
|
||||||
|
CanMentionOthers: other.IntoPointer(false),
|
||||||
|
HasMentionCountLimit: other.IntoPointer(false),
|
||||||
|
MentionLimit: other.IntoPointer(
|
||||||
|
uint32(math.MaxUint32),
|
||||||
|
), // Set this to max, even if not used due to *HasMentionCountLimit == false
|
||||||
|
|
||||||
|
AutoNsfwMedia: other.IntoPointer(true),
|
||||||
|
AutoCwPosts: other.IntoPointer(false),
|
||||||
|
AutoCwPostsText: other.IntoPointer("Account frozen"),
|
||||||
|
WithholdNotesForManualApproval: other.IntoPointer(true),
|
||||||
|
ScanCreatedPublicNotes: other.IntoPointer(false),
|
||||||
|
ScanCreatedLocalNotes: other.IntoPointer(false),
|
||||||
|
ScanCreatedFollowerOnlyNotes: other.IntoPointer(false),
|
||||||
|
ScanCreatedPrivateNotes: other.IntoPointer(false),
|
||||||
|
DisallowInteractionsWith: []string{},
|
||||||
|
|
||||||
|
FullAdmin: other.IntoPointer(false),
|
||||||
|
CanAffectOtherAdmins: other.IntoPointer(false),
|
||||||
|
CanDeleteNotes: other.IntoPointer(false),
|
||||||
|
CanConfirmWithheldNotes: other.IntoPointer(false),
|
||||||
|
CanAssignRoles: other.IntoPointer(false),
|
||||||
|
CanSupressInteractionsBetweenUsers: other.IntoPointer(false),
|
||||||
|
CanOverwriteDisplayNames: other.IntoPointer(false),
|
||||||
|
CanManageCustomEmotes: other.IntoPointer(false),
|
||||||
|
CanViewDeletedNotes: other.IntoPointer(false),
|
||||||
|
CanRecoverDeletedNotes: other.IntoPointer(false),
|
||||||
|
CanManageAvatarDecorations: other.IntoPointer(false),
|
||||||
|
CanManageAds: other.IntoPointer(false),
|
||||||
|
CanSendAnnouncements: other.IntoPointer(false),
|
||||||
|
}
|
||||||
|
|
||||||
var allDefaultRoles = []*Role{
|
var allDefaultRoles = []*Role{
|
||||||
&DefaultUserRole,
|
&DefaultUserRole,
|
||||||
&fullAdminRole,
|
&FullAdminRole,
|
||||||
|
&AccountFreezeRole,
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue