linstrom/storage-new/models/User.go
mstar 5e93ecee73
Some checks failed
/ docker (push) Failing after 3m56s
User import now works
2025-04-15 17:18:56 +02:00

139 lines
5.4 KiB
Go

package models
import (
"database/sql"
"time"
"gorm.io/gen"
"gorm.io/gorm"
)
// A user describes an account for creating content and events.
// This may be controlled by either a human or some external script
//
// Data stored externally:
// - Feed connections (which note belongs in the feed of this user, for what reason), see [NoteToFeed]
type User struct {
// ID is a uuid for this account
//
// NOTE: Performance and storage wise, using a UUID (as string) for the primary key
// is not the best idea and it would be better to use incrementing integers
// Additionally, there is a risk with inconsistency if postgres crashes during a commit
// in which case the new entry might not have a valid Id with which it could be found
// and the username is lost until manual recovery
// However, a UUID is still necessary in some way to provide a (secondary) stable
// identifier for users and other servers, especially when changing the username
// (username != display name) might be a future feature
// Same also applies for other types that use a UUID as primary key
ID string `gorm:"primarykey;default:gen_random_uuid()"`
// Username of the user (eg "max" if the full username is @max@example.com)
// Assume unchangable (once set by a user) to be kind to other implementations
// Would be an easy avenue to fuck with them though
Username string `gorm:"unique"`
CreatedAt time.Time // When this entry was created. Automatically set by gorm
// When this account was last updated. Will also be used for refreshing remote accounts. Automatically set by gorm
UpdatedAt time.Time
// When this entry was deleted (for soft deletions)
// Soft delete means that this entry still exists in the db, but gorm won't include it anymore unless specifically told to
// If not null, this entry is marked as deleted
DeletedAt gorm.DeletedAt `gorm:"index"`
Server RemoteServer
ServerId uint // Id of the server this user is from, needed for including RemoteServer
DisplayName string // The display name of the user. Can be different from the handle
Description string // The description of a user account
IsBot bool // Whether to mark this account as a script controlled one
Icon *MediaMetadata
IconId sql.NullString // ID of a media file used as icon
Background *MediaMetadata
BackgroundId sql.NullString // ID of a media file used as background image
Banner *MediaMetadata
BannerId sql.NullString // ID of a media file used as banner
Indexable bool // Whether this account can be found by crawlers
PublicKeyRsa []byte // The public RSA key of the account
PublicKeyEd []byte // The public Ed25519 key of the account
// Whether this account restricts following
// If true, the owner must approve of a follow request first
RestrictedFollow bool
// Technically should be a timestamp, but can't trust other implementations
// to enforce this in a consistent format
Birthday sql.NullString
Location sql.NullString
// Whether the account got verified and is allowed to be active
// For local accounts being active means being allowed to login and perform interactions
// No impact on remote accounts
Verified bool
// 64 byte unique id for passkeys, because UUIDs are 128 bytes and passkey spec says 64 bytes max
// In theory, could also slash Id in half, but that would be a lot more calculations than the
// saved space is worth
PasskeyId []byte
FinishedRegistration bool // Whether this account has completed registration yet
PrivateKeyRsa []byte
PrivateKeyEd []byte
// ---- "Remote" linked values
InfoFields []UserInfoField
BeingTypes []UserToBeing
Tags []UserToTag
Relations []UserToUserRelation
Pronouns []UserToPronoun
Roles []UserToRole
RemoteInfo *UserRemoteLinks
RemoteInfoId sql.NullInt64
AuthMethods []UserAuthMethod
}
type IUser interface {
// Get a user by a username, ignoring all restrictions on that user
//
// SELECT * FROM @@table WHERE username = @username AND deleted_at IS NULL LIMIT 1
GetByUsernameUnrestricted(username string) (*gen.T, error)
// Get a user by the username.
// Restricted to users visible to ActivityPub
//
// SELECT * FROM @@table WHERE
// username = @username AND
// deleted_at IS NULL AND
// finished_registration = true AND
// verified = true
// LIMIT 1
GetByUsername(username string) (*gen.T, error)
// Get all true public accounts (verified & no restricted follow & indexable)
// in a paged manner, sorted by date saved
//
// SELECT * FROM @@table WHERE
// deleted_at IS NULL AND
// verified = true AND
// restricted_follow = false AND
// indexable = true
// ORDER BY created_at ASC
// LIMIT 50
// OFFSET @pageNr * 50
GetPagedTruePublic(pageNr uint) ([]gen.T, error)
// Get all deleted accounts in a paged manner, sorted by date saved
//
// SELECT * FROM @@table WHERE
// deleted_at IS NOT NULL AND
// ORDER BY created_at ASC
// LIMIT 50
// OFFSET @pageNr * 50
GetPagedAllDeleted(pageNr uint) ([]gen.T, error)
// Get all accounts that aren't deleted in a paged manner, sorted by date saved
//
// SELECT * FROM @@table WHERE
// deleted_at IS NULL
// ORDER BY created_at ASC
// LIMIT 50
// OFFSET @pageNr * 50
GetPagedAllNonDeleted(pageNr uint) ([]gen.T, error)
// Gdpr deleted users
//
// DELETE FROM @@table WHERE deleted_at IS NOT NULL AND deleted_at + interval '30 days' < NOW()
GdprUsers() error
}