mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 18:02:25 -05:00 
			
		
		
		
	move oauth models into gtsmodel
This commit is contained in:
		
					parent
					
						
							
								464e3d1324
							
						
					
				
			
			
				commit
				
					
						684bd56528
					
				
			
		
					 39 changed files with 1060 additions and 96 deletions
				
			
		|  | @ -9,7 +9,6 @@ import ( | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/federation" | 	"github.com/superseriousbusiness/gotosocial/internal/federation" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/oauth" |  | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/processing" | 	"github.com/superseriousbusiness/gotosocial/internal/processing" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/typeutils" | 	"github.com/superseriousbusiness/gotosocial/internal/typeutils" | ||||||
| ) | ) | ||||||
|  | @ -27,8 +26,8 @@ type AccountStandardTestSuite struct { | ||||||
| 	processor processing.Processor | 	processor processing.Processor | ||||||
| 
 | 
 | ||||||
| 	// standard suite models | 	// standard suite models | ||||||
| 	testTokens       map[string]*oauth.Token | 	testTokens       map[string]*gtsmodel.Token | ||||||
| 	testClients      map[string]*oauth.Client | 	testClients      map[string]*gtsmodel.Client | ||||||
| 	testApplications map[string]*gtsmodel.Application | 	testApplications map[string]*gtsmodel.Application | ||||||
| 	testUsers        map[string]*gtsmodel.User | 	testUsers        map[string]*gtsmodel.User | ||||||
| 	testAccounts     map[string]*gtsmodel.Account | 	testAccounts     map[string]*gtsmodel.Account | ||||||
|  |  | ||||||
|  | @ -41,7 +41,7 @@ type AuthTestSuite struct { | ||||||
| 	testAccount     *gtsmodel.Account | 	testAccount     *gtsmodel.Account | ||||||
| 	testApplication *gtsmodel.Application | 	testApplication *gtsmodel.Application | ||||||
| 	testUser        *gtsmodel.User | 	testUser        *gtsmodel.User | ||||||
| 	testClient      *oauth.Client | 	testClient      *gtsmodel.Client | ||||||
| 	config          *config.Config | 	config          *config.Config | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -83,7 +83,7 @@ func (suite *AuthTestSuite) SetupSuite() { | ||||||
| 		Email:             "user@example.org", | 		Email:             "user@example.org", | ||||||
| 		AccountID:         acctID, | 		AccountID:         acctID, | ||||||
| 	} | 	} | ||||||
| 	suite.testClient = &oauth.Client{ | 	suite.testClient = >smodel.Client{ | ||||||
| 		ID:     "a-known-client-id", | 		ID:     "a-known-client-id", | ||||||
| 		Secret: "some-secret", | 		Secret: "some-secret", | ||||||
| 		Domain: fmt.Sprintf("%s://%s", c.Protocol, c.Host), | 		Domain: fmt.Sprintf("%s://%s", c.Protocol, c.Host), | ||||||
|  | @ -112,8 +112,8 @@ func (suite *AuthTestSuite) SetupTest() { | ||||||
| 	suite.db = db | 	suite.db = db | ||||||
| 
 | 
 | ||||||
| 	models := []interface{}{ | 	models := []interface{}{ | ||||||
| 		&oauth.Client{}, | 		>smodel.Client{}, | ||||||
| 		&oauth.Token{}, | 		>smodel.Token{}, | ||||||
| 		>smodel.User{}, | 		>smodel.User{}, | ||||||
| 		>smodel.Account{}, | 		>smodel.Account{}, | ||||||
| 		>smodel.Application{}, | 		>smodel.Application{}, | ||||||
|  | @ -145,8 +145,8 @@ func (suite *AuthTestSuite) SetupTest() { | ||||||
| // TearDownTest drops the oauth_clients table and closes the pg connection after each test | // TearDownTest drops the oauth_clients table and closes the pg connection after each test | ||||||
| func (suite *AuthTestSuite) TearDownTest() { | func (suite *AuthTestSuite) TearDownTest() { | ||||||
| 	models := []interface{}{ | 	models := []interface{}{ | ||||||
| 		&oauth.Client{}, | 		>smodel.Client{}, | ||||||
| 		&oauth.Token{}, | 		>smodel.Token{}, | ||||||
| 		>smodel.User{}, | 		>smodel.User{}, | ||||||
| 		>smodel.Account{}, | 		>smodel.Account{}, | ||||||
| 		>smodel.Application{}, | 		>smodel.Application{}, | ||||||
|  |  | ||||||
|  | @ -57,8 +57,8 @@ type ServeFileTestSuite struct { | ||||||
| 	oauthServer  oauth.Server | 	oauthServer  oauth.Server | ||||||
| 
 | 
 | ||||||
| 	// standard suite models | 	// standard suite models | ||||||
| 	testTokens       map[string]*oauth.Token | 	testTokens       map[string]*gtsmodel.Token | ||||||
| 	testClients      map[string]*oauth.Client | 	testClients      map[string]*gtsmodel.Client | ||||||
| 	testApplications map[string]*gtsmodel.Application | 	testApplications map[string]*gtsmodel.Application | ||||||
| 	testUsers        map[string]*gtsmodel.User | 	testUsers        map[string]*gtsmodel.User | ||||||
| 	testAccounts     map[string]*gtsmodel.Account | 	testAccounts     map[string]*gtsmodel.Account | ||||||
|  |  | ||||||
|  | @ -60,8 +60,8 @@ type MediaCreateTestSuite struct { | ||||||
| 	processor    processing.Processor | 	processor    processing.Processor | ||||||
| 
 | 
 | ||||||
| 	// standard suite models | 	// standard suite models | ||||||
| 	testTokens       map[string]*oauth.Token | 	testTokens       map[string]*gtsmodel.Token | ||||||
| 	testClients      map[string]*oauth.Client | 	testClients      map[string]*gtsmodel.Client | ||||||
| 	testApplications map[string]*gtsmodel.Application | 	testApplications map[string]*gtsmodel.Application | ||||||
| 	testUsers        map[string]*gtsmodel.User | 	testUsers        map[string]*gtsmodel.User | ||||||
| 	testAccounts     map[string]*gtsmodel.Account | 	testAccounts     map[string]*gtsmodel.Account | ||||||
|  |  | ||||||
|  | @ -27,7 +27,6 @@ import ( | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/federation" | 	"github.com/superseriousbusiness/gotosocial/internal/federation" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/oauth" |  | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/processing" | 	"github.com/superseriousbusiness/gotosocial/internal/processing" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/typeutils" | 	"github.com/superseriousbusiness/gotosocial/internal/typeutils" | ||||||
| ) | ) | ||||||
|  | @ -45,8 +44,8 @@ type StatusStandardTestSuite struct { | ||||||
| 	storage   blob.Storage | 	storage   blob.Storage | ||||||
| 
 | 
 | ||||||
| 	// standard suite models | 	// standard suite models | ||||||
| 	testTokens       map[string]*oauth.Token | 	testTokens       map[string]*gtsmodel.Token | ||||||
| 	testClients      map[string]*oauth.Client | 	testClients      map[string]*gtsmodel.Client | ||||||
| 	testApplications map[string]*gtsmodel.Application | 	testApplications map[string]*gtsmodel.Application | ||||||
| 	testUsers        map[string]*gtsmodel.User | 	testUsers        map[string]*gtsmodel.User | ||||||
| 	testAccounts     map[string]*gtsmodel.Account | 	testAccounts     map[string]*gtsmodel.Account | ||||||
|  |  | ||||||
|  | @ -10,7 +10,6 @@ import ( | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/federation" | 	"github.com/superseriousbusiness/gotosocial/internal/federation" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/oauth" |  | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/processing" | 	"github.com/superseriousbusiness/gotosocial/internal/processing" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/typeutils" | 	"github.com/superseriousbusiness/gotosocial/internal/typeutils" | ||||||
| ) | ) | ||||||
|  | @ -29,8 +28,8 @@ type UserStandardTestSuite struct { | ||||||
| 	securityModule *security.Module | 	securityModule *security.Module | ||||||
| 
 | 
 | ||||||
| 	// standard suite models | 	// standard suite models | ||||||
| 	testTokens       map[string]*oauth.Token | 	testTokens       map[string]*gtsmodel.Token | ||||||
| 	testClients      map[string]*oauth.Client | 	testClients      map[string]*gtsmodel.Client | ||||||
| 	testApplications map[string]*gtsmodel.Application | 	testApplications map[string]*gtsmodel.Application | ||||||
| 	testUsers        map[string]*gtsmodel.User | 	testUsers        map[string]*gtsmodel.User | ||||||
| 	testAccounts     map[string]*gtsmodel.Account | 	testAccounts     map[string]*gtsmodel.Account | ||||||
|  |  | ||||||
|  | @ -73,8 +73,8 @@ var models []interface{} = []interface{}{ | ||||||
| 	>smodel.Instance{}, | 	>smodel.Instance{}, | ||||||
| 	>smodel.Notification{}, | 	>smodel.Notification{}, | ||||||
| 	>smodel.RouterSession{}, | 	>smodel.RouterSession{}, | ||||||
| 	&oauth.Token{}, | 	>smodel.Token{}, | ||||||
| 	&oauth.Client{}, | 	>smodel.Client{}, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Start creates and starts a gotosocial server | // Start creates and starts a gotosocial server | ||||||
|  |  | ||||||
|  | @ -24,7 +24,6 @@ import ( | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/config" | 	"github.com/superseriousbusiness/gotosocial/internal/config" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/oauth" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type BunDBStandardTestSuite struct { | type BunDBStandardTestSuite struct { | ||||||
|  | @ -35,8 +34,8 @@ type BunDBStandardTestSuite struct { | ||||||
| 	log    *logrus.Logger | 	log    *logrus.Logger | ||||||
| 
 | 
 | ||||||
| 	// standard suite models | 	// standard suite models | ||||||
| 	testTokens       map[string]*oauth.Token | 	testTokens       map[string]*gtsmodel.Token | ||||||
| 	testClients      map[string]*oauth.Client | 	testClients      map[string]*gtsmodel.Client | ||||||
| 	testApplications map[string]*gtsmodel.Application | 	testApplications map[string]*gtsmodel.Application | ||||||
| 	testUsers        map[string]*gtsmodel.User | 	testUsers        map[string]*gtsmodel.User | ||||||
| 	testAccounts     map[string]*gtsmodel.Account | 	testAccounts     map[string]*gtsmodel.Account | ||||||
|  |  | ||||||
|  | @ -21,16 +21,45 @@ package migrations | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 
 | 
 | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	gtsmodel "github.com/superseriousbusiness/gotosocial/internal/db/bundb/migrations/20210816411877_struct_validation" | ||||||
| 	"github.com/uptrace/bun" | 	"github.com/uptrace/bun" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
|  | 
 | ||||||
|  | 	var models []interface{} = []interface{}{ | ||||||
|  | 		>smodel.Account{}, | ||||||
|  | 		>smodel.Application{}, | ||||||
|  | 		>smodel.Block{}, | ||||||
|  | 		>smodel.DomainBlock{}, | ||||||
|  | 		>smodel.EmailDomainBlock{}, | ||||||
|  | 		>smodel.Follow{}, | ||||||
|  | 		>smodel.FollowRequest{}, | ||||||
|  | 		>smodel.MediaAttachment{}, | ||||||
|  | 		>smodel.Mention{}, | ||||||
|  | 		>smodel.Status{}, | ||||||
|  | 		>smodel.StatusToEmoji{}, | ||||||
|  | 		>smodel.StatusToTag{}, | ||||||
|  | 		>smodel.StatusFave{}, | ||||||
|  | 		>smodel.StatusBookmark{}, | ||||||
|  | 		>smodel.StatusMute{}, | ||||||
|  | 		>smodel.Tag{}, | ||||||
|  | 		>smodel.User{}, | ||||||
|  | 		>smodel.Emoji{}, | ||||||
|  | 		>smodel.Instance{}, | ||||||
|  | 		>smodel.Notification{}, | ||||||
|  | 		>smodel.RouterSession{}, | ||||||
|  | 		>smodel.Token{}, | ||||||
|  | 		>smodel.Client{}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	up := func(ctx context.Context, db *bun.DB) error { | 	up := func(ctx context.Context, db *bun.DB) error { | ||||||
| 		return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { | 		return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { | ||||||
| 			_, err := tx.NewCreateTable().Model(>smodel.Account{}).IfNotExists().Exec(ctx) | 			for _, m := range models { | ||||||
| 			if err != nil { | 				_, err := tx.NewCreateTable().Model(m).IfNotExists().Exec(ctx) | ||||||
| 				return err | 				if err != nil { | ||||||
|  | 					return err | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			return nil | 			return nil | ||||||
|  |  | ||||||
|  | @ -0,0 +1,78 @@ | ||||||
|  | /* | ||||||
|  |    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 ( | ||||||
|  | 	"crypto/rsa" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Account represents either a local or a remote fediverse account, gotosocial or otherwise (mastodon, pleroma, etc). | ||||||
|  | type Account struct { | ||||||
|  | 	ID                      string           `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"`                                      // id of this item in the database | ||||||
|  | 	CreatedAt               time.Time        `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`                                               // when was item created | ||||||
|  | 	UpdatedAt               time.Time        `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`                                               // when was item last updated | ||||||
|  | 	Username                string           `validate:"required" bun:",nullzero,notnull,unique:userdomain"`                                                // Username of the account, should just be a string of [a-zA-Z0-9_]. Can be added to domain to create the full username in the form ``[username]@[domain]`` eg., ``user_96@example.org``. Username and domain should be unique *with* each other | ||||||
|  | 	Domain                  string           `validate:"omitempty,fqdn" bun:",nullzero,unique:userdomain"`                                                  // 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. | ||||||
|  | 	AvatarMediaAttachmentID string           `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"`                                                       // Database ID of the media attachment, if present | ||||||
|  | 	AvatarMediaAttachment   *MediaAttachment `validate:"-" bun:"rel:belongs-to"`                                                                            // MediaAttachment corresponding to avatarMediaAttachmentID | ||||||
|  | 	AvatarRemoteURL         string           `validate:"omitempty,url" bun:",nullzero"`                                                                     // For a non-local account, where can the header be fetched? | ||||||
|  | 	HeaderMediaAttachmentID string           `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"`                                                       // Database ID of the media attachment, if present | ||||||
|  | 	HeaderMediaAttachment   *MediaAttachment `validate:"-" bun:"rel:belongs-to"`                                                                            // MediaAttachment corresponding to headerMediaAttachmentID | ||||||
|  | 	HeaderRemoteURL         string           `validate:"omitempty,url" bun:",nullzero"`                                                                     // For a non-local account, where can the header be fetched? | ||||||
|  | 	DisplayName             string           `validate:"-" bun:",nullzero"`                                                                                 // DisplayName for this account. Can be empty, then just the Username will be used for display purposes. | ||||||
|  | 	Fields                  []Field          `validate:"-"`                                                                                                 // a key/value map of fields that this account has added to their profile | ||||||
|  | 	Note                    string           `validate:"-" bun:",nullzero"`                                                                                 // A note that this account has on their profile (ie., the account's bio/description of themselves) | ||||||
|  | 	Memorial                bool             `validate:"-" bun:",nullzero,default:false"`                                                                   // Is this a memorial account, ie., has the user passed away? | ||||||
|  | 	AlsoKnownAs             string           `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"`                                                       // This account is associated with x account id | ||||||
|  | 	MovedToAccountID        string           `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"`                                                       // This account has moved this account id in the database | ||||||
|  | 	Bot                     bool             `validate:"-" bun:",nullzero,default:false"`                                                                   // Does this account identify itself as a bot? | ||||||
|  | 	Reason                  string           `validate:"-" bun:",nullzero"`                                                                                 // What reason was given for signing up when this account was created? | ||||||
|  | 	Locked                  bool             `validate:"-" bun:",nullzero,default:true"`                                                                    // Does this account need an approval for new followers? | ||||||
|  | 	Discoverable            bool             `validate:"-" bun:",nullzero,default:false"`                                                                   // Should this account be shown in the instance's profile directory? | ||||||
|  | 	Privacy                 Visibility       `validate:"oneof=public unlocked followers_only mutuals_only direct" bun:",nullzero,notnull,default:'public'"` // Default post privacy for this account | ||||||
|  | 	Sensitive               bool             `validate:"-" bun:",nullzero,default:false"`                                                                   // Set posts from this account to sensitive by default? | ||||||
|  | 	Language                string           `validate:"-" bun:",nullzero,notnull,default:'en'"`                                                            // What language does this account post in? | ||||||
|  | 	URI                     string           `validate:"required,url" bun:",nullzero,notnull,unique"`                                                       // ActivityPub URI for this account. | ||||||
|  | 	URL                     string           `validate:"omitempty,url" bun:",unique,nullzero"`                                                              // Web URL for this account's profile | ||||||
|  | 	LastWebfingeredAt       time.Time        `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`                                               // Last time this account was refreshed/located with webfinger. | ||||||
|  | 	InboxURI                string           `validate:"omitempty,url" bun:",nullzero,unique"`                                                              // Address of this account's ActivityPub inbox, for sending activity to | ||||||
|  | 	OutboxURI               string           `validate:"omitempty,url" bun:",nullzero,unique"`                                                              // Address of this account's activitypub outbox | ||||||
|  | 	FollowingURI            string           `validate:"omitempty,url" bun:",nullzero,unique"`                                                              // URI for getting the following list of this account | ||||||
|  | 	FollowersURI            string           `validate:"omitempty,url" bun:",nullzero,unique"`                                                              // URI for getting the followers list of this account | ||||||
|  | 	FeaturedCollectionURI   string           `validate:"omitempty,url" bun:",nullzero,unique"`                                                              // URL for getting the featured collection list of this account | ||||||
|  | 	ActorType               string           `validate:"oneof=Application Group Organization Person Service " bun:",nullzero,notnull"`                      // What type of activitypub actor is this account? | ||||||
|  | 	PrivateKey              *rsa.PrivateKey  `validate:"required_without=Domain"`                                                                           // Privatekey for validating activitypub requests, will only be defined for local accounts | ||||||
|  | 	PublicKey               *rsa.PublicKey   `validate:"required"`                                                                                          // Publickey for encoding activitypub requests, will be defined for both local and remote accounts | ||||||
|  | 	PublicKeyURI            string           `validate:"required" bun:",nullzero,notnull"`                                                                  // Web-reachable location of this account's public key | ||||||
|  | 	SensitizedAt            time.Time        `validate:"-" bun:",nullzero"`                                                                                 // When was this account set to have all its media shown as sensitive? | ||||||
|  | 	SilencedAt              time.Time        `validate:"-" bun:",nullzero"`                                                                                 // When was this account silenced (eg., statuses only visible to followers, not public)? | ||||||
|  | 	SuspendedAt             time.Time        `validate:"-" bun:",nullzero"`                                                                                 // When was this account suspended (eg., don't allow it to log in/post, don't accept media/posts from this account) | ||||||
|  | 	HideCollections         bool             `validate:"-" bun:",nullzero,default:false"`                                                                   // Hide this account's collections | ||||||
|  | 	SuspensionOrigin        string           `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"`                                                       // id of the database entry that caused this account to become suspended -- can be an account ID or a domain block ID | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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    `validate:"required"`          // Name of this field. | ||||||
|  | 	Value      string    `validate:"required"`          // Value of this field. | ||||||
|  | 	VerifiedAt time.Time `validate:"-" bun:",nullzero"` // This field was verified at (optional). | ||||||
|  | } | ||||||
|  | @ -0,0 +1,32 @@ | ||||||
|  | /* | ||||||
|  |    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           string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull"` // id of this application in the db | ||||||
|  | 	Name         string `validate:"required" bun:",nullzero,notnull"`                      // name of the application given when it was created (eg., 'tusky') | ||||||
|  | 	Website      string `validate:"omitempty,url" bun:",nullzero"`                         // website for the application given when it was created (eg., 'https://tusky.app') | ||||||
|  | 	RedirectURI  string `validate:"required" bun:",nullzero,notnull"`                      // redirect uri requested by the application for oauth2 flow | ||||||
|  | 	ClientID     string `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"`           // id of the associated oauth client entity in the db | ||||||
|  | 	ClientSecret string `validate:"required,uuid" bun:",nullzero,notnull"`                 // secret of the associated oauth client entity in the db | ||||||
|  | 	Scopes       string `validate:"required" bun:",nullzero,default:'read'"`               // scopes requested when this app was created | ||||||
|  | 	VapidKey     string `validate:"-" bun:",nullzero"`                                     // a vapid key generated for this app when it was created | ||||||
|  | } | ||||||
|  | @ -0,0 +1,15 @@ | ||||||
|  | package gtsmodel | ||||||
|  | 
 | ||||||
|  | import "time" | ||||||
|  | 
 | ||||||
|  | // Block refers to the blocking of one account by another. | ||||||
|  | type Block struct { | ||||||
|  | 	ID              string    `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"`    // id of this item in the database | ||||||
|  | 	CreatedAt       time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`             // when was item created | ||||||
|  | 	UpdatedAt       time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`             // when was item last updated | ||||||
|  | 	URI             string    `validate:"required,url" bun:",notnull,nullzero,unique"`                     // ActivityPub uri of this block. | ||||||
|  | 	AccountID       string    `validate:"required,ulid" bun:"type:CHAR(26),unique:blocksrctarget,notnull"` // Who does this block originate from? | ||||||
|  | 	Account         *Account  `validate:"-" bun:"rel:belongs-to"`                                          // Account corresponding to accountID | ||||||
|  | 	TargetAccountID string    `validate:"required,ulid" bun:"type:CHAR(26),unique:blocksrctarget,notnull"` // Who is the target of this block ? | ||||||
|  | 	TargetAccount   *Account  `validate:"-" bun:"rel:belongs-to"`                                          // Account corresponding to targetAccountID | ||||||
|  | } | ||||||
|  | @ -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" | ||||||
|  | 
 | ||||||
|  | // DomainBlock represents a federation block against a particular domain | ||||||
|  | type DomainBlock struct { | ||||||
|  | 	ID                 string    `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database | ||||||
|  | 	CreatedAt          time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item created | ||||||
|  | 	UpdatedAt          time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item last updated | ||||||
|  | 	Domain             string    `validate:"required,fqdn" bun:",nullzero,notnull"`                        // domain to block. Eg. 'whatever.com' | ||||||
|  | 	CreatedByAccountID string    `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`           // Account ID of the creator of this block | ||||||
|  | 	CreatedByAccount   *Account  `validate:"-" bun:"rel:belongs-to"`                                       // Account corresponding to createdByAccountID | ||||||
|  | 	PrivateComment     string    `validate:"-" bun:",nullzero"`                                            // Private comment on this block, viewable to admins | ||||||
|  | 	PublicComment      string    `validate:"-" bun:",nullzero"`                                            // Public comment on this block, viewable (optionally) by everyone | ||||||
|  | 	Obfuscate          bool      `validate:"-" bun:",nullzero,default:false"`                              // whether the domain name should appear obfuscated when displaying it publicly | ||||||
|  | 	SubscriptionID     string    `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"`                  // if this block was created through a subscription, what's the subscription ID? | ||||||
|  | } | ||||||
|  | @ -0,0 +1,31 @@ | ||||||
|  | /* | ||||||
|  |    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                 string    `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database | ||||||
|  | 	CreatedAt          time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item created | ||||||
|  | 	UpdatedAt          time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item last updated | ||||||
|  | 	Domain             string    `validate:"required,fqdn" bun:",nullzero,notnull"`                        // Email domain to block. Eg. 'gmail.com' or 'hotmail.com' | ||||||
|  | 	CreatedByAccountID string    `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`           // Account ID of the creator of this block | ||||||
|  | 	CreatedByAccount   *Account  `validate:"-" bun:"rel:belongs-to"`                                       // Account corresponding to createdByAccountID | ||||||
|  | } | ||||||
|  | @ -0,0 +1,45 @@ | ||||||
|  | /* | ||||||
|  |    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 { | ||||||
|  | 	ID                     string    `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"`                                // id of this item in the database | ||||||
|  | 	CreatedAt              time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`                                         // when was item created | ||||||
|  | 	UpdatedAt              time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`                                         // when was item last updated | ||||||
|  | 	Shortcode              string    `validate:"required" bun:",notnull,unique:shortcodedomain"`                                              // 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. | ||||||
|  | 	Domain                 string    `validate:"omitempty,fqdn" bun:",notnull,default:'',unique:shortcodedomain"`                             // Origin domain of this emoji, eg 'example.org', 'queer.party'. empty string for local emojis. | ||||||
|  | 	ImageRemoteURL         string    `validate:"required_without=ImageURL,omitempty,url" bun:",nullzero"`                                     // Where can this emoji be retrieved remotely? Null for local emojis. | ||||||
|  | 	ImageStaticRemoteURL   string    `validate:"required_without=ImageStaticURL,omitempty,url" bun:",nullzero"`                               // Where can a static / non-animated version of this emoji be retrieved remotely? Null for local emojis. | ||||||
|  | 	ImageURL               string    `validate:"required_without=ImageRemoteURL,required_without=Domain,omitempty,url" bun:",nullzero"`       // Where can this emoji be retrieved from the local server? Null for remote emojis. | ||||||
|  | 	ImageStaticURL         string    `validate:"required_without=ImageStaticRemoteURL,required_without=Domain,omitempty,url" bun:",nullzero"` // Where can a static version of this emoji be retrieved from the local server? Null for remote emojis. | ||||||
|  | 	ImagePath              string    `validate:"required,file" bun:",nullzero,notnull"`                                                       // Path of the emoji image in the server storage system. | ||||||
|  | 	ImageStaticPath        string    `validate:"required,file" bun:",nullzero,notnull"`                                                       // Path of a static version of the emoji image in the server storage system | ||||||
|  | 	ImageContentType       string    `validate:"required" bun:",nullzero,notnull"`                                                            // MIME content type of the emoji image | ||||||
|  | 	ImageStaticContentType string    `validate:"required" bun:",nullzero,notnull"`                                                            // MIME content type of the static version of the emoji image. | ||||||
|  | 	ImageFileSize          int       `validate:"required,min=1" bun:",nullzero,notnull"`                                                      // Size of the emoji image file in bytes, for serving purposes. | ||||||
|  | 	ImageStaticFileSize    int       `validate:"required,min=1" bun:",nullzero,notnull"`                                                      // Size of the static version of the emoji image file in bytes, for serving purposes. | ||||||
|  | 	ImageUpdatedAt         time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`                                         // When was the emoji image last updated? | ||||||
|  | 	Disabled               bool      `validate:"-" bun:",notnull,default:false"`                                                              // Has a moderation action disabled this emoji from being shown? | ||||||
|  | 	URI                    string    `validate:"url" bun:",nullzero,notnull,unique"`                                                          // ActivityPub uri of this emoji. Something like 'https://example.org/emojis/1234' | ||||||
|  | 	VisibleInPicker        bool      `validate:"-" bun:",notnull,default:true"`                                                               // Is this emoji visible in the admin emoji picker? | ||||||
|  | 	CategoryID             string    `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"`                                                 // In which emoji category is this emoji visible? | ||||||
|  | } | ||||||
|  | @ -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" | ||||||
|  | 
 | ||||||
|  | // Follow represents one account following another, and the metadata around that follow. | ||||||
|  | type Follow struct { | ||||||
|  | 	ID              string    `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database | ||||||
|  | 	CreatedAt       time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item created | ||||||
|  | 	UpdatedAt       time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item last updated | ||||||
|  | 	URI             string    `validate:"required,url" bun:",notnull,nullzero,unique"`                  // ActivityPub uri of this follow. | ||||||
|  | 	AccountID       string    `validate:"required,ulid" bun:"type:CHAR(26),unique:srctarget,notnull"`   // Who does this follow originate from? | ||||||
|  | 	Account         *Account  `validate:"-" bun:"rel:belongs-to"`                                       // Account corresponding to accountID | ||||||
|  | 	TargetAccountID string    `validate:"required,ulid" bun:"type:CHAR(26),unique:srctarget,notnull"`   // Who is the target of this follow ? | ||||||
|  | 	TargetAccount   *Account  `validate:"-" bun:"rel:belongs-to"`                                       // Account corresponding to targetAccountID | ||||||
|  | 	ShowReblogs     bool      `validate:"-" bun:",nullzero,default:true"`                               // Does this follow also want to see reblogs and not just posts? | ||||||
|  | 	Notify          bool      `validate:"-" bun:",nullzero,default:false"`                              // does the following account want to be notified when the followed account posts? | ||||||
|  | } | ||||||
|  | @ -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" | ||||||
|  | 
 | ||||||
|  | // FollowRequest represents one account requesting to follow another, and the metadata around that request. | ||||||
|  | type FollowRequest struct { | ||||||
|  | 	ID              string    `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database | ||||||
|  | 	CreatedAt       time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item created | ||||||
|  | 	UpdatedAt       time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item last updated | ||||||
|  | 	URI             string    `validate:"required,url" bun:",notnull,nullzero,unique"`                  // ActivityPub uri of this follow (request). | ||||||
|  | 	AccountID       string    `validate:"required,ulid" bun:"type:CHAR(26),unique:frsrctarget,notnull"` // Who does this follow request originate from? | ||||||
|  | 	Account         *Account  `validate:"-" bun:"rel:belongs-to"`                                       // Account corresponding to accountID | ||||||
|  | 	TargetAccountID string    `validate:"required,ulid" bun:"type:CHAR(26),unique:frsrctarget,notnull"` // Who is the target of this follow request? | ||||||
|  | 	TargetAccount   *Account  `validate:"-" bun:"rel:belongs-to"`                                       // Account corresponding to targetAccountID | ||||||
|  | 	ShowReblogs     bool      `validate:"-" bun:",nullzero,default:true"`                               // Does this follow also want to see reblogs and not just posts? | ||||||
|  | 	Notify          bool      `validate:"-" bun:",nullzero,default:false"`                              // does the following account want to be notified when the followed account posts? | ||||||
|  | } | ||||||
|  | @ -0,0 +1,25 @@ | ||||||
|  | package gtsmodel | ||||||
|  | 
 | ||||||
|  | import "time" | ||||||
|  | 
 | ||||||
|  | // Instance represents a federated instance, either local or remote. | ||||||
|  | type Instance struct { | ||||||
|  | 	ID                     string       `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"`                     // id of this item in the database | ||||||
|  | 	CreatedAt              time.Time    `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`                              // when was item created | ||||||
|  | 	UpdatedAt              time.Time    `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`                              // when was item last updated | ||||||
|  | 	Domain                 string       `validate:"required,fqdn" bun:",nullzero,notnull,unique"`                                     // Instance domain eg example.org | ||||||
|  | 	Title                  string       `validate:"-" bun:",nullzero"`                                                                // Title of this instance as it would like to be displayed. | ||||||
|  | 	URI                    string       `validate:"required,url" bun:",nullzero,notnull,unique"`                                      // base URI of this instance eg https://example.org | ||||||
|  | 	SuspendedAt            time.Time    `validate:"-" bun:",nullzero"`                                                                // When was this instance suspended, if at all? | ||||||
|  | 	DomainBlockID          string       `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"`                                      // ID of any existing domain block for this instance in the database | ||||||
|  | 	DomainBlock            *DomainBlock `validate:"-" bun:"rel:belongs-to"`                                                           // Domain block corresponding to domainBlockID | ||||||
|  | 	ShortDescription       string       `validate:"-" bun:",nullzero"`                                                                // Short description of this instance | ||||||
|  | 	Description            string       `validate:"-" bun:",nullzero"`                                                                // Longer description of this instance | ||||||
|  | 	Terms                  string       `validate:"-" bun:",nullzero"`                                                                // Terms and conditions of this instance | ||||||
|  | 	ContactEmail           string       `validate:"omitempty,email" bun:",nullzero"`                                                  // Contact email address for this instance | ||||||
|  | 	ContactAccountUsername string       `validate:"required_with=ContactAccountID" bun:",nullzero"`                                   // Username of the contact account for this instance | ||||||
|  | 	ContactAccountID       string       `validate:"required_with=ContactAccountUsername,omitempty,ulid" bun:"type:CHAR(26),nullzero"` // Contact account ID in the database for this instance | ||||||
|  | 	ContactAccount         *Account     `validate:"-" bun:"rel:belongs-to"`                                                           // account corresponding to contactAccountID | ||||||
|  | 	Reputation             int64        `validate:"-" bun:",notnull,default:0"`                                                       // Reputation score of this instance | ||||||
|  | 	Version                string       `validate:"-" bun:",nullzero"`                                                                // Version of the software used on this instance | ||||||
|  | } | ||||||
|  | @ -0,0 +1,117 @@ | ||||||
|  | /* | ||||||
|  |    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                string           `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"`                       // id of this item in the database | ||||||
|  | 	CreatedAt         time.Time        `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`                                // when was item created | ||||||
|  | 	UpdatedAt         time.Time        `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`                                // when was item last updated | ||||||
|  | 	StatusID          string           `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"`                                        // ID of the status to which this is attached | ||||||
|  | 	URL               string           `validate:"required_without=RemoteURL,omitempty,url" bun:",nullzero"`                           // Where can the attachment be retrieved on *this* server | ||||||
|  | 	RemoteURL         string           `validate:"required_without=URL,omitempty,url" bun:",nullzero"`                                 // Where can the attachment be retrieved on a remote server (empty for local media) | ||||||
|  | 	Type              FileType         `validate:"oneof=Image Gif Audio Video Unknown" bun:",notnull"`                                 // Type of file (image/gif/audio/video) | ||||||
|  | 	FileMeta          FileMeta         `validate:"required" bun:",nullzero,notnull"`                                                   // Metadata about the file | ||||||
|  | 	AccountID         string           `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`                                 // To which account does this attachment belong | ||||||
|  | 	Account           *Account         `validate:"-" bun:"rel:has-one"`                                                                // Account corresponding to accountID | ||||||
|  | 	Description       string           `validate:"-" bun:",nullzero"`                                                                  // Description of the attachment (for screenreaders) | ||||||
|  | 	ScheduledStatusID string           `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"`                                        // To which scheduled status does this attachment belong | ||||||
|  | 	Blurhash          string           `validate:"required_if=Type Image,required_if=Type Gif,required_if=Type Video" bun:",nullzero"` // What is the generated blurhash of this attachment | ||||||
|  | 	Processing        ProcessingStatus `validate:"oneof=0 1 2 666" bun:",notnull,default:2"`                                           // What is the processing status of this attachment | ||||||
|  | 	File              File             `validate:"required" bun:",notnull,nullzero"`                                                   // metadata for the whole file | ||||||
|  | 	Thumbnail         Thumbnail        `validate:"required" bun:",notnull,nullzero"`                                                   // small image thumbnail derived from a larger image, video, or audio file. | ||||||
|  | 	Avatar            bool             `validate:"-" bun:",notnull,default:false"`                                                     // Is this attachment being used as an avatar? | ||||||
|  | 	Header            bool             `validate:"-" bun:",notnull,default:false"`                                                     // Is this attachment being used as a header? | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // File refers to the metadata for the whole file | ||||||
|  | type File struct { | ||||||
|  | 	Path        string    `validate:"required,file" bun:",nullzero,notnull"`               // Path of the file in storage. | ||||||
|  | 	ContentType string    `validate:"required" bun:",nullzero,notnull"`                    // MIME content type of the file. | ||||||
|  | 	FileSize    int       `validate:"required" bun:",nullzero,notnull"`                    // File size in bytes | ||||||
|  | 	UpdatedAt   time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"` // When was the file last updated. | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Thumbnail refers to a small image thumbnail derived from a larger image, video, or audio file. | ||||||
|  | type Thumbnail struct { | ||||||
|  | 	Path        string    `validate:"required,file" bun:",nullzero,notnull"`                    // Path of the file in storage. | ||||||
|  | 	ContentType string    `validate:"required" bun:",nullzero,notnull"`                         // MIME content type of the file. | ||||||
|  | 	FileSize    int       `validate:"required" bun:",nullzero,notnull"`                         // File size in bytes | ||||||
|  | 	UpdatedAt   time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`      // When was the file last updated. | ||||||
|  | 	URL         string    `validate:"required_without=RemoteURL,omitempty,url" bun:",nullzero"` // What is the URL of the thumbnail on the local server | ||||||
|  | 	RemoteURL   string    `validate:"required_without=URL,omitempty,url" bun:",nullzero"`       // What is the remote URL of the thumbnail (empty for local media) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ProcessingStatus refers to how far along in the processing stage the attachment is. | ||||||
|  | type ProcessingStatus int | ||||||
|  | 
 | ||||||
|  | // MediaAttachment processing states. | ||||||
|  | const ( | ||||||
|  | 	ProcessingStatusReceived   ProcessingStatus = 0   // ProcessingStatusReceived indicates the attachment has been received and is awaiting processing. No thumbnail available yet. | ||||||
|  | 	ProcessingStatusProcessing ProcessingStatus = 1   // ProcessingStatusProcessing indicates the attachment is currently being processed. Thumbnail is available but full media is not. | ||||||
|  | 	ProcessingStatusProcessed  ProcessingStatus = 2   // ProcessingStatusProcessed indicates the attachment has been fully processed and is ready to be served. | ||||||
|  | 	ProcessingStatusError      ProcessingStatus = 666 // ProcessingStatusError indicates something went wrong processing the attachment and it won't be tried again--these can be deleted. | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // FileType refers to the file type of the media attaachment. | ||||||
|  | type FileType string | ||||||
|  | 
 | ||||||
|  | // MediaAttachment file types. | ||||||
|  | const ( | ||||||
|  | 	FileTypeImage   FileType = "Image"   // FileTypeImage is for jpegs and pngs | ||||||
|  | 	FileTypeGif     FileType = "Gif"     // FileTypeGif is for native gifs and soundless videos that have been converted to gifs | ||||||
|  | 	FileTypeAudio   FileType = "Audio"   // FileTypeAudio is for audio-only files (no video) | ||||||
|  | 	FileTypeVideo   FileType = "Video"   // FileTypeVideo is for files with audio + visual | ||||||
|  | 	FileTypeUnknown FileType = "Unknown" // FileTypeUnknown is for unknown file types (surprise surprise!) | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // FileMeta describes metadata about the actual contents of the file. | ||||||
|  | type FileMeta struct { | ||||||
|  | 	Original Original `validate:"required"` | ||||||
|  | 	Small    Small | ||||||
|  | 	Focus    Focus | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Small can be used for a thumbnail of any media type | ||||||
|  | type Small struct { | ||||||
|  | 	Width  int     `validate:"required_with=Height Size Aspect"`  // width in pixels | ||||||
|  | 	Height int     `validate:"required_with=Width Size Aspect"`   // height in pixels | ||||||
|  | 	Size   int     `validate:"required_with=Width Height Aspect"` // size in pixels (width * height) | ||||||
|  | 	Aspect float64 `validate:"required_with=Widhth Height Size"`  // aspect ratio (width / height) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Original can be used for original metadata for any media type | ||||||
|  | type Original struct { | ||||||
|  | 	Width  int     `validate:"required_with=Height Size Aspect"`  // width in pixels | ||||||
|  | 	Height int     `validate:"required_with=Width Size Aspect"`   // height in pixels | ||||||
|  | 	Size   int     `validate:"required_with=Width Height Aspect"` // size in pixels (width * height) | ||||||
|  | 	Aspect float64 `validate:"required_with=Widhth Height Size"`  // aspect ratio (width / height) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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 `validate:"omitempty,max=1,min=-1"` | ||||||
|  | 	Y float32 `validate:"omitempty,max=1,min=-1"` | ||||||
|  | } | ||||||
|  | @ -0,0 +1,59 @@ | ||||||
|  | /* | ||||||
|  |    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               string    `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database | ||||||
|  | 	CreatedAt        time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item created | ||||||
|  | 	UpdatedAt        time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item last updated | ||||||
|  | 	StatusID         string    `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`           // ID of the status this mention originates from | ||||||
|  | 	Status           *Status   `validate:"-" bun:"rel:belongs-to"`                                       // status referred to by statusID | ||||||
|  | 	OriginAccountID  string    `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`           // ID of the mention creator account | ||||||
|  | 	OriginAccountURI string    `validate:"url" bun:",nullzero,notnull"`                                  // ActivityPub URI of the originator/creator of the mention | ||||||
|  | 	OriginAccount    *Account  `validate:"-" bun:"rel:belongs-to"`                                       // account referred to by originAccountID | ||||||
|  | 	TargetAccountID  string    `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`           // Mention target/receiver account ID | ||||||
|  | 	TargetAccount    *Account  `validate:"-" bun:"rel:belongs-to"`                                       // account referred to by targetAccountID | ||||||
|  | 	Silent           bool      `validate:"-" bun:",notnull,default:false"`                               // Prevent this mention from generating a notification? | ||||||
|  | 
 | ||||||
|  | 	/* | ||||||
|  | 		NON-DATABASE CONVENIENCE FIELDS | ||||||
|  | 		These fields are just for convenience while passing the mention | ||||||
|  | 		around internally, to make fewer database calls and whatnot. They're | ||||||
|  | 		not meant to be put in the database! | ||||||
|  | 	*/ | ||||||
|  | 
 | ||||||
|  | 	// NameString is for putting in the namestring of the mentioned user | ||||||
|  | 	// before the mention is dereferenced. Should be in a form along the lines of: | ||||||
|  | 	// @whatever_username@example.org | ||||||
|  | 	// | ||||||
|  | 	// This will not be put in the database, it's just for convenience. | ||||||
|  | 	NameString string `validate:"-" bun:"-"` | ||||||
|  | 	// TargetAccountURI is the AP ID (uri) of the user mentioned. | ||||||
|  | 	// | ||||||
|  | 	// This will not be put in the database, it's just for convenience. | ||||||
|  | 	TargetAccountURI string `validate:"-" bun:"-"` | ||||||
|  | 	// TargetAccountURL is the web url of the user mentioned. | ||||||
|  | 	// | ||||||
|  | 	// This will not be put in the database, it's just for convenience. | ||||||
|  | 	TargetAccountURL string `validate:"-" bun:"-"` | ||||||
|  | 	// A pointer to the gtsmodel account of the mentioned account. | ||||||
|  | } | ||||||
|  | @ -0,0 +1,49 @@ | ||||||
|  | /* | ||||||
|  |    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" | ||||||
|  | 
 | ||||||
|  | // Notification models an alert/notification sent to an account about something like a reblog, like, new follow request, etc. | ||||||
|  | type Notification struct { | ||||||
|  | 	ID               string           `validate:"ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"`                                                                                                                                             // id of this item in the database | ||||||
|  | 	CreatedAt        time.Time        `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`                                                                                                                                             // when was item created | ||||||
|  | 	NotificationType NotificationType `validate:"oneof=follow follow_request mention reblog favourite poll status" bun:",nullzero,notnull"`                                                                                                        // Type of this notification | ||||||
|  | 	TargetAccountID  string           `validate:"ulid" bun:"type:CHAR(26),nullzero,notnull"`                                                                                                                                                       // Which account does this notification target (ie., who will receive the notification?) | ||||||
|  | 	TargetAccount    *Account         `validate:"-" bun:"rel:belongs-to"`                                                                                                                                                                          // Which account performed the action that created this notification? | ||||||
|  | 	OriginAccountID  string           `validate:"ulid" bun:"type:CHAR(26),nullzero,notnull"`                                                                                                                                                       // ID of the account that performed the action that created the notification. | ||||||
|  | 	OriginAccount    *Account         `validate:"-" bun:"rel:belongs-to"`                                                                                                                                                                          // Account corresponding to originAccountID | ||||||
|  | 	StatusID         string           `validate:"required_if=NotificationType mention,required_if=NotificationType reblog,required_if=NotificationType favourite,required_if=NotificationType status,omitempty,ulid" bun:"type:CHAR(26),nullzero"` // If the notification pertains to a status, what is the database ID of that status? | ||||||
|  | 	Status           *Status          `validate:"-" bun:"rel:belongs-to"`                                                                                                                                                                          // Status corresponding to statusID | ||||||
|  | 	Read             bool             `validate:"-" bun:",notnull,default:false"`                                                                                                                                                                  // Notification has been seen/read | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NotificationType describes the reason/type of this notification. | ||||||
|  | type NotificationType string | ||||||
|  | 
 | ||||||
|  | // Notification Types | ||||||
|  | const ( | ||||||
|  | 	NotificationFollow        NotificationType = "follow"         // NotificationFollow -- someone followed you | ||||||
|  | 	NotificationFollowRequest NotificationType = "follow_request" // NotificationFollowRequest -- someone requested to follow you | ||||||
|  | 	NotificationMention       NotificationType = "mention"        // NotificationMention -- someone mentioned you in their status | ||||||
|  | 	NotificationReblog        NotificationType = "reblog"         // NotificationReblog -- someone boosted one of your statuses | ||||||
|  | 	NotificationFave          NotificationType = "favourite"      // NotificationFave -- someone faved/liked one of your statuses | ||||||
|  | 	NotificationPoll          NotificationType = "poll"           // NotificationPoll -- a poll you voted in or created has ended | ||||||
|  | 	NotificationStatus        NotificationType = "status"         // NotificationStatus -- someone you enabled notifications for has posted a status. | ||||||
|  | ) | ||||||
|  | @ -0,0 +1,26 @@ | ||||||
|  | /* | ||||||
|  |    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 | ||||||
|  | 
 | ||||||
|  | // RouterSession is used to store and retrieve settings for a router session. | ||||||
|  | type RouterSession struct { | ||||||
|  | 	ID    string `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull"` | ||||||
|  | 	Auth  []byte `validate:"required,len=32" bun:"type:bytea,notnull,nullzero"` | ||||||
|  | 	Crypt []byte `validate:"required,len=32" bun:"type:bytea,notnull,nullzero"` | ||||||
|  | } | ||||||
|  | @ -0,0 +1,116 @@ | ||||||
|  | /* | ||||||
|  |    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                       string             `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"`                              // id of this item in the database | ||||||
|  | 	CreatedAt                time.Time          `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`                                       // when was item created | ||||||
|  | 	UpdatedAt                time.Time          `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`                                       // when was item last updated | ||||||
|  | 	URI                      string             `validate:"required,url" bun:",unique,nullzero,notnull"`                                               // activitypub URI of this status | ||||||
|  | 	URL                      string             `validate:"url" bun:",nullzero"`                                                                       // web url for viewing this status | ||||||
|  | 	Content                  string             `validate:"-" bun:",nullzero"`                                                                         // content of this status; likely html-formatted but not guaranteed | ||||||
|  | 	AttachmentIDs            []string           `validate:"dive,ulid" bun:"attachments,array,nullzero"`                                                // Database IDs of any media attachments associated with this status | ||||||
|  | 	Attachments              []*MediaAttachment `validate:"-" bun:"attached_media,rel:has-many"`                                                       // Attachments corresponding to attachmentIDs | ||||||
|  | 	TagIDs                   []string           `validate:"dive,ulid" bun:"tags,array,nullzero"`                                                       // Database IDs of any tags used in this status | ||||||
|  | 	Tags                     []*Tag             `validate:"-" bun:"attached_tags,m2m:status_to_tags"`                                                  // Tags corresponding to tagIDs. https://bun.uptrace.dev/guide/relations.html#many-to-many-relation | ||||||
|  | 	MentionIDs               []string           `validate:"dive,ulid" bun:"mentions,array,nullzero"`                                                   // Database IDs of any mentions in this status | ||||||
|  | 	Mentions                 []*Mention         `validate:"-" bun:"attached_mentions,rel:has-many"`                                                    // Mentions corresponding to mentionIDs | ||||||
|  | 	EmojiIDs                 []string           `validate:"dive,ulid" bun:"emojis,array,nullzero"`                                                     // Database IDs of any emojis used in this status | ||||||
|  | 	Emojis                   []*Emoji           `validate:"-" bun:"attached_emojis,m2m:status_to_emojis"`                                              // Emojis corresponding to emojiIDs. https://bun.uptrace.dev/guide/relations.html#many-to-many-relation | ||||||
|  | 	Local                    bool               `validate:"-" bun:",notnull,default:false"`                                                            // is this status from a local account? | ||||||
|  | 	AccountID                string             `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`                                        // which account posted this status? | ||||||
|  | 	Account                  *Account           `validate:"-" bun:"rel:belongs-to"`                                                                    // account corresponding to accountID | ||||||
|  | 	AccountURI               string             `validate:"required,url" bun:",nullzero,notnull"`                                                      // activitypub uri of the owner of this status | ||||||
|  | 	InReplyToID              string             `validate:"required_with=InReplyToURI InReplyToAccountID,omitempty,ulid" bun:"type:CHAR(26),nullzero"` // id of the status this status replies to | ||||||
|  | 	InReplyToURI             string             `validate:"required_with=InReplyToID InReplyToAccountID,omitempty,url" bun:",nullzero"`                // activitypub uri of the status this status is a reply to | ||||||
|  | 	InReplyToAccountID       string             `validate:"required_with=InReplyToID InReplyToURI,omitempty,ulid" bun:"type:CHAR(26),nullzero"`        // id of the account that this status replies to | ||||||
|  | 	InReplyTo                *Status            `validate:"-" bun:"-"`                                                                                 // status corresponding to inReplyToID | ||||||
|  | 	InReplyToAccount         *Account           `validate:"-" bun:"rel:belongs-to"`                                                                    // account corresponding to inReplyToAccountID | ||||||
|  | 	BoostOfID                string             `validate:"required_with=BoostOfAccountID,omitempty,ulid" bun:"type:CHAR(26),nullzero"`                // id of the status this status is a boost of | ||||||
|  | 	BoostOfAccountID         string             `validate:"required_with=BoostOfID,omitempty,ulid" bun:"type:CHAR(26),nullzero"`                       // id of the account that owns the boosted status | ||||||
|  | 	BoostOf                  *Status            `validate:"-" bun:"-"`                                                                                 // status that corresponds to boostOfID | ||||||
|  | 	BoostOfAccount           *Account           `validate:"-" bun:"rel:belongs-to"`                                                                    // account that corresponds to boostOfAccountID | ||||||
|  | 	ContentWarning           string             `validate:"-" bun:",nullzero"`                                                                         // cw string for this status | ||||||
|  | 	Visibility               Visibility         `validate:"-" bun:",nullzero,notnull"`                                                                 // visibility entry for this status | ||||||
|  | 	Sensitive                bool               `validate:"-" bun:",notnull,default:false"`                                                            // mark the status as sensitive? | ||||||
|  | 	Language                 string             `validate:"-" bun:",nullzero"`                                                                         // what language is this status written in? | ||||||
|  | 	CreatedWithApplicationID string             `validate:"required_if=Local true,omitempty,ulid" bun:"type:CHAR(26),nullzero"`                        // Which application was used to create this status? | ||||||
|  | 	CreatedWithApplication   *Application       `validate:"-" bun:"rel:belongs-to"`                                                                    // application corresponding to createdWithApplicationID | ||||||
|  | 	VisibilityAdvanced       VisibilityAdvanced `validate:"required" bun:",nullzero,notnull" `                                                         // advanced visibility for this status | ||||||
|  | 	ActivityStreamsType      string             `validate:"required" bun:",nullzero,notnull"`                                                          // 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!. | ||||||
|  | 	Text                     string             `validate:"-" bun:",nullzero"`                                                                         // Original text of the status without formatting | ||||||
|  | 	Pinned                   bool               `validate:"-" bun:",notnull,default:false" `                                                           // Has this status been pinned by its owner? | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StatusToTag is an intermediate struct to facilitate the many2many relationship between a status and one or more tags. | ||||||
|  | type StatusToTag struct { | ||||||
|  | 	StatusID string  `validate:"ulid,required" bun:"type:CHAR(26),unique:statustag,nullzero,notnull"` | ||||||
|  | 	Status   *Status `validate:"-" bun:"rel:belongs-to"` | ||||||
|  | 	TagID    string  `validate:"ulid,required" bun:"type:CHAR(26),unique:statustag,nullzero,notnull"` | ||||||
|  | 	Tag      *Tag    `validate:"-" bun:"rel:belongs-to"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // StatusToEmoji is an intermediate struct to facilitate the many2many relationship between a status and one or more emojis. | ||||||
|  | type StatusToEmoji struct { | ||||||
|  | 	StatusID string  `validate:"ulid,required" bun:"type:CHAR(26),unique:statusemoji,nullzero,notnull"` | ||||||
|  | 	Status   *Status `validate:"-" bun:"rel:belongs-to"` | ||||||
|  | 	EmojiID  string  `validate:"ulid,required" bun:"type:CHAR(26),unique:statusemoji,nullzero,notnull"` | ||||||
|  | 	Emoji    *Emoji  `validate:"-" bun:"rel:belongs-to"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 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 = VisibilityUnlocked | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // VisibilityAdvanced models flags for fine-tuning visibility and interactivity of a status. | ||||||
|  | // | ||||||
|  | // All flags default to true. | ||||||
|  | // | ||||||
|  | // If PUBLIC is selected, flags will all be overwritten to TRUE regardless of what is selected. | ||||||
|  | // | ||||||
|  | // If UNLOCKED is selected, any flags can be turned on or off in any combination. | ||||||
|  | // | ||||||
|  | // If FOLLOWERS-ONLY or MUTUALS-ONLY are selected, boostable will always be FALSE. Other flags can be turned on or off as desired. | ||||||
|  | // | ||||||
|  | // If DIRECT is selected, boostable will be FALSE, and all other flags will be TRUE. | ||||||
|  | type VisibilityAdvanced struct { | ||||||
|  | 	Federated bool `validate:"-" bun:",notnull,default:true"` // This status will be federated beyond the local timeline(s) | ||||||
|  | 	Boostable bool `validate:"-" bun:",notnull,default:true"` // This status can be boosted/reblogged | ||||||
|  | 	Replyable bool `validate:"-" bun:",notnull,default:true"` // This status can be replied to | ||||||
|  | 	Likeable  bool `validate:"-" bun:",notnull,default:true"` // This status can be liked/faved | ||||||
|  | } | ||||||
|  | @ -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" | ||||||
|  | 
 | ||||||
|  | // StatusBookmark refers to one account having a 'bookmark' of the status of another account. | ||||||
|  | type StatusBookmark struct { | ||||||
|  | 	ID              string    `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database | ||||||
|  | 	CreatedAt       time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item created | ||||||
|  | 	AccountID       string    `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`           // id of the account that created ('did') the bookmark | ||||||
|  | 	Account         *Account  `validate:"-" bun:"rel:belongs-to"`                                       // account that created the bookmark | ||||||
|  | 	TargetAccountID string    `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`           // id the account owning the bookmarked status | ||||||
|  | 	TargetAccount   *Account  `validate:"-" bun:"rel:belongs-to"`                                       // account owning the bookmarked status | ||||||
|  | 	StatusID        string    `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`           // database id of the status that has been bookmarked | ||||||
|  | 	Status          *Status   `validate:"-" bun:"rel:belongs-to"`                                       // the bookmarked status | ||||||
|  | } | ||||||
|  | @ -0,0 +1,34 @@ | ||||||
|  | /* | ||||||
|  |    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              string    `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database | ||||||
|  | 	CreatedAt       time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item created | ||||||
|  | 	AccountID       string    `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`           // id of the account that created ('did') the fave | ||||||
|  | 	Account         *Account  `validate:"-" bun:"rel:belongs-to"`                                       // account that created the fave | ||||||
|  | 	TargetAccountID string    `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`           // id the account owning the faved status | ||||||
|  | 	TargetAccount   *Account  `validate:"-" bun:"rel:belongs-to"`                                       // account owning the faved status | ||||||
|  | 	StatusID        string    `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`           // database id of the status that has been 'faved' | ||||||
|  | 	Status          *Status   `validate:"-" bun:"rel:belongs-to"`                                       // the faved status | ||||||
|  | 	URI             string    `validate:"required,url" bun:",nullzero,notnull"`                         // ActivityPub URI of this fave | ||||||
|  | } | ||||||
|  | @ -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" | ||||||
|  | 
 | ||||||
|  | // StatusMute refers to one account having muted the status of another account or its own. | ||||||
|  | type StatusMute struct { | ||||||
|  | 	ID              string    `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database | ||||||
|  | 	CreatedAt       time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item created | ||||||
|  | 	AccountID       string    `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`           // id of the account that created ('did') the mute | ||||||
|  | 	Account         *Account  `validate:"-" bun:"rel:belongs-to"`                                       // pointer to the account specified by accountID | ||||||
|  | 	TargetAccountID string    `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`           // id the account owning the muted status (can be the same as accountID) | ||||||
|  | 	TargetAccount   *Account  `validate:"-" bun:"rel:belongs-to"`                                       // pointer to the account specified by targetAccountID | ||||||
|  | 	StatusID        string    `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`           // database id of the status that has been muted | ||||||
|  | 	Status          *Status   `validate:"-" bun:"rel:belongs-to"`                                       // pointer to the muted status specified by statusID | ||||||
|  | } | ||||||
|  | @ -0,0 +1,34 @@ | ||||||
|  | /* | ||||||
|  |    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                     string    `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database | ||||||
|  | 	CreatedAt              time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item created | ||||||
|  | 	UpdatedAt              time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item last updated | ||||||
|  | 	URL                    string    `validate:"required,url" bun:",nullzero,notnull"`                         // Href/web address of this tag, eg https://example.org/tags/somehashtag | ||||||
|  | 	Name                   string    `validate:"required" bun:",unique,nullzero,notnull"`                      // name of this tag -- the tag without the hash part | ||||||
|  | 	FirstSeenFromAccountID string    `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"`                  // Which account ID is the first one we saw using this tag? | ||||||
|  | 	Useable                bool      `validate:"-" bun:",notnull,default:true"`                                // can our instance users use this tag? | ||||||
|  | 	Listable               bool      `validate:"-" bun:",notnull,default:true"`                                // can our instance users look up this tag? | ||||||
|  | 	LastStatusAt           time.Time `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was this tag last used? | ||||||
|  | } | ||||||
|  | @ -0,0 +1,70 @@ | ||||||
|  | /* | ||||||
|  |    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 { | ||||||
|  | 	ID                     string       `validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique"` // id of this item in the database | ||||||
|  | 	CreatedAt              time.Time    `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item created | ||||||
|  | 	UpdatedAt              time.Time    `validate:"-" bun:",nullzero,notnull,default:current_timestamp"`          // when was item last updated | ||||||
|  | 	Email                  string       `validate:"required_with=ConfirmedAt" bun:",nullzero,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 | ||||||
|  | 	AccountID              string       `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull,unique"`    // The id of the local gtsmodel.Account entry for this user. | ||||||
|  | 	Account                *Account     `validate:"-" bun:"rel:belongs-to"`                                       // Pointer to the account of this user that corresponds to AccountID. | ||||||
|  | 	EncryptedPassword      string       `validate:"required" bun:",nullzero,notnull"`                             // 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. | ||||||
|  | 	SignUpIP               net.IP       `validate:"-" bun:",nullzero"`                                            // From what IP was this user created? | ||||||
|  | 	CurrentSignInAt        time.Time    `validate:"-" bun:",nullzero"`                                            // When did the user sign in with their current session. | ||||||
|  | 	CurrentSignInIP        net.IP       `validate:"-" bun:",nullzero"`                                            // What's the most recent IP of this user | ||||||
|  | 	LastSignInAt           time.Time    `validate:"-" bun:",nullzero"`                                            // When did this user last sign in? | ||||||
|  | 	LastSignInIP           net.IP       `validate:"-" bun:",nullzero"`                                            // What's the previous IP of this user? | ||||||
|  | 	SignInCount            int          `validate:"-" bun:",nullzero,notnull,default:0"`                          // How many times has this user signed in? | ||||||
|  | 	InviteID               string       `validate:"omitempty,ulid" bun:"type:CHAR(26),nullzero"`                  // id of the user who invited this user (who let this joker in?) | ||||||
|  | 	ChosenLanguages        []string     `validate:"-" bun:",nullzero"`                                            // What languages does this user want to see? | ||||||
|  | 	FilteredLanguages      []string     `validate:"-" bun:",nullzero"`                                            // What languages does this user not want to see? | ||||||
|  | 	Locale                 string       `validate:"-" bun:",nullzero"`                                            // In what timezone/locale is this user located? | ||||||
|  | 	CreatedByApplicationID string       `validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull"`           // Which application id created this user? See gtsmodel.Application | ||||||
|  | 	CreatedByApplication   *Application `validate:"-" bun:"rel:belongs-to"`                                       // Pointer to the application corresponding to createdbyapplicationID. | ||||||
|  | 	LastEmailedAt          time.Time    `validate:"-" bun:",nullzero"`                                            // When was this user last contacted by email. | ||||||
|  | 	ConfirmationToken      string       `validate:"required_with=ConfirmationSentAt" bun:",nullzero"`             // What confirmation token did we send this user/what are we expecting back? | ||||||
|  | 	ConfirmationSentAt     time.Time    `validate:"required_with=ConfirmationToken" bun:",nullzero"`              // When did we send email confirmation to this user? | ||||||
|  | 	ConfirmedAt            time.Time    `validate:"required_with=Email" bun:",nullzero"`                          // When did the user confirm their email address | ||||||
|  | 	UnconfirmedEmail       string       `validate:"required_without=Email" bun:",nullzero"`                       // Email address that hasn't yet been confirmed | ||||||
|  | 	Moderator              bool         `validate:"-" bun:",notnull,default:false"`                               // Is this user a moderator? | ||||||
|  | 	Admin                  bool         `validate:"-" bun:",notnull,default:false"`                               // Is this user an admin? | ||||||
|  | 	Disabled               bool         `validate:"-" bun:",notnull,default:false"`                               // Is this user disabled from posting? | ||||||
|  | 	Approved               bool         `validate:"-" bun:",notnull,default:false"`                               // Has this user been approved by a moderator? | ||||||
|  | 	ResetPasswordToken     string       `validate:"required_with=ResetPasswordSentAt" bun:",nullzero"`            // The generated token that the user can use to reset their password | ||||||
|  | 	ResetPasswordSentAt    time.Time    `validate:"required_with=ResetPasswordToken" bun:",nullzero"`             // When did we email the user their reset-password email? | ||||||
|  | 
 | ||||||
|  | 	EncryptedOTPSecret     string    `validate:"-" bun:",nullzero"` | ||||||
|  | 	EncryptedOTPSecretIv   string    `validate:"-" bun:",nullzero"` | ||||||
|  | 	EncryptedOTPSecretSalt string    `validate:"-" bun:",nullzero"` | ||||||
|  | 	OTPRequiredForLogin    bool      `validate:"-" bun:",notnull,default:false"` | ||||||
|  | 	OTPBackupCodes         []string  `validate:"-" bun:",nullzero"` | ||||||
|  | 	ConsumedTimestamp      int       `validate:"-" bun:",nullzero"` | ||||||
|  | 	RememberToken          string    `validate:"-" bun:",nullzero"` | ||||||
|  | 	SignInToken            string    `validate:"-" bun:",nullzero"` | ||||||
|  | 	SignInTokenSentAt      time.Time `validate:"-" bun:",nullzero"` | ||||||
|  | 	WebauthnID             string    `validate:"-" bun:",nullzero"` | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								internal/gtsmodel/client.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								internal/gtsmodel/client.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | ||||||
|  | package gtsmodel | ||||||
|  | 
 | ||||||
|  | // Client is a handy little wrapper for typical oauth client details | ||||||
|  | type Client struct { | ||||||
|  | 	ID     string `bun:"type:CHAR(26),pk,notnull"` | ||||||
|  | 	Secret string | ||||||
|  | 	Domain string | ||||||
|  | 	UserID string | ||||||
|  | } | ||||||
							
								
								
									
										50
									
								
								internal/gtsmodel/token.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								internal/gtsmodel/token.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,50 @@ | ||||||
|  | /* | ||||||
|  |    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" | ||||||
|  | 
 | ||||||
|  | // Token is a translation of the gotosocial token with the ExpiresIn fields replaced with ExpiresAt. | ||||||
|  | // | ||||||
|  | // Explanation for this: gotosocial assumes an in-memory or file database of some kind, where a time-to-live parameter (TTL) can be defined, | ||||||
|  | // and tokens with expired TTLs are automatically removed. Since some databases don't have that feature, it's easier to set an expiry time and | ||||||
|  | // then periodically sweep out tokens when that time has passed. | ||||||
|  | // | ||||||
|  | // Note that this struct does *not* satisfy the token interface shown here: https://github.com/superseriousbusiness/oauth2/blob/master/model.go#L22 | ||||||
|  | // and implemented here: https://github.com/superseriousbusiness/oauth2/blob/master/models/token.go. | ||||||
|  | // As such, manual translation is always required between Token and the gotosocial *model.Token. The helper functions oauthTokenToPGToken | ||||||
|  | // and pgTokenToOauthToken can be used for that. | ||||||
|  | type Token struct { | ||||||
|  | 	ID                  string `validate:"ulid" bun:"type:CHAR(26),pk,nullzero,notnull"` | ||||||
|  | 	ClientID            string | ||||||
|  | 	UserID              string | ||||||
|  | 	RedirectURI         string | ||||||
|  | 	Scope               string | ||||||
|  | 	Code                string `bun:"default:'',pk"` | ||||||
|  | 	CodeChallenge       string | ||||||
|  | 	CodeChallengeMethod string | ||||||
|  | 	CodeCreateAt        time.Time `bun:",nullzero"` | ||||||
|  | 	CodeExpiresAt       time.Time `bun:",nullzero"` | ||||||
|  | 	Access              string    `bun:"default:'',pk"` | ||||||
|  | 	AccessCreateAt      time.Time `bun:",nullzero"` | ||||||
|  | 	AccessExpiresAt     time.Time `bun:",nullzero"` | ||||||
|  | 	Refresh             string    `bun:"default:'',pk"` | ||||||
|  | 	RefreshCreateAt     time.Time `bun:",nullzero"` | ||||||
|  | 	RefreshExpiresAt    time.Time `bun:",nullzero"` | ||||||
|  | } | ||||||
|  | @ -1,3 +1,21 @@ | ||||||
|  | /* | ||||||
|  |    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_test | package gtsmodel_test | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  |  | ||||||
|  | @ -22,6 +22,7 @@ import ( | ||||||
| 	"context" | 	"context" | ||||||
| 
 | 
 | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
| 	"github.com/superseriousbusiness/oauth2/v4" | 	"github.com/superseriousbusiness/oauth2/v4" | ||||||
| 	"github.com/superseriousbusiness/oauth2/v4/models" | 	"github.com/superseriousbusiness/oauth2/v4/models" | ||||||
| ) | ) | ||||||
|  | @ -39,7 +40,7 @@ func NewClientStore(db db.Basic) oauth2.ClientStore { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (cs *clientStore) GetByID(ctx context.Context, clientID string) (oauth2.ClientInfo, error) { | func (cs *clientStore) GetByID(ctx context.Context, clientID string) (oauth2.ClientInfo, error) { | ||||||
| 	poc := &Client{} | 	poc := >smodel.Client{} | ||||||
| 	if err := cs.db.GetByID(ctx, clientID, poc); err != nil { | 	if err := cs.db.GetByID(ctx, clientID, poc); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | @ -47,7 +48,7 @@ func (cs *clientStore) GetByID(ctx context.Context, clientID string) (oauth2.Cli | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (cs *clientStore) Set(ctx context.Context, id string, cli oauth2.ClientInfo) error { | func (cs *clientStore) Set(ctx context.Context, id string, cli oauth2.ClientInfo) error { | ||||||
| 	poc := &Client{ | 	poc := >smodel.Client{ | ||||||
| 		ID:     cli.GetID(), | 		ID:     cli.GetID(), | ||||||
| 		Secret: cli.GetSecret(), | 		Secret: cli.GetSecret(), | ||||||
| 		Domain: cli.GetDomain(), | 		Domain: cli.GetDomain(), | ||||||
|  | @ -57,16 +58,8 @@ func (cs *clientStore) Set(ctx context.Context, id string, cli oauth2.ClientInfo | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (cs *clientStore) Delete(ctx context.Context, id string) error { | func (cs *clientStore) Delete(ctx context.Context, id string) error { | ||||||
| 	poc := &Client{ | 	poc := >smodel.Client{ | ||||||
| 		ID: id, | 		ID: id, | ||||||
| 	} | 	} | ||||||
| 	return cs.db.DeleteByID(ctx, id, poc) | 	return cs.db.DeleteByID(ctx, id, poc) | ||||||
| } | } | ||||||
| 
 |  | ||||||
| // Client is a handy little wrapper for typical oauth client details |  | ||||||
| type Client struct { |  | ||||||
| 	ID     string `bun:"type:CHAR(26),pk,notnull"` |  | ||||||
| 	Secret string |  | ||||||
| 	Domain string |  | ||||||
| 	UserID string |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  | @ -26,6 +26,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"github.com/sirupsen/logrus" | 	"github.com/sirupsen/logrus" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/id" | 	"github.com/superseriousbusiness/gotosocial/internal/id" | ||||||
| 	"github.com/superseriousbusiness/oauth2/v4" | 	"github.com/superseriousbusiness/oauth2/v4" | ||||||
| 	"github.com/superseriousbusiness/oauth2/v4/models" | 	"github.com/superseriousbusiness/oauth2/v4/models" | ||||||
|  | @ -71,7 +72,7 @@ func newTokenStore(ctx context.Context, db db.Basic, log *logrus.Logger) oauth2. | ||||||
| func (ts *tokenStore) sweep(ctx context.Context) error { | func (ts *tokenStore) sweep(ctx context.Context) error { | ||||||
| 	// select *all* tokens from the db | 	// select *all* tokens from the db | ||||||
| 	// todo: if this becomes expensive (ie., there are fucking LOADS of tokens) then figure out a better way. | 	// todo: if this becomes expensive (ie., there are fucking LOADS of tokens) then figure out a better way. | ||||||
| 	tokens := new([]*Token) | 	tokens := new([]*gtsmodel.Token) | ||||||
| 	if err := ts.db.GetAll(ctx, tokens); err != nil { | 	if err := ts.db.GetAll(ctx, tokens); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | @ -117,17 +118,17 @@ func (ts *tokenStore) Create(ctx context.Context, info oauth2.TokenInfo) error { | ||||||
| 
 | 
 | ||||||
| // RemoveByCode deletes a token from the DB based on the Code field | // RemoveByCode deletes a token from the DB based on the Code field | ||||||
| func (ts *tokenStore) RemoveByCode(ctx context.Context, code string) error { | func (ts *tokenStore) RemoveByCode(ctx context.Context, code string) error { | ||||||
| 	return ts.db.DeleteWhere(ctx, []db.Where{{Key: "code", Value: code}}, &Token{}) | 	return ts.db.DeleteWhere(ctx, []db.Where{{Key: "code", Value: code}}, >smodel.Token{}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // RemoveByAccess deletes a token from the DB based on the Access field | // RemoveByAccess deletes a token from the DB based on the Access field | ||||||
| func (ts *tokenStore) RemoveByAccess(ctx context.Context, access string) error { | func (ts *tokenStore) RemoveByAccess(ctx context.Context, access string) error { | ||||||
| 	return ts.db.DeleteWhere(ctx, []db.Where{{Key: "access", Value: access}}, &Token{}) | 	return ts.db.DeleteWhere(ctx, []db.Where{{Key: "access", Value: access}}, >smodel.Token{}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // RemoveByRefresh deletes a token from the DB based on the Refresh field | // RemoveByRefresh deletes a token from the DB based on the Refresh field | ||||||
| func (ts *tokenStore) RemoveByRefresh(ctx context.Context, refresh string) error { | func (ts *tokenStore) RemoveByRefresh(ctx context.Context, refresh string) error { | ||||||
| 	return ts.db.DeleteWhere(ctx, []db.Where{{Key: "refresh", Value: refresh}}, &Token{}) | 	return ts.db.DeleteWhere(ctx, []db.Where{{Key: "refresh", Value: refresh}}, >smodel.Token{}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetByCode selects a token from the DB based on the Code field | // GetByCode selects a token from the DB based on the Code field | ||||||
|  | @ -135,7 +136,7 @@ func (ts *tokenStore) GetByCode(ctx context.Context, code string) (oauth2.TokenI | ||||||
| 	if code == "" { | 	if code == "" { | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
| 	dbt := &Token{ | 	dbt := >smodel.Token{ | ||||||
| 		Code: code, | 		Code: code, | ||||||
| 	} | 	} | ||||||
| 	if err := ts.db.GetWhere(ctx, []db.Where{{Key: "code", Value: code}}, dbt); err != nil { | 	if err := ts.db.GetWhere(ctx, []db.Where{{Key: "code", Value: code}}, dbt); err != nil { | ||||||
|  | @ -149,7 +150,7 @@ func (ts *tokenStore) GetByAccess(ctx context.Context, access string) (oauth2.To | ||||||
| 	if access == "" { | 	if access == "" { | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
| 	dbt := &Token{ | 	dbt := >smodel.Token{ | ||||||
| 		Access: access, | 		Access: access, | ||||||
| 	} | 	} | ||||||
| 	if err := ts.db.GetWhere(ctx, []db.Where{{Key: "access", Value: access}}, dbt); err != nil { | 	if err := ts.db.GetWhere(ctx, []db.Where{{Key: "access", Value: access}}, dbt); err != nil { | ||||||
|  | @ -163,7 +164,7 @@ func (ts *tokenStore) GetByRefresh(ctx context.Context, refresh string) (oauth2. | ||||||
| 	if refresh == "" { | 	if refresh == "" { | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
| 	dbt := &Token{ | 	dbt := >smodel.Token{ | ||||||
| 		Refresh: refresh, | 		Refresh: refresh, | ||||||
| 	} | 	} | ||||||
| 	if err := ts.db.GetWhere(ctx, []db.Where{{Key: "refresh", Value: refresh}}, dbt); err != nil { | 	if err := ts.db.GetWhere(ctx, []db.Where{{Key: "refresh", Value: refresh}}, dbt); err != nil { | ||||||
|  | @ -176,37 +177,8 @@ func (ts *tokenStore) GetByRefresh(ctx context.Context, refresh string) (oauth2. | ||||||
| 	The following models are basically helpers for the token store implementation, they should only be used internally. | 	The following models are basically helpers for the token store implementation, they should only be used internally. | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| // Token is a translation of the gotosocial token with the ExpiresIn fields replaced with ExpiresAt. |  | ||||||
| // |  | ||||||
| // Explanation for this: gotosocial assumes an in-memory or file database of some kind, where a time-to-live parameter (TTL) can be defined, |  | ||||||
| // and tokens with expired TTLs are automatically removed. Since some databases don't have that feature, it's easier to set an expiry time and |  | ||||||
| // then periodically sweep out tokens when that time has passed. |  | ||||||
| // |  | ||||||
| // Note that this struct does *not* satisfy the token interface shown here: https://github.com/superseriousbusiness/oauth2/blob/master/model.go#L22 |  | ||||||
| // and implemented here: https://github.com/superseriousbusiness/oauth2/blob/master/models/token.go. |  | ||||||
| // As such, manual translation is always required between Token and the gotosocial *model.Token. The helper functions oauthTokenToPGToken |  | ||||||
| // and pgTokenToOauthToken can be used for that. |  | ||||||
| type Token struct { |  | ||||||
| 	ID                  string `bun:"type:CHAR(26),pk,notnull"` |  | ||||||
| 	ClientID            string |  | ||||||
| 	UserID              string |  | ||||||
| 	RedirectURI         string |  | ||||||
| 	Scope               string |  | ||||||
| 	Code                string `bun:"default:'',pk"` |  | ||||||
| 	CodeChallenge       string |  | ||||||
| 	CodeChallengeMethod string |  | ||||||
| 	CodeCreateAt        time.Time `bun:",nullzero"` |  | ||||||
| 	CodeExpiresAt       time.Time `bun:",nullzero"` |  | ||||||
| 	Access              string    `bun:"default:'',pk"` |  | ||||||
| 	AccessCreateAt      time.Time `bun:",nullzero"` |  | ||||||
| 	AccessExpiresAt     time.Time `bun:",nullzero"` |  | ||||||
| 	Refresh             string    `bun:"default:'',pk"` |  | ||||||
| 	RefreshCreateAt     time.Time `bun:",nullzero"` |  | ||||||
| 	RefreshExpiresAt    time.Time `bun:",nullzero"` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // TokenToDBToken is a lil util function that takes a gotosocial token and gives back a token for inserting into a database. | // TokenToDBToken is a lil util function that takes a gotosocial token and gives back a token for inserting into a database. | ||||||
| func TokenToDBToken(tkn *models.Token) *Token { | func TokenToDBToken(tkn *models.Token) *gtsmodel.Token { | ||||||
| 	now := time.Now() | 	now := time.Now() | ||||||
| 
 | 
 | ||||||
| 	// For the following, we want to make sure we're not adding a time.Now() to an *empty* ExpiresIn, otherwise that's | 	// For the following, we want to make sure we're not adding a time.Now() to an *empty* ExpiresIn, otherwise that's | ||||||
|  | @ -228,7 +200,7 @@ func TokenToDBToken(tkn *models.Token) *Token { | ||||||
| 		rea = now.Add(tkn.RefreshExpiresIn) | 		rea = now.Add(tkn.RefreshExpiresIn) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return &Token{ | 	return >smodel.Token{ | ||||||
| 		ClientID:            tkn.ClientID, | 		ClientID:            tkn.ClientID, | ||||||
| 		UserID:              tkn.UserID, | 		UserID:              tkn.UserID, | ||||||
| 		RedirectURI:         tkn.RedirectURI, | 		RedirectURI:         tkn.RedirectURI, | ||||||
|  | @ -248,7 +220,7 @@ func TokenToDBToken(tkn *models.Token) *Token { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DBTokenToToken is a lil util function that takes a database token and gives back a gotosocial token | // DBTokenToToken is a lil util function that takes a database token and gives back a gotosocial token | ||||||
| func DBTokenToToken(dbt *Token) *models.Token { | func DBTokenToToken(dbt *gtsmodel.Token) *models.Token { | ||||||
| 	now := time.Now() | 	now := time.Now() | ||||||
| 
 | 
 | ||||||
| 	var codeExpiresIn time.Duration | 	var codeExpiresIn time.Duration | ||||||
|  |  | ||||||
|  | @ -27,7 +27,6 @@ import ( | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/messages" | 	"github.com/superseriousbusiness/gotosocial/internal/messages" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/oauth" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Delete handles the complete deletion of an account. | // Delete handles the complete deletion of an account. | ||||||
|  | @ -66,12 +65,12 @@ func (p *processor) Delete(ctx context.Context, account *gtsmodel.Account, origi | ||||||
| 		u := >smodel.User{} | 		u := >smodel.User{} | ||||||
| 		if err := p.db.GetWhere(ctx, []db.Where{{Key: "account_id", Value: account.ID}}, u); err == nil { | 		if err := p.db.GetWhere(ctx, []db.Where{{Key: "account_id", Value: account.ID}}, u); err == nil { | ||||||
| 			// we got one! select all tokens with the user's ID | 			// we got one! select all tokens with the user's ID | ||||||
| 			tokens := []*oauth.Token{} | 			tokens := []*gtsmodel.Token{} | ||||||
| 			if err := p.db.GetWhere(ctx, []db.Where{{Key: "user_id", Value: u.ID}}, &tokens); err == nil { | 			if err := p.db.GetWhere(ctx, []db.Where{{Key: "user_id", Value: u.ID}}, &tokens); err == nil { | ||||||
| 				// we have some tokens to delete | 				// we have some tokens to delete | ||||||
| 				for _, t := range tokens { | 				for _, t := range tokens { | ||||||
| 					// delete client(s) associated with this token | 					// delete client(s) associated with this token | ||||||
| 					if err := p.db.DeleteByID(ctx, t.ClientID, &oauth.Client{}); err != nil { | 					if err := p.db.DeleteByID(ctx, t.ClientID, >smodel.Client{}); err != nil { | ||||||
| 						l.Errorf("error deleting oauth client: %s", err) | 						l.Errorf("error deleting oauth client: %s", err) | ||||||
| 					} | 					} | ||||||
| 					// delete application(s) associated with this token | 					// delete application(s) associated with this token | ||||||
|  |  | ||||||
|  | @ -68,7 +68,7 @@ func (p *processor) AppCreate(ctx context.Context, authed *oauth.Auth, form *api | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// now we need to model an oauth client from the application that the oauth library can use | 	// now we need to model an oauth client from the application that the oauth library can use | ||||||
| 	oc := &oauth.Client{ | 	oc := >smodel.Client{ | ||||||
| 		ID:     clientID, | 		ID:     clientID, | ||||||
| 		Secret: clientSecret, | 		Secret: clientSecret, | ||||||
| 		Domain: form.RedirectURIs, | 		Domain: form.RedirectURIs, | ||||||
|  |  | ||||||
|  | @ -25,7 +25,6 @@ import ( | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/messages" | 	"github.com/superseriousbusiness/gotosocial/internal/messages" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/oauth" |  | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/processing/status" | 	"github.com/superseriousbusiness/gotosocial/internal/processing/status" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/typeutils" | 	"github.com/superseriousbusiness/gotosocial/internal/typeutils" | ||||||
| ) | ) | ||||||
|  | @ -40,8 +39,8 @@ type StatusStandardTestSuite struct { | ||||||
| 	fromClientAPIChan chan messages.FromClientAPI | 	fromClientAPIChan chan messages.FromClientAPI | ||||||
| 
 | 
 | ||||||
| 	// standard suite models | 	// standard suite models | ||||||
| 	testTokens       map[string]*oauth.Token | 	testTokens       map[string]*gtsmodel.Token | ||||||
| 	testClients      map[string]*oauth.Client | 	testClients      map[string]*gtsmodel.Client | ||||||
| 	testApplications map[string]*gtsmodel.Application | 	testApplications map[string]*gtsmodel.Application | ||||||
| 	testUsers        map[string]*gtsmodel.User | 	testUsers        map[string]*gtsmodel.User | ||||||
| 	testAccounts     map[string]*gtsmodel.Account | 	testAccounts     map[string]*gtsmodel.Account | ||||||
|  |  | ||||||
|  | @ -24,7 +24,6 @@ import ( | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/config" | 	"github.com/superseriousbusiness/gotosocial/internal/config" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/oauth" |  | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/text" | 	"github.com/superseriousbusiness/gotosocial/internal/text" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -37,8 +36,8 @@ type TextStandardTestSuite struct { | ||||||
| 	log    *logrus.Logger | 	log    *logrus.Logger | ||||||
| 
 | 
 | ||||||
| 	// standard suite models | 	// standard suite models | ||||||
| 	testTokens       map[string]*oauth.Token | 	testTokens       map[string]*gtsmodel.Token | ||||||
| 	testClients      map[string]*oauth.Client | 	testClients      map[string]*gtsmodel.Client | ||||||
| 	testApplications map[string]*gtsmodel.Application | 	testApplications map[string]*gtsmodel.Application | ||||||
| 	testUsers        map[string]*gtsmodel.User | 	testUsers        map[string]*gtsmodel.User | ||||||
| 	testAccounts     map[string]*gtsmodel.Account | 	testAccounts     map[string]*gtsmodel.Account | ||||||
|  |  | ||||||
|  | @ -26,7 +26,6 @@ import ( | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db/bundb" | 	"github.com/superseriousbusiness/gotosocial/internal/db/bundb" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/oauth" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var testModels []interface{} = []interface{}{ | var testModels []interface{} = []interface{}{ | ||||||
|  | @ -51,8 +50,8 @@ var testModels []interface{} = []interface{}{ | ||||||
| 	>smodel.Instance{}, | 	>smodel.Instance{}, | ||||||
| 	>smodel.Notification{}, | 	>smodel.Notification{}, | ||||||
| 	>smodel.RouterSession{}, | 	>smodel.RouterSession{}, | ||||||
| 	&oauth.Token{}, | 	>smodel.Token{}, | ||||||
| 	&oauth.Client{}, | 	>smodel.Client{}, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NewTestDB returns a new initialized, empty database for testing. | // NewTestDB returns a new initialized, empty database for testing. | ||||||
|  |  | ||||||
|  | @ -38,12 +38,11 @@ import ( | ||||||
| 	"github.com/go-fed/activity/streams/vocab" | 	"github.com/go-fed/activity/streams/vocab" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/ap" | 	"github.com/superseriousbusiness/gotosocial/internal/ap" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/oauth" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // NewTestTokens returns a map of tokens keyed according to which account the token belongs to. | // NewTestTokens returns a map of tokens keyed according to which account the token belongs to. | ||||||
| func NewTestTokens() map[string]*oauth.Token { | func NewTestTokens() map[string]*gtsmodel.Token { | ||||||
| 	tokens := map[string]*oauth.Token{ | 	tokens := map[string]*gtsmodel.Token{ | ||||||
| 		"local_account_1": { | 		"local_account_1": { | ||||||
| 			ID:              "01F8MGTQW4DKTDF8SW5CT9HYGA", | 			ID:              "01F8MGTQW4DKTDF8SW5CT9HYGA", | ||||||
| 			ClientID:        "01F8MGV8AC3NGSJW0FE8W1BV70", | 			ClientID:        "01F8MGV8AC3NGSJW0FE8W1BV70", | ||||||
|  | @ -69,8 +68,8 @@ func NewTestTokens() map[string]*oauth.Token { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NewTestClients returns a map of Clients keyed according to which account they are used by. | // NewTestClients returns a map of Clients keyed according to which account they are used by. | ||||||
| func NewTestClients() map[string]*oauth.Client { | func NewTestClients() map[string]*gtsmodel.Client { | ||||||
| 	clients := map[string]*oauth.Client{ | 	clients := map[string]*gtsmodel.Client{ | ||||||
| 		"admin_account": { | 		"admin_account": { | ||||||
| 			ID:     "01F8MGWSJCND9BWBD4WGJXBM93", | 			ID:     "01F8MGWSJCND9BWBD4WGJXBM93", | ||||||
| 			Secret: "dda8e835-2c9c-4bd2-9b8b-77c2e26d7a7a", | 			Secret: "dda8e835-2c9c-4bd2-9b8b-77c2e26d7a7a", | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue