commit 81760963b04501e237a2822570fb580104aacd0a
parent 0abe01ea225ba91a504a462b1d72a5c33655bd6f
Author: tsmethurst <tobi.smethurst@klarrio.com>
Date: Sat, 20 Mar 2021 19:04:27 +0100
formatting,comments
Diffstat:
5 files changed, 212 insertions(+), 87 deletions(-)
diff --git a/internal/config/config.go b/internal/config/config.go
@@ -48,7 +48,7 @@ func Default() *Config {
// TODO: find a way of doing this without code repetition, because having to
// repeat all values here and elsewhere is annoying and gonna be prone to mistakes.
return &Config{
- DBConfig: &DBConfig{},
+ DBConfig: &DBConfig{},
TemplateConfig: &TemplateConfig{},
}
}
@@ -56,7 +56,7 @@ func Default() *Config {
// Empty just returns an empty config
func Empty() *Config {
return &Config{
- DBConfig: &DBConfig{},
+ DBConfig: &DBConfig{},
TemplateConfig: &TemplateConfig{},
}
}
diff --git a/internal/gtsmodel/account.go b/internal/gtsmodel/account.go
@@ -26,60 +26,130 @@ import (
"time"
)
-// Account represents a GoToSocial user account
+// Account represents either a local or a remote fediverse account, gotosocial or otherwise (mastodon, pleroma, etc)
type Account struct {
+ /*
+ BASIC INFO
+ */
+
+ // id of this account in the local database; the end-user will never need to know this, it's strictly internal
+ ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull,unique"`
+ // Username of the account, should just be a string of [a-z0-9_]. Can be added to domain to create the full username in the form ``[username]@[domain]`` eg., ``user_96@example.org``
+ Username string `pg:",notnull,unique:userdomain"` // username and domain should be unique *with* each other
+ // Domain of the account, will be empty if this is a local account, otherwise something like ``example.org`` or ``mastodon.social``. Should be unique with username.
+ Domain string `pg:",unique:userdomain"` // username and domain
+
+ /*
+ ACCOUNT METADATA
+ */
+
+ // Avatar image for this account
Avatar
+ // Header image for this account
Header
- URI string
- URL string
- ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull"`
- Username string
- Domain string
- Secret string
- PrivateKey string
- PublicKey string
- RemoteURL string
- CreatedAt time.Time `pg:"type:timestamp,notnull"`
- UpdatedAt time.Time `pg:"type:timestamp,notnull"`
- Note string
- DisplayName string
+ // DisplayName for this account. Can be empty, then just the Username will be used for display purposes.
+ DisplayName string
+ // a key/value map of fields that this account has added to their profile
+ Fields map[string]string
+ // A note that this account has on their profile (ie., the account's bio/description of themselves)
+ Note string
+ // Is this a memorial account, ie., has the user passed away?
+ Memorial bool
+ // This account has moved this account id in the database
+ MovedToAccountID int
+ // When was this account created?
+ CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
+ // When was this account last updated?
+ UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
+ // When should this account function until
SubscriptionExpiresAt time.Time `pg:"type:timestamp"`
- Locked bool
- LastWebfingeredAt time.Time `pg:"type:timestamp"`
- InboxURL string
- OutboxURL string
- SharedInboxURL string
- FollowersURL string
- Protocol int
- Memorial bool
- MovedToAccountID int
- FeaturedCollectionURL string
- Fields map[string]string
- ActorType string
- Discoverable bool
- AlsoKnownAs string
- SilencedAt time.Time `pg:"type:timestamp"`
- SuspendedAt time.Time `pg:"type:timestamp"`
- TrustLevel int
- HideCollections bool
- SensitizedAt time.Time `pg:"type:timestamp"`
- SuspensionOrigin int
+
+ /*
+ PRIVACY SETTINGS
+ */
+
+ // Does this account need an approval for new followers?
+ Locked bool
+ // Should this account be shown in the instance's profile directory?
+ Discoverable bool
+
+ /*
+ ACTIVITYPUB THINGS
+ */
+
+ // What is the activitypub URI for this account discovered by webfinger?
+ URI string `pg:",unique"`
+ // At which URL can we see the user account in a web browser?
+ URL string `pg:",unique"`
+ // RemoteURL where this account is located. Will be empty if this is a local account.
+ RemoteURL string `pg:",unique"`
+ // Last time this account was located using the webfinger API.
+ LastWebfingeredAt time.Time `pg:"type:timestamp"`
+ // Address of this account's activitypub inbox, for sending activity to
+ InboxURL string `pg:",unique"`
+ // Address of this account's activitypub outbox
+ OutboxURL string `pg:",unique"`
+ // Don't support shared inbox right now so this is just a stub for a future implementation
+ SharedInboxURL string `pg:",unique"`
+ // URL for getting the followers list of this account
+ FollowersURL string `pg:",unique"`
+ // URL for getting the featured collection list of this account
+ FeaturedCollectionURL string `pg:",unique"`
+ // What type of activitypub actor is this account?
+ ActorType string
+ // This account is associated with x account id
+ AlsoKnownAs string
+
+ /*
+ CRYPTO FIELDS
+ */
+
+ Secret string
+ // Privatekey for validating activitypub requests, will obviously only be defined for local accounts
+ PrivateKey string
+ // Publickey for encoding activitypub requests, will be defined for both local and remote accounts
+ PublicKey string
+
+ /*
+ ADMIN FIELDS
+ */
+
+ // When was this account set to have all its media shown as sensitive?
+ SensitizedAt time.Time `pg:"type:timestamp"`
+ // When was this account silenced (eg., statuses only visible to followers, not public)?
+ SilencedAt time.Time `pg:"type:timestamp"`
+ // When was this account suspended (eg., don't allow it to log in/post, don't accept media/posts from this account)
+ SuspendedAt time.Time `pg:"type:timestamp"`
+ // How much do we trust this account 🤔
+ TrustLevel int
+ // Should we hide this account's collections?
+ HideCollections bool
+ // id of the user that suspended this account through an admin action
+ SuspensionOrigin int
}
+// Avatar represents the avatar for the account for display purposes
type Avatar struct {
- AvatarFileName string
- AvatarContentType string
- AvatarFileSize int
- AvatarUpdatedAt *time.Time `pg:"type:timestamp"`
- AvatarRemoteURL *url.URL `pg:"type:text"`
+ // File name of the avatar on local storage
+ AvatarFileName string
+ // Gif? png? jpeg?
+ AvatarContentType string
+ AvatarFileSize int
+ AvatarUpdatedAt *time.Time `pg:"type:timestamp"`
+ // Where can we retrieve the avatar?
+ AvatarRemoteURL *url.URL `pg:"type:text"`
AvatarStorageSchemaVersion int
}
+// Header represents the header of the account for display purposes
type Header struct {
- HeaderFileName string
- HeaderContentType string
- HeaderFileSize int
- HeaderUpdatedAt *time.Time `pg:"type:timestamp"`
- HeaderRemoteURL *url.URL `pg:"type:text"`
+ // File name of the header on local storage
+ HeaderFileName string
+ // Gif? png? jpeg?
+ HeaderContentType string
+ HeaderFileSize int
+ HeaderUpdatedAt *time.Time `pg:"type:timestamp"`
+ // Where can we retrieve the header?
+ HeaderRemoteURL *url.URL `pg:"type:text"`
HeaderStorageSchemaVersion int
}
diff --git a/internal/gtsmodel/status.go b/internal/gtsmodel/status.go
@@ -22,11 +22,11 @@ import "time"
type Status struct {
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull"`
- URI string
- URL string
+ URI string `pg:",unique"`
+ URL string `pg:",unique"`
Content string
- CreatedAt time.Time `pg:"type:timestamp,notnull"`
- UpdatedAt time.Time `pg:"type:timestamp,notnull"`
+ CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
+ UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
Local bool
AccountID string
InReplyToID string
diff --git a/internal/gtsmodel/user.go b/internal/gtsmodel/user.go
@@ -23,43 +23,98 @@ import (
"time"
)
+// User represents an actual human user of gotosocial. Note, this is a LOCAL gotosocial user, not a remote account.
+// To cross reference this local user with their account (which can be local or remote), use the AccountID field.
type User struct {
- ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull"`
- Email string `pg:",notnull"`
- CreatedAt time.Time `pg:"type:timestamp,notnull"`
- UpdatedAt time.Time `pg:"type:timestamp,notnull"`
- EncryptedPassword string `pg:",notnull"`
- ResetPasswordToken string
- ResetPasswordSentAt time.Time `pg:"type:timestamp"`
- SignInCount int
- CurrentSignInAt time.Time `pg:"type:timestamp"`
- LastSignInAt time.Time `pg:"type:timestamp"`
- CurrentSignInIP net.IP
- LastSignInIP net.IP
- Admin bool
- ConfirmationToken string
- ConfirmedAt time.Time `pg:"type:timestamp"`
- ConfirmationSentAt time.Time `pg:"type:timestamp"`
- UnconfirmedEmail string
- Locale string
+ /*
+ BASIC INFO
+ */
+
+ // id of this user in the local database; the end-user will never need to know this, it's strictly internal
+ ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull,unique"`
+ // confirmed email address for this user, this should be unique -- only one email address registered per instance, multiple users per email are not supported
+ Email string `pg:",notnull,unique"`
+ // The id of the local gtsmodel.Account entry for this user, if it exists (unconfirmed users don't have an account yet)
+ AccountID string `pg:"default:'',notnull,unique"`
+ // The encrypted password of this user, generated using https://pkg.go.dev/golang.org/x/crypto/bcrypt#GenerateFromPassword. A salt is included so we're safe against 🌈 tables
+ EncryptedPassword string `pg:",notnull"`
+
+ /*
+ USER METADATA
+ */
+
+ // When was this user created?
+ CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
+ // From what IP was this user created?
+ SignUpIP net.IP
+ // When was this user updated (eg., password changed, email address changed)?
+ UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
+ // When did this user sign in for their current session?
+ CurrentSignInAt time.Time `pg:"type:timestamp"`
+ // What's the most recent IP of this user
+ CurrentSignInIP net.IP
+ // When did this user last sign in?
+ LastSignInAt time.Time `pg:"type:timestamp"`
+ // What's the previous IP of this user?
+ LastSignInIP net.IP
+ // How many times has this user signed in?
+ SignInCount int
+ // id of the user who invited this user (who let this guy in?)
+ InviteID string
+ // What languages does this user want to see?
+ ChosenLanguages []string
+ // What languages does this user not want to see?
+ FilteredLanguages []string
+ // In what timezone/locale is this user located?
+ Locale string
+ // Which application id created this user? See gtsmodel.Application
+ CreatedByApplicationID string
+ // When did we last contact this user
+ LastEmailedAt time.Time `pg:"type:timestamp"`
+
+ /*
+ USER CONFIRMATION
+ */
+
+ // What confirmation token did we send this user/what are we expecting back?
+ ConfirmationToken string
+ // When did the user confirm their email address
+ ConfirmedAt time.Time `pg:"type:timestamp"`
+ // When did we send email confirmation to this user?
+ ConfirmationSentAt time.Time `pg:"type:timestamp"`
+ // Email address that hasn't yet been confirmed
+ UnconfirmedEmail string
+
+ /*
+ ACL FLAGS
+ */
+
+ // Is this user a moderator?
+ Moderator bool
+ // Is this user an admin?
+ Admin bool
+ // Is this user disabled from posting?
+ Disabled bool
+ // Has this user been approved by a moderator?
+ Approved bool
+
+ /*
+ USER SECURITY
+ */
+
+ // The generated token that the user can use to reset their password
+ ResetPasswordToken string
+ // When did we email the user their reset-password email?
+ ResetPasswordSentAt time.Time `pg:"type:timestamp"`
+
EncryptedOTPSecret string
EncryptedOTPSecretIv string
EncryptedOTPSecretSalt string
- ConsumedTimestamp int
OTPRequiredForLogin bool
- LastEmailedAt time.Time `pg:"type:timestamp"`
OTPBackupCodes []string
- FilteredLanguages []string
- AccountID string `pg:",notnull"`
- Disabled bool
- Moderator bool
- InviteID string
- RememberToken string
- ChosenLanguages []string
- CreatedByApplicationID string
- Approved bool
- SignInToken string
- SignInTokenSentAt time.Time `pg:"type:timestamp"`
- WebauthnID string
- SignUpIP net.IP
+ ConsumedTimestamp int
+ RememberToken string
+ SignInToken string
+ SignInTokenSentAt time.Time `pg:"type:timestamp"`
+ WebauthnID string
}
diff --git a/pkg/mastotypes/oauth.go b/pkg/mastotypes/oauth.go
@@ -22,16 +22,16 @@ package mastotypes
// See here: https://docs.joinmastodon.org/methods/apps/oauth/
type OAuthAuthorize struct {
// Forces the user to re-login, which is necessary for authorizing with multiple accounts from the same instance.
- ForceLogin string `form:"force_login,omitempty"`
+ ForceLogin string `form:"force_login,omitempty"`
// Should be set equal to `code`.
ResponseType string `form:"response_type"`
// Client ID, obtained during app registration.
- ClientID string `form:"client_id"`
+ ClientID string `form:"client_id"`
// Set a URI to redirect the user to.
// If this parameter is set to urn:ietf:wg:oauth:2.0:oob then the authorization code will be shown instead.
// Must match one of the redirect URIs declared during app registration.
- RedirectURI string `form:"redirect_uri"`
+ RedirectURI string `form:"redirect_uri"`
// List of requested OAuth scopes, separated by spaces (or by pluses, if using query parameters).
// Must be a subset of scopes declared during app registration. If not provided, defaults to read.
- Scope string `form:"scope,omitempty"`
+ Scope string `form:"scope,omitempty"`
}