Big restructuring and initial work on activitypub
This commit is contained in:
Tobi Smethurst
2021-05-08 14:25:55 +02:00
committed by GitHub
parent ac9adb172b
commit 6f5c045284
183 changed files with 7391 additions and 5414 deletions

View File

@ -0,0 +1,5 @@
# gtsmodel
This package contains types used *internally* by GoToSocial and added/removed/selected from the database. As such, they contain sensitive fields which should **never** be serialized or reach the API level. Use the [mastotypes](../../pkg/mastotypes) package for that.
The annotation used on these structs is for handling them via the go-pg ORM. See [here](https://pg.uptrace.dev/models/).

View File

@ -0,0 +1,148 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Package gtsmodel contains types used *internally* by GoToSocial and added/removed/selected from the database.
// These types should never be serialized and/or sent out via public APIs, as they contain sensitive information.
// The annotation used on these structs is for handling them via the go-pg ORM (hence why they're in this db subdir).
// See here for more info on go-pg model annotations: https://pg.uptrace.dev/models/
package gtsmodel
import (
"crypto/rsa"
"time"
)
// 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 null 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 should be unique *with* each other
/*
ACCOUNT METADATA
*/
// ID of the avatar as a media attachment
AvatarMediaAttachmentID string
// For a non-local account, where can the header be fetched?
AvatarRemoteURL string
// ID of the header as a media attachment
HeaderMediaAttachmentID string
// For a non-local account, where can the header be fetched?
HeaderRemoteURL 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 []Field
// 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 string
// 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()"`
// Does this account identify itself as a bot?
Bot bool
// What reason was given for signing up when this account was created?
Reason string
/*
USER AND PRIVACY PREFERENCES
*/
// Does this account need an approval for new followers?
Locked bool
// Should this account be shown in the instance's profile directory?
Discoverable bool
// Default post privacy for this account
Privacy Visibility
// Set posts from this account to sensitive by default?
Sensitive bool
// What language does this account post in?
Language string
/*
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"`
// 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
InboxURI string `pg:",unique"`
// Address of this account's activitypub outbox
OutboxURI string `pg:",unique"`
// URI for getting the following list of this account
FollowingURI string `pg:",unique"`
// URI for getting the followers list of this account
FollowersURI string `pg:",unique"`
// URL for getting the featured collection list of this account
FeaturedCollectionURI string `pg:",unique"`
// What type of activitypub actor is this account?
ActorType ActivityStreamsActor
// This account is associated with x account id
AlsoKnownAs string
/*
CRYPTO FIELDS
*/
// Privatekey for validating activitypub requests, will obviously only be defined for local accounts
PrivateKey *rsa.PrivateKey
// Publickey for encoding activitypub requests, will be defined for both local and remote accounts
PublicKey *rsa.PublicKey
// Web-reachable location of this account's public key
PublicKeyURI 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"`
// Should we hide this account's collections?
HideCollections bool
// id of the user that suspended this account through an admin action
SuspensionOrigin string
}
// Field represents a key value field on an account, for things like pronouns, website, etc.
// VerifiedAt is optional, to be used only if Value is a URL to a webpage that contains the
// username of the user.
type Field struct {
Name string
Value string
VerifiedAt time.Time `pg:"type:timestamp"`
}

View File

@ -0,0 +1,127 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
// ActivityStreamsObject refers to https://www.w3.org/TR/activitystreams-vocabulary/#object-types
type ActivityStreamsObject string
const (
// ActivityStreamsArticle https://www.w3.org/TR/activitystreams-vocabulary/#dfn-article
ActivityStreamsArticle ActivityStreamsObject = "Article"
// ActivityStreamsAudio https://www.w3.org/TR/activitystreams-vocabulary/#dfn-audio
ActivityStreamsAudio ActivityStreamsObject = "Audio"
// ActivityStreamsDocument https://www.w3.org/TR/activitystreams-vocabulary/#dfn-document
ActivityStreamsDocument ActivityStreamsObject = "Event"
// ActivityStreamsEvent https://www.w3.org/TR/activitystreams-vocabulary/#dfn-event
ActivityStreamsEvent ActivityStreamsObject = "Event"
// ActivityStreamsImage https://www.w3.org/TR/activitystreams-vocabulary/#dfn-image
ActivityStreamsImage ActivityStreamsObject = "Image"
// ActivityStreamsNote https://www.w3.org/TR/activitystreams-vocabulary/#dfn-note
ActivityStreamsNote ActivityStreamsObject = "Note"
// ActivityStreamsPage https://www.w3.org/TR/activitystreams-vocabulary/#dfn-page
ActivityStreamsPage ActivityStreamsObject = "Page"
// ActivityStreamsPlace https://www.w3.org/TR/activitystreams-vocabulary/#dfn-place
ActivityStreamsPlace ActivityStreamsObject = "Place"
// ActivityStreamsProfile https://www.w3.org/TR/activitystreams-vocabulary/#dfn-profile
ActivityStreamsProfile ActivityStreamsObject = "Profile"
// ActivityStreamsRelationship https://www.w3.org/TR/activitystreams-vocabulary/#dfn-relationship
ActivityStreamsRelationship ActivityStreamsObject = "Relationship"
// ActivityStreamsTombstone https://www.w3.org/TR/activitystreams-vocabulary/#dfn-tombstone
ActivityStreamsTombstone ActivityStreamsObject = "Tombstone"
// ActivityStreamsVideo https://www.w3.org/TR/activitystreams-vocabulary/#dfn-video
ActivityStreamsVideo ActivityStreamsObject = "Video"
)
// ActivityStreamsActor refers to https://www.w3.org/TR/activitystreams-vocabulary/#actor-types
type ActivityStreamsActor string
const (
// ActivityStreamsApplication https://www.w3.org/TR/activitystreams-vocabulary/#dfn-application
ActivityStreamsApplication ActivityStreamsActor = "Application"
// ActivityStreamsGroup https://www.w3.org/TR/activitystreams-vocabulary/#dfn-group
ActivityStreamsGroup ActivityStreamsActor = "Group"
// ActivityStreamsOrganization https://www.w3.org/TR/activitystreams-vocabulary/#dfn-organization
ActivityStreamsOrganization ActivityStreamsActor = "Organization"
// ActivityStreamsPerson https://www.w3.org/TR/activitystreams-vocabulary/#dfn-person
ActivityStreamsPerson ActivityStreamsActor = "Person"
// ActivityStreamsService https://www.w3.org/TR/activitystreams-vocabulary/#dfn-service
ActivityStreamsService ActivityStreamsActor = "Service"
)
// ActivityStreamsActivity refers to https://www.w3.org/TR/activitystreams-vocabulary/#activity-types
type ActivityStreamsActivity string
const (
// ActivityStreamsAccept https://www.w3.org/TR/activitystreams-vocabulary/#dfn-accept
ActivityStreamsAccept ActivityStreamsActivity = "Accept"
// ActivityStreamsAdd https://www.w3.org/TR/activitystreams-vocabulary/#dfn-add
ActivityStreamsAdd ActivityStreamsActivity = "Add"
// ActivityStreamsAnnounce https://www.w3.org/TR/activitystreams-vocabulary/#dfn-announce
ActivityStreamsAnnounce ActivityStreamsActivity = "Announce"
// ActivityStreamsArrive https://www.w3.org/TR/activitystreams-vocabulary/#dfn-arrive
ActivityStreamsArrive ActivityStreamsActivity = "Arrive"
// ActivityStreamsBlock https://www.w3.org/TR/activitystreams-vocabulary/#dfn-block
ActivityStreamsBlock ActivityStreamsActivity = "Block"
// ActivityStreamsCreate https://www.w3.org/TR/activitystreams-vocabulary/#dfn-create
ActivityStreamsCreate ActivityStreamsActivity = "Create"
// ActivityStreamsDelete https://www.w3.org/TR/activitystreams-vocabulary/#dfn-delete
ActivityStreamsDelete ActivityStreamsActivity = "Delete"
// ActivityStreamsDislike https://www.w3.org/TR/activitystreams-vocabulary/#dfn-dislike
ActivityStreamsDislike ActivityStreamsActivity = "Dislike"
// ActivityStreamsFlag https://www.w3.org/TR/activitystreams-vocabulary/#dfn-flag
ActivityStreamsFlag ActivityStreamsActivity = "Flag"
// ActivityStreamsFollow https://www.w3.org/TR/activitystreams-vocabulary/#dfn-follow
ActivityStreamsFollow ActivityStreamsActivity = "Follow"
// ActivityStreamsIgnore https://www.w3.org/TR/activitystreams-vocabulary/#dfn-ignore
ActivityStreamsIgnore ActivityStreamsActivity = "Ignore"
// ActivityStreamsInvite https://www.w3.org/TR/activitystreams-vocabulary/#dfn-invite
ActivityStreamsInvite ActivityStreamsActivity = "Invite"
// ActivityStreamsJoin https://www.w3.org/TR/activitystreams-vocabulary/#dfn-join
ActivityStreamsJoin ActivityStreamsActivity = "Join"
// ActivityStreamsLeave https://www.w3.org/TR/activitystreams-vocabulary/#dfn-leave
ActivityStreamsLeave ActivityStreamsActivity = "Leave"
// ActivityStreamsLike https://www.w3.org/TR/activitystreams-vocabulary/#dfn-like
ActivityStreamsLike ActivityStreamsActivity = "Like"
// ActivityStreamsListen https://www.w3.org/TR/activitystreams-vocabulary/#dfn-listen
ActivityStreamsListen ActivityStreamsActivity = "Listen"
// ActivityStreamsMove https://www.w3.org/TR/activitystreams-vocabulary/#dfn-move
ActivityStreamsMove ActivityStreamsActivity = "Move"
// ActivityStreamsOffer https://www.w3.org/TR/activitystreams-vocabulary/#dfn-offer
ActivityStreamsOffer ActivityStreamsActivity = "Offer"
// ActivityStreamsQuestion https://www.w3.org/TR/activitystreams-vocabulary/#dfn-question
ActivityStreamsQuestion ActivityStreamsActivity = "Question"
// ActivityStreamsReject https://www.w3.org/TR/activitystreams-vocabulary/#dfn-reject
ActivityStreamsReject ActivityStreamsActivity = "Reject"
// ActivityStreamsRead https://www.w3.org/TR/activitystreams-vocabulary/#dfn-read
ActivityStreamsRead ActivityStreamsActivity = "Read"
// ActivityStreamsRemove https://www.w3.org/TR/activitystreams-vocabulary/#dfn-remove
ActivityStreamsRemove ActivityStreamsActivity = "Remove"
// ActivityStreamsTentativeReject https://www.w3.org/TR/activitystreams-vocabulary/#dfn-tentativereject
ActivityStreamsTentativeReject ActivityStreamsActivity = "TentativeReject"
// ActivityStreamsTentativeAccept https://www.w3.org/TR/activitystreams-vocabulary/#dfn-tentativeaccept
ActivityStreamsTentativeAccept ActivityStreamsActivity = "TentativeAccept"
// ActivityStreamsTravel https://www.w3.org/TR/activitystreams-vocabulary/#dfn-travel
ActivityStreamsTravel ActivityStreamsActivity = "Travel"
// ActivityStreamsUndo https://www.w3.org/TR/activitystreams-vocabulary/#dfn-undo
ActivityStreamsUndo ActivityStreamsActivity = "Undo"
// ActivityStreamsUpdate https://www.w3.org/TR/activitystreams-vocabulary/#dfn-update
ActivityStreamsUpdate ActivityStreamsActivity = "Update"
// ActivityStreamsView https://www.w3.org/TR/activitystreams-vocabulary/#dfn-view
ActivityStreamsView ActivityStreamsActivity = "View"
)

View File

@ -0,0 +1,40 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
// Application represents an application that can perform actions on behalf of a user.
// It is used to authorize tokens etc, and is associated with an oauth client id in the database.
type Application struct {
// id of this application in the db
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull"`
// name of the application given when it was created (eg., 'tusky')
Name string
// website for the application given when it was created (eg., 'https://tusky.app')
Website string
// redirect uri requested by the application for oauth2 flow
RedirectURI string
// id of the associated oauth client entity in the db
ClientID string
// secret of the associated oauth client entity in the db
ClientSecret string
// scopes requested when this app was created
Scopes string
// a vapid key generated for this app when it was created
VapidKey string
}

View File

@ -0,0 +1,19 @@
package gtsmodel
import "time"
// Block refers to the blocking of one account by another.
type Block struct {
// id of this block in the database
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull"`
// When was this block created
CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// When was this block updated
UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// Who created this block?
AccountID string `pg:",notnull"`
// Who is targeted by this block?
TargetAccountID string `pg:",notnull"`
// Activitypub URI for this block
URI string
}

View File

@ -0,0 +1,47 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
import "time"
// DomainBlock represents a federation block against a particular domain, of varying severity.
type DomainBlock struct {
// ID of this block in the database
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull,unique"`
// Domain to block. If ANY PART of the candidate domain contains this string, it will be blocked.
// For example: 'example.org' also blocks 'gts.example.org'. '.com' blocks *any* '.com' domains.
// TODO: implement wildcards here
Domain string `pg:",notnull"`
// When was this block created
CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// When was this block updated
UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// Account ID of the creator of this block
CreatedByAccountID string `pg:",notnull"`
// TODO: define this
Severity int
// Reject media from this domain?
RejectMedia bool
// Reject reports from this domain?
RejectReports bool
// Private comment on this block, viewable to admins
PrivateComment string
// Public comment on this block, viewable (optionally) by everyone
PublicComment string
}

View File

@ -0,0 +1,35 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
import "time"
// EmailDomainBlock represents a domain that the server should automatically reject sign-up requests from.
type EmailDomainBlock struct {
// ID of this block in the database
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull,unique"`
// Email domain to block. Eg. 'gmail.com' or 'hotmail.com'
Domain string `pg:",notnull"`
// When was this block created
CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// When was this block updated
UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// Account ID of the creator of this block
CreatedByAccountID string `pg:",notnull"`
}

View File

@ -0,0 +1,77 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
import "time"
// Emoji represents a custom emoji that's been uploaded through the admin UI, and is useable by instance denizens.
type Emoji struct {
// database ID of this emoji
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull"`
// String shortcode for this emoji -- the part that's between colons. This should be lowercase a-z_
// eg., 'blob_hug' 'purple_heart' Must be unique with domain.
Shortcode string `pg:",notnull,unique:shortcodedomain"`
// Origin domain of this emoji, eg 'example.org', 'queer.party'. empty string for local emojis.
Domain string `pg:",notnull,default:'',use_zero,unique:shortcodedomain"`
// When was this emoji created. Must be unique with shortcode.
CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// When was this emoji updated
UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// Where can this emoji be retrieved remotely? Null for local emojis.
// For remote emojis, it'll be something like:
// https://hackers.town/system/custom_emojis/images/000/049/842/original/1b74481204feabfd.png
ImageRemoteURL string
// Where can a static / non-animated version of this emoji be retrieved remotely? Null for local emojis.
// For remote emojis, it'll be something like:
// https://hackers.town/system/custom_emojis/images/000/049/842/static/1b74481204feabfd.png
ImageStaticRemoteURL string
// Where can this emoji be retrieved from the local server? Null for remote emojis.
// Assuming our server is hosted at 'example.org', this will be something like:
// 'https://example.org/fileserver/6339820e-ef65-4166-a262-5a9f46adb1a7/emoji/original/bfa6c9c5-6c25-4ea4-98b4-d78b8126fb52.png'
ImageURL string
// Where can a static version of this emoji be retrieved from the local server? Null for remote emojis.
// Assuming our server is hosted at 'example.org', this will be something like:
// 'https://example.org/fileserver/6339820e-ef65-4166-a262-5a9f46adb1a7/emoji/small/bfa6c9c5-6c25-4ea4-98b4-d78b8126fb52.png'
ImageStaticURL string
// Path of the emoji image in the server storage system. Will be something like:
// '/gotosocial/storage/6339820e-ef65-4166-a262-5a9f46adb1a7/emoji/original/bfa6c9c5-6c25-4ea4-98b4-d78b8126fb52.png'
ImagePath string `pg:",notnull"`
// Path of a static version of the emoji image in the server storage system. Will be something like:
// '/gotosocial/storage/6339820e-ef65-4166-a262-5a9f46adb1a7/emoji/small/bfa6c9c5-6c25-4ea4-98b4-d78b8126fb52.png'
ImageStaticPath string `pg:",notnull"`
// MIME content type of the emoji image
// Probably "image/png"
ImageContentType string `pg:",notnull"`
// MIME content type of the static version of the emoji image.
ImageStaticContentType string `pg:",notnull"`
// Size of the emoji image file in bytes, for serving purposes.
ImageFileSize int `pg:",notnull"`
// Size of the static version of the emoji image file in bytes, for serving purposes.
ImageStaticFileSize int `pg:",notnull"`
// When was the emoji image last updated?
ImageUpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// Has a moderation action disabled this emoji from being shown?
Disabled bool `pg:",notnull,default:false"`
// ActivityStreams uri of this emoji. Something like 'https://example.org/emojis/1234'
URI string `pg:",notnull,unique"`
// Is this emoji visible in the admin emoji picker?
VisibleInPicker bool `pg:",notnull,default:true"`
// In which emoji category is this emoji visible?
CategoryID string
}

View File

@ -0,0 +1,41 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
import "time"
// Follow represents one account following another, and the metadata around that follow.
type Follow struct {
// id of this follow in the database
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull,unique"`
// When was this follow created?
CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// When was this follow last updated?
UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// Who does this follow belong to?
AccountID string `pg:",unique:srctarget,notnull"`
// Who does AccountID follow?
TargetAccountID string `pg:",unique:srctarget,notnull"`
// Does this follow also want to see reblogs and not just posts?
ShowReblogs bool `pg:"default:true"`
// What is the activitypub URI of this follow?
URI string `pg:",unique"`
// does the following account want to be notified when the followed account posts?
Notify bool
}

View File

@ -0,0 +1,41 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
import "time"
// FollowRequest represents one account requesting to follow another, and the metadata around that request.
type FollowRequest struct {
// id of this follow request in the database
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull,unique"`
// When was this follow request created?
CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// When was this follow request last updated?
UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// Who does this follow request originate from?
AccountID string `pg:",unique:srctarget,notnull"`
// Who is the target of this follow request?
TargetAccountID string `pg:",unique:srctarget,notnull"`
// Does this follow also want to see reblogs and not just posts?
ShowReblogs bool `pg:"default:true"`
// What is the activitypub URI of this follow request?
URI string `pg:",unique"`
// does the following account want to be notified when the followed account posts?
Notify bool
}

View File

@ -0,0 +1,150 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
import (
"time"
)
// MediaAttachment represents a user-uploaded media attachment: an image/video/audio/gif that is
// somewhere in storage and that can be retrieved and served by the router.
type MediaAttachment struct {
// ID of the attachment in the database
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull,unique"`
// ID of the status to which this is attached
StatusID string
// Where can the attachment be retrieved on *this* server
URL string
// Where can the attachment be retrieved on a remote server (empty for local media)
RemoteURL string
// When was the attachment created
CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// When was the attachment last updated
UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// Type of file (image/gif/audio/video)
Type FileType `pg:",notnull"`
// Metadata about the file
FileMeta FileMeta
// To which account does this attachment belong
AccountID string `pg:",notnull"`
// Description of the attachment (for screenreaders)
Description string
// To which scheduled status does this attachment belong
ScheduledStatusID string
// What is the generated blurhash of this attachment
Blurhash string
// What is the processing status of this attachment
Processing ProcessingStatus
// metadata for the whole file
File File
// small image thumbnail derived from a larger image, video, or audio file.
Thumbnail Thumbnail
// Is this attachment being used as an avatar?
Avatar bool
// Is this attachment being used as a header?
Header bool
}
// File refers to the metadata for the whole file
type File struct {
// What is the path of the file in storage.
Path string
// What is the MIME content type of the file.
ContentType string
// What is the size of the file in bytes.
FileSize int
// When was the file last updated.
UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
}
// Thumbnail refers to a small image thumbnail derived from a larger image, video, or audio file.
type Thumbnail struct {
// What is the path of the file in storage
Path string
// What is the MIME content type of the file.
ContentType string
// What is the size of the file in bytes
FileSize int
// When was the file last updated
UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// What is the URL of the thumbnail on the local server
URL string
// What is the remote URL of the thumbnail (empty for local media)
RemoteURL string
}
// ProcessingStatus refers to how far along in the processing stage the attachment is.
type ProcessingStatus int
const (
// ProcessingStatusReceived indicates the attachment has been received and is awaiting processing. No thumbnail available yet.
ProcessingStatusReceived ProcessingStatus = 0
// ProcessingStatusProcessing indicates the attachment is currently being processed. Thumbnail is available but full media is not.
ProcessingStatusProcessing ProcessingStatus = 1
// ProcessingStatusProcessed indicates the attachment has been fully processed and is ready to be served.
ProcessingStatusProcessed ProcessingStatus = 2
// ProcessingStatusError indicates something went wrong processing the attachment and it won't be tried again--these can be deleted.
ProcessingStatusError ProcessingStatus = 666
)
// FileType refers to the file type of the media attaachment.
type FileType string
const (
// FileTypeImage is for jpegs and pngs
FileTypeImage FileType = "Image"
// FileTypeGif is for native gifs and soundless videos that have been converted to gifs
FileTypeGif FileType = "Gif"
// FileTypeAudio is for audio-only files (no video)
FileTypeAudio FileType = "Audio"
// FileTypeVideo is for files with audio + visual
FileTypeVideo FileType = "Video"
// FileTypeUnknown is for unknown file types (surprise surprise!)
FileTypeUnknown FileType = "Unknown"
)
// FileMeta describes metadata about the actual contents of the file.
type FileMeta struct {
Original Original
Small Small
Focus Focus
}
// Small can be used for a thumbnail of any media type
type Small struct {
Width int
Height int
Size int
Aspect float64
}
// Original can be used for original metadata for any media type
type Original struct {
Width int
Height int
Size int
Aspect float64
}
// Focus describes the 'center' of the image for display purposes.
// X and Y should each be between -1 and 1
type Focus struct {
X float32
Y float32
}

View File

@ -0,0 +1,39 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
import "time"
// Mention refers to the 'tagging' or 'mention' of a user within a status.
type Mention struct {
// ID of this mention in the database
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull,unique"`
// ID of the status this mention originates from
StatusID string `pg:",notnull"`
// When was this mention created?
CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// When was this mention last updated?
UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// Who created this mention?
OriginAccountID string `pg:",notnull"`
// Who does this mention target?
TargetAccountID string `pg:",notnull"`
// Prevent this mention from generating a notification?
Silent bool
}

19
internal/gtsmodel/poll.go Normal file
View File

@ -0,0 +1,19 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel

138
internal/gtsmodel/status.go Normal file
View File

@ -0,0 +1,138 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
import "time"
// Status represents a user-created 'post' or 'status' in the database, either remote or local
type Status struct {
// id of the status in the database
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull"`
// uri at which this status is reachable
URI string `pg:",unique"`
// web url for viewing this status
URL string `pg:",unique"`
// the html-formatted content of this status
Content string
// Database IDs of any media attachments associated with this status
Attachments []string `pg:",array"`
// Database IDs of any tags used in this status
Tags []string `pg:",array"`
// Database IDs of any accounts mentioned in this status
Mentions []string `pg:",array"`
// Database IDs of any emojis used in this status
Emojis []string `pg:",array"`
// when was this status created?
CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// when was this status updated?
UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// is this status from a local account?
Local bool
// which account posted this status?
AccountID string
// id of the status this status is a reply to
InReplyToID string
// id of the account that this status replies to
InReplyToAccountID string
// id of the status this status is a boost of
BoostOfID string
// cw string for this status
ContentWarning string
// visibility entry for this status
Visibility Visibility `pg:",notnull"`
// mark the status as sensitive?
Sensitive bool
// what language is this status written in?
Language string
// Which application was used to create this status?
CreatedWithApplicationID string
// advanced visibility for this status
VisibilityAdvanced *VisibilityAdvanced
// What is the activitystreams type of this status? See: https://www.w3.org/TR/activitystreams-vocabulary/#object-types
// Will probably almost always be Note but who knows!.
ActivityStreamsType ActivityStreamsObject
// Original text of the status without formatting
Text string
/*
NON-DATABASE FIELDS
These are for convenience while passing the status around internally,
but these fields should *never* be put in the db.
*/
// Mentions created in this status
GTSMentions []*Mention `pg:"-"`
// Hashtags used in this status
GTSTags []*Tag `pg:"-"`
// Emojis used in this status
GTSEmojis []*Emoji `pg:"-"`
// MediaAttachments used in this status
GTSMediaAttachments []*MediaAttachment `pg:"-"`
// Status being replied to
GTSReplyToStatus *Status `pg:"-"`
// Account being replied to
GTSReplyToAccount *Account `pg:"-"`
}
// Visibility represents the visibility granularity of a status.
type Visibility string
const (
// VisibilityPublic means this status will be visible to everyone on all timelines.
VisibilityPublic Visibility = "public"
// VisibilityUnlocked means this status will be visible to everyone, but will only show on home timeline to followers, and in lists.
VisibilityUnlocked Visibility = "unlocked"
// VisibilityFollowersOnly means this status is viewable to followers only.
VisibilityFollowersOnly Visibility = "followers_only"
// VisibilityMutualsOnly means this status is visible to mutual followers only.
VisibilityMutualsOnly Visibility = "mutuals_only"
// VisibilityDirect means this status is visible only to mentioned recipients
VisibilityDirect Visibility = "direct"
// VisibilityDefault is used when no other setting can be found
VisibilityDefault Visibility = "public"
)
// VisibilityAdvanced denotes a set of flags that can be set on a status for fine-tuning visibility and interactivity of the status.
type VisibilityAdvanced struct {
/*
ADVANCED SETTINGS -- These should all default to TRUE.
If PUBLIC is selected, they will all be overwritten to TRUE regardless of what is selected.
If UNLOCKED is selected, any of them can be turned on or off in any combination.
If FOLLOWERS-ONLY or MUTUALS-ONLY are selected, boostable will always be FALSE. The others can be turned on or off as desired.
If DIRECT is selected, boostable will be FALSE, and all other flags will be TRUE.
*/
// This status will be federated beyond the local timeline(s)
Federated bool `pg:"default:true"`
// This status can be boosted/reblogged
Boostable bool `pg:"default:true"`
// This status can be replied to
Replyable bool `pg:"default:true"`
// This status can be liked/faved
Likeable bool `pg:"default:true"`
}
// RelevantAccounts denotes accounts that are replied to, boosted by, or mentioned in a status.
type RelevantAccounts struct {
ReplyToAccount *Account
BoostedAccount *Account
BoostedReplyToAccount *Account
MentionedAccounts []*Account
}

View File

@ -0,0 +1,35 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
import "time"
// StatusBookmark refers to one account having a 'bookmark' of the status of another account
type StatusBookmark struct {
// id of this bookmark in the database
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull,unique"`
// when was this bookmark created
CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// id of the account that created ('did') the bookmarking
AccountID string `pg:",notnull"`
// id the account owning the bookmarked status
TargetAccountID string `pg:",notnull"`
// database id of the status that has been bookmarked
StatusID string `pg:",notnull"`
}

View File

@ -0,0 +1,38 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
import "time"
// StatusFave refers to a 'fave' or 'like' in the database, from one account, targeting the status of another account
type StatusFave struct {
// id of this fave in the database
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull,unique"`
// when was this fave created
CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// id of the account that created ('did') the fave
AccountID string `pg:",notnull"`
// id the account owning the faved status
TargetAccountID string `pg:",notnull"`
// database id of the status that has been 'faved'
StatusID string `pg:",notnull"`
// FavedStatus is the status being interacted with. It won't be put or retrieved from the db, it's just for conveniently passing a pointer around.
FavedStatus *Status `pg:"-"`
}

View File

@ -0,0 +1,35 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
import "time"
// StatusMute refers to one account having muted the status of another account or its own
type StatusMute struct {
// id of this mute in the database
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull,unique"`
// when was this mute created
CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// id of the account that created ('did') the mute
AccountID string `pg:",notnull"`
// id the account owning the muted status (can be the same as accountID)
TargetAccountID string `pg:",notnull"`
// database id of the status that has been muted
StatusID string `pg:",notnull"`
}

View File

@ -0,0 +1,33 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
import "time"
// StatusPin refers to a status 'pinned' to the top of an account
type StatusPin struct {
// id of this pin in the database
ID string `pg:"type:uuid,default:gen_random_uuid(),pk,notnull,unique"`
// when was this pin created
CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// id of the account that created ('did') the pinning (this should always be the same as the author of the status)
AccountID string `pg:",notnull"`
// database id of the status that has been pinned
StatusID string `pg:",notnull"`
}

41
internal/gtsmodel/tag.go Normal file
View File

@ -0,0 +1,41 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
import "time"
// Tag represents a hashtag for gathering public statuses together
type Tag struct {
// id of this tag in the database
ID string `pg:",unique,type:uuid,default:gen_random_uuid(),pk,notnull"`
// name of this tag -- the tag without the hash part
Name string `pg:",unique,pk,notnull"`
// Which account ID is the first one we saw using this tag?
FirstSeenFromAccountID string
// when was this tag created
CreatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// when was this tag last updated
UpdatedAt time.Time `pg:"type:timestamp,notnull,default:now()"`
// can our instance users use this tag?
Useable bool `pg:",notnull,default:true"`
// can our instance users look up this tag?
Listable bool `pg:",notnull,default:true"`
// when was this tag last used?
LastStatusAt time.Time `pg:"type:timestamp,notnull,default:now()"`
}

120
internal/gtsmodel/user.go Normal file
View File

@ -0,0 +1,120 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gtsmodel
import (
"net"
"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 {
/*
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:"default:null,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
OTPRequiredForLogin bool
OTPBackupCodes []string
ConsumedTimestamp int
RememberToken string
SignInToken string
SignInTokenSentAt time.Time `pg:"type:timestamp"`
WebauthnID string
}