sync for backup
This commit is contained in:
parent
1fbdf7fc9d
commit
a9916acea5
92 changed files with 35330 additions and 882 deletions
|
@ -21,6 +21,7 @@ type MediaFile struct {
|
|||
// And caching a file for those few times would be a waste of storage
|
||||
// Caching user and server icons locally however should reduce burden on remote servers by quite a bit though
|
||||
LocallyCached bool
|
||||
Sensitive bool // Whether the media is marked as sensitive. If so, hide it in the UI by default
|
||||
}
|
||||
|
||||
// Placeholder media file. Acts as placeholder for media file fields that have not been initialised yet but need a value
|
||||
|
|
|
@ -42,3 +42,13 @@ var placeholderNote = &Note{
|
|||
OriginServer: "placeholder",
|
||||
Tags: []string{},
|
||||
}
|
||||
|
||||
// Try and find a note with a given ID
|
||||
func (store *Storage) FindNoteById(id string) (*Note, error) {
|
||||
note := Note{}
|
||||
res := store.db.First(¬e, id)
|
||||
if res.Error != nil {
|
||||
return nil, res.Error
|
||||
}
|
||||
return ¬e, nil
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/glebarez/sqlite"
|
||||
|
@ -14,6 +15,8 @@ type Storage struct {
|
|||
db *gorm.DB
|
||||
}
|
||||
|
||||
var ErrAccountNotFound = errors.New("account not found")
|
||||
|
||||
// Build a new storage using sqlite as database backend
|
||||
func NewStorageSqlite(filePath string) (*Storage, error) {
|
||||
db, err := gorm.Open(sqlite.Open(filePath))
|
||||
|
@ -34,12 +37,14 @@ func NewStoragePostgres(dbUrl string) (*Storage, error) {
|
|||
func storageFromEmptyDb(db *gorm.DB) (*Storage, error) {
|
||||
// AutoMigrate ensures the db is in a state where all the structs given here
|
||||
// have their own tables and relations setup. It also updates tables if necessary
|
||||
db.AutoMigrate(
|
||||
if err := db.AutoMigrate(
|
||||
placeholderMediaFile,
|
||||
placeholderUser(),
|
||||
placeholderUser,
|
||||
placeholderNote,
|
||||
placeholderServer,
|
||||
)
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("problem while auto migrating: %w", err)
|
||||
}
|
||||
// Afterwards add the placeholder entries for each table.
|
||||
// FirstOrCreate either creates a new entry or retrieves the first matching one
|
||||
// We only care about the creation if there is none yet, so no need to carry the result over
|
||||
|
@ -62,7 +67,14 @@ func storageFromEmptyDb(db *gorm.DB) (*Storage, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// TODO: Placeholder. Update to proper implementation later. Including signature
|
||||
func (s *Storage) FindLocalAccount(handle string) (string, error) {
|
||||
return handle, nil
|
||||
func (s *Storage) FindLocalAccount(handle string) (*User, error) {
|
||||
acc := User{}
|
||||
res := s.db.Where("handle = ?", handle).First(&acc)
|
||||
if res.Error != nil {
|
||||
return nil, fmt.Errorf("failed to query db: %w", res.Error)
|
||||
}
|
||||
if res.RowsAffected == 0 {
|
||||
return nil, ErrAccountNotFound
|
||||
}
|
||||
return nil, errors.New("unimplemented")
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-webauthn/webauthn/webauthn"
|
||||
|
@ -55,6 +58,35 @@ type User struct {
|
|||
// Access should be rare enough anyway
|
||||
Passkeys map[string]webauthn.Credential `gorm:"serializer:json"`
|
||||
PrivateKeyPem *string // The private key of the account. Nil if remote user
|
||||
// Restrictions applied to the account
|
||||
// Flag value, can be multiple
|
||||
Restrictions AccountRestriction
|
||||
}
|
||||
|
||||
var placeholderUser = &User{
|
||||
ID: "placeholder",
|
||||
Handle: "placeholder",
|
||||
Remote: false,
|
||||
Server: "placeholder",
|
||||
DisplayName: "placeholder",
|
||||
CustomFields: []uint{},
|
||||
Description: "placeholder",
|
||||
Tags: []string{},
|
||||
IsBot: true,
|
||||
Follows: []string{},
|
||||
Followers: []string{},
|
||||
Icon: "placeholder",
|
||||
Background: "placeholder",
|
||||
Banner: "placeholder",
|
||||
Indexable: false,
|
||||
PublicKeyPem: nil,
|
||||
RestrictedFollow: false,
|
||||
IdentifiesAs: []Being{BEING_ROBOT},
|
||||
Gender: []string{"it", "its"},
|
||||
PasswordHash: []byte("placeholder"),
|
||||
TotpToken: []byte("placeholder"),
|
||||
Passkeys: map[string]webauthn.Credential{},
|
||||
PrivateKeyPem: nil,
|
||||
}
|
||||
|
||||
func NewEmptyUser() *User {
|
||||
|
@ -85,8 +117,32 @@ func NewEmptyUser() *User {
|
|||
}
|
||||
}
|
||||
|
||||
func placeholderUser() *User {
|
||||
tmp := NewEmptyUser()
|
||||
tmp.ID = "placeholder"
|
||||
return tmp
|
||||
// Get a stored user by the ID the user has been stored with
|
||||
// Either returns a valid user and nil for the error
|
||||
// Or nil for the user and an error
|
||||
func (s *Storage) GetUserByID(id string) (*User, error) {
|
||||
user := User{}
|
||||
res := s.db.First(&user, "id = ?", id)
|
||||
// Check if any error except NotFound occured
|
||||
// If so, wrap it a little
|
||||
if res.Error != nil && !errors.Is(res.Error, gorm.ErrRecordNotFound) {
|
||||
return nil, fmt.Errorf("problem while getting user from db: %w", res.Error)
|
||||
}
|
||||
// Then check if an error occured and said error is NotFound
|
||||
// If it is, just pass it forward
|
||||
if res.Error != nil && errors.Is(res.Error, gorm.ErrRecordNotFound) {
|
||||
return nil, res.Error
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
// Get only the name part of the handle a user has
|
||||
func (u *User) GetHandleNameOnly() string {
|
||||
// First remove the leading @ (TrimPrefix) to achieve a format of username@server
|
||||
// Then split at the @ to the server and user seperately
|
||||
// And return the first element since that is the username
|
||||
// Note: Getting the first element will always be safe
|
||||
// since trim returns a string guaranteed (empty is ok)
|
||||
// and if Split doesn't do anything (eg empty string) it just returns the input in the first elemen it just returns the input in the first element
|
||||
return strings.Split(strings.TrimPrefix(u.Handle, "@"), "@")[0]
|
||||
}
|
||||
|
|
34
storage/userRestrictionType.go
Normal file
34
storage/userRestrictionType.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package storage
|
||||
|
||||
type AccountRestriction int64
|
||||
|
||||
const (
|
||||
// Account has no restrictions applied
|
||||
ACCOUNT_RESTRICTION_NONE = AccountRestriction(0)
|
||||
// All messages of the account get a content warning applied if none is set
|
||||
// Warning could be something like "Message auto-CWd by server"
|
||||
ACCOUNT_RESTRICTION_AUTO_CW = AccountRestriction(1 << iota)
|
||||
// Disable accessing the account via login or access token
|
||||
ACCOUNT_RESTRICTION_DISABLE_LOGIN
|
||||
// Disable sending activities to other servers if the account is local
|
||||
// Or reject all activities if the account is remote
|
||||
ACCOUNT_RESTRICTION_NO_FEDERATION
|
||||
// Disallow sending direct messages from that account
|
||||
ACCOUNT_RESTRICTION_NO_DMS
|
||||
// Disallow sending follower only messages from that account
|
||||
ACCOUNT_RESTRICTION_NO_FOLLOWER_POSTS
|
||||
// Disable outbound follow requests (restricted account can't send follow requests)
|
||||
ACCOUNT_RESTRICTION_DISABLE_OUTBOUND_FOLLOWS
|
||||
// Disable inbound follow requests (all follow requests to that account are automatically rejected)
|
||||
ACCOUNT_RESTRICTION_DISABLE_INBOUND_FOLLOWS
|
||||
// Forces all posts by that account to be follower only
|
||||
ACCOUNT_RESTRICTION_FORCE_FOLLOWERS_ONLY
|
||||
// Disable all outbound activities of an account.
|
||||
// Includes sending, updating or deleting own notes
|
||||
// as well as boosting or reacting to any notes
|
||||
ACCOUNT_RESTRICTION_DISABLE_ACTIVITIES
|
||||
// Account can only be viewed while logged in or via verified requests to the AP endpoints
|
||||
ACCOUNT_RESTRICTIONS_NO_PUBLIC_ACCESS
|
||||
// Force tag all media the account posts as sensitive
|
||||
ACCOUNT_RESTRICTIONS_FORCE_MEDIA_SENSITIVE
|
||||
)
|
Loading…
Add table
Add a link
Reference in a new issue