Defaults and start of config
This commit is contained in:
parent
3086b0e9b4
commit
1fbdf7fc9d
6 changed files with 128 additions and 10 deletions
26
config/config.go
Normal file
26
config/config.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
type ConfigSSL struct {
|
||||||
|
HandleSSL bool // Whether Linstrom should handle SSL encryption itself
|
||||||
|
// If Linstrom is to handle SSL, whether it should use LetsEncrypt for certificates
|
||||||
|
UseLetsEncrypt *bool
|
||||||
|
// Path to the certificate if Linstrom is to handle SSL while not using LetsEncrypt
|
||||||
|
CertificateFile *string
|
||||||
|
// Mail adress to use in case of using LetsEncrypt
|
||||||
|
AdminMail *string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConfigGeneral struct {
|
||||||
|
Domain string // The domain this server operates under
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConfigAdmin struct {
|
||||||
|
Username string
|
||||||
|
PasswordHash string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
General ConfigGeneral
|
||||||
|
SSL ConfigSSL
|
||||||
|
Admin ConfigAdmin
|
||||||
|
}
|
|
@ -13,10 +13,21 @@ type MediaFile struct {
|
||||||
DeletedAt gorm.DeletedAt `gorm:"index"`
|
DeletedAt gorm.DeletedAt `gorm:"index"`
|
||||||
Remote bool // whether the attachment is a remote one
|
Remote bool // whether the attachment is a remote one
|
||||||
Link string // url if remote attachment, identifier if local
|
Link string // url if remote attachment, identifier if local
|
||||||
|
Type string // What media type this is, eg image/png
|
||||||
// Whether this media has been cached locally
|
// Whether this media has been cached locally
|
||||||
// Only really used for user and server icons, not attachments
|
// Only really used for user and server icons, not attachments
|
||||||
|
// If true, Link will be read as file path. url otherwise
|
||||||
// Reason: Attachments would take way to much space considering that they are often only loaded a few times at most
|
// Reason: Attachments would take way to much space considering that they are often only loaded a few times at most
|
||||||
// And caching a file for those few times would be a waste of storage
|
// 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
|
// Caching user and server icons locally however should reduce burden on remote servers by quite a bit though
|
||||||
LocallyCached bool
|
LocallyCached bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Placeholder media file. Acts as placeholder for media file fields that have not been initialised yet but need a value
|
||||||
|
var placeholderMediaFile = &MediaFile{
|
||||||
|
ID: "placeholder",
|
||||||
|
Remote: false,
|
||||||
|
Link: "placeholder", // TODO: Replace this with a file path to a staticly included image
|
||||||
|
Type: "image/png",
|
||||||
|
LocallyCached: true,
|
||||||
|
}
|
||||||
|
|
|
@ -26,3 +26,19 @@ type Note struct {
|
||||||
OriginServer string // Url of the origin server. Also the primary key for those
|
OriginServer string // Url of the origin server. Also the primary key for those
|
||||||
Tags []string `gorm:"serializer:json"` // Hashtags
|
Tags []string `gorm:"serializer:json"` // Hashtags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var placeholderNote = &Note{
|
||||||
|
ID: "placeholder",
|
||||||
|
Creator: "placeholder",
|
||||||
|
Remote: false,
|
||||||
|
RawContent: "placeholder",
|
||||||
|
ContentWarning: nil,
|
||||||
|
Attachments: []string{},
|
||||||
|
Emotes: []string{},
|
||||||
|
RepliesTo: nil,
|
||||||
|
Quotes: nil,
|
||||||
|
Target: NOTE_TARGET_HOME,
|
||||||
|
Pings: []string{},
|
||||||
|
OriginServer: "placeholder",
|
||||||
|
Tags: []string{},
|
||||||
|
}
|
||||||
|
|
|
@ -16,3 +16,11 @@ type RemoteServer struct {
|
||||||
Icon string // ID of a media file
|
Icon string // ID of a media file
|
||||||
IsSelf bool // Whether this server is yours truly
|
IsSelf bool // Whether this server is yours truly
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var placeholderServer = &RemoteServer{
|
||||||
|
ID: "placeholder",
|
||||||
|
ServerType: REMOTE_SERVER_LINSTROM,
|
||||||
|
Name: "placeholder",
|
||||||
|
Icon: "placeholder",
|
||||||
|
IsSelf: false,
|
||||||
|
}
|
||||||
|
|
|
@ -1,23 +1,26 @@
|
||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/glebarez/sqlite"
|
"github.com/glebarez/sqlite"
|
||||||
"gorm.io/driver/postgres"
|
"gorm.io/driver/postgres"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Storage is responsible for all database, cache and media related actions
|
||||||
|
// and serves as the lowest layer of the cake
|
||||||
type Storage struct {
|
type Storage struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build a new storage using sqlite as database backend
|
||||||
func NewStorageSqlite(filePath string) (*Storage, error) {
|
func NewStorageSqlite(filePath string) (*Storage, error) {
|
||||||
db, err := gorm.Open(sqlite.Open(filePath))
|
db, err := gorm.Open(sqlite.Open(filePath))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &Storage{
|
return storageFromEmptyDb(db)
|
||||||
db: db,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStoragePostgres(dbUrl string) (*Storage, error) {
|
func NewStoragePostgres(dbUrl string) (*Storage, error) {
|
||||||
|
@ -25,6 +28,35 @@ func NewStoragePostgres(dbUrl string) (*Storage, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return storageFromEmptyDb(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
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(
|
||||||
|
placeholderMediaFile,
|
||||||
|
placeholderUser(),
|
||||||
|
placeholderNote,
|
||||||
|
placeholderServer,
|
||||||
|
)
|
||||||
|
// 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
|
||||||
|
if res := db.FirstOrCreate(placeholderMediaFile); res.Error != nil {
|
||||||
|
return nil, fmt.Errorf("failed to add placeholder media file: %w", res.Error)
|
||||||
|
}
|
||||||
|
if res := db.FirstOrCreate(placeholderUser()); res.Error != nil {
|
||||||
|
return nil, fmt.Errorf("failed to add placeholder media file: %w", res.Error)
|
||||||
|
}
|
||||||
|
if res := db.FirstOrCreate(placeholderNote); res.Error != nil {
|
||||||
|
return nil, fmt.Errorf("failed to add placeholder media file: %w", res.Error)
|
||||||
|
}
|
||||||
|
if res := db.FirstOrCreate(placeholderServer); res.Error != nil {
|
||||||
|
return nil, fmt.Errorf("failed to add placeholder media file: %w", res.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// And finally, build the actual storage struct
|
||||||
return &Storage{
|
return &Storage{
|
||||||
db: db,
|
db: db,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
|
@ -12,7 +12,8 @@ import (
|
||||||
// This can be a bot, remote or not
|
// This can be a bot, remote or not
|
||||||
// If remote, this is used for caching the account
|
// If remote, this is used for caching the account
|
||||||
type User struct {
|
type User struct {
|
||||||
ID string `gorm:"primarykey"` // ID is the full handle, eg @max@example.com
|
ID string `gorm:"primarykey"` // ID is a uuid for this account
|
||||||
|
Handle string // Handle is the full handle, eg @max@example.com
|
||||||
CreatedAt time.Time // When this entry was created
|
CreatedAt time.Time // When this entry was created
|
||||||
UpdatedAt time.Time // When this account was last updated. Will also be used for refreshing remote accounts
|
UpdatedAt time.Time // When this account was last updated. Will also be used for refreshing remote accounts
|
||||||
DeletedAt gorm.DeletedAt `gorm:"index"`
|
DeletedAt gorm.DeletedAt `gorm:"index"`
|
||||||
|
@ -29,7 +30,7 @@ type User struct {
|
||||||
Background string // ID of a media file used as background image
|
Background string // ID of a media file used as background image
|
||||||
Banner string // ID of a media file used as banner
|
Banner string // ID of a media file used as banner
|
||||||
Indexable bool // Whether this account can be found by crawlers
|
Indexable bool // Whether this account can be found by crawlers
|
||||||
PublicKeyPem string // The public key of the account
|
PublicKeyPem *string // The public key of the account
|
||||||
// Whether this account restricts following
|
// Whether this account restricts following
|
||||||
// If true, the owner must approve of a follow request first
|
// If true, the owner must approve of a follow request first
|
||||||
RestrictedFollow bool
|
RestrictedFollow bool
|
||||||
|
@ -58,10 +59,34 @@ type User struct {
|
||||||
|
|
||||||
func NewEmptyUser() *User {
|
func NewEmptyUser() *User {
|
||||||
return &User{
|
return &User{
|
||||||
ID: uuid.NewString(),
|
ID: uuid.NewString(),
|
||||||
CreatedAt: time.Now(),
|
Handle: "placeholder",
|
||||||
UpdatedAt: time.Now(),
|
Remote: false,
|
||||||
Remote: false,
|
Server: "placeholder",
|
||||||
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 placeholderUser() *User {
|
||||||
|
tmp := NewEmptyUser()
|
||||||
|
tmp.ID = "placeholder"
|
||||||
|
return tmp
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue