forked from mirrors/gotosocial
dfdc473cef
* move finger to dereferencer * totally break GetRemoteAccount * start reworking finger func a bit * start reworking getRemoteAccount a bit * move mention parts to namestring * rework webfingerget * use util function to extract webfinger parts * use accountDomain * rework finger again, final form * just a real nasty commit, the worst * remove refresh from account * use new ASRepToAccount signature * fix incorrect debug call * fix for new getRemoteAccount * rework GetRemoteAccount * start updating tests to remove repetition * break a lot of tests Move shared test logic into the testrig, rather than having it scattered all over the place. This allows us to just mock the transport controller once, and have all tests use it (unless they need not to for some other reason). * fix up tests to use main mock httpclient * webfinger only if necessary * cheeky linting with the lads * update mentionName regex recognize instance accounts * don't finger instance accounts * test webfinger part extraction * increase default worker count to 4 per cpu * don't repeat regex parsing * final search for discovered accountDomain * be more permissive in namestring lookup * add more extraction tests * simplify GetParseMentionFunc * skip long search if local account * fix broken test
2935 lines
123 KiB
Go
2935 lines
123 KiB
Go
/*
|
|
GoToSocial
|
|
Copyright (C) 2021-2022 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 testrig
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/x509"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/superseriousbusiness/activity/pub"
|
|
"github.com/superseriousbusiness/activity/streams"
|
|
"github.com/superseriousbusiness/activity/streams/vocab"
|
|
"github.com/superseriousbusiness/gotosocial/internal/ap"
|
|
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
|
"github.com/superseriousbusiness/gotosocial/internal/transport"
|
|
)
|
|
|
|
// NewTestTokens returns a map of tokens keyed according to which account the token belongs to.
|
|
func NewTestTokens() map[string]*gtsmodel.Token {
|
|
tokens := map[string]*gtsmodel.Token{
|
|
"local_account_1": {
|
|
ID: "01F8MGTQW4DKTDF8SW5CT9HYGA",
|
|
ClientID: "01F8MGV8AC3NGSJW0FE8W1BV70",
|
|
UserID: "01F8MGVGPHQ2D3P3X0454H54Z5",
|
|
RedirectURI: "http://localhost:8080",
|
|
Scope: "read write follow push",
|
|
Access: "NZAZOTC0OWITMDU0NC0ZODG4LWE4NJITMWUXM2M4MTRHZDEX",
|
|
AccessCreateAt: time.Now(),
|
|
AccessExpiresAt: time.Now().Add(72 * time.Hour),
|
|
},
|
|
"local_account_1_client_application_token": {
|
|
ID: "01P9SVWS9J3SPHZQ3KCMBEN70N",
|
|
ClientID: "01F8MGV8AC3NGSJW0FE8W1BV70",
|
|
RedirectURI: "http://localhost:8080",
|
|
Access: "ZTK1MWMWZDGTMGMXOS0ZY2UXLWI5ZWETMWEZYZZIYTLHMZI4",
|
|
AccessCreateAt: TimeMustParse("2022-06-10T15:22:08Z"),
|
|
AccessExpiresAt: TimeMustParse("2050-01-01T15:22:08Z"),
|
|
},
|
|
"local_account_1_user_authorization_token": {
|
|
ID: "01G574M2VTV66YZBC9AZ7HY3FV",
|
|
ClientID: "01F8MGV8AC3NGSJW0FE8W1BV70",
|
|
UserID: "01F8MGVGPHQ2D3P3X0454H54Z5",
|
|
RedirectURI: "http://localhost:8080",
|
|
Code: "ZJYYMZQ0MTQTZTU1NC0ZNJK4LWE2ZWITYTM1MDHHOTAXNJHL",
|
|
CodeCreateAt: TimeMustParse("2022-06-10T15:22:08Z"),
|
|
CodeExpiresAt: TimeMustParse("2050-01-01T15:22:08Z"),
|
|
},
|
|
"local_account_2": {
|
|
ID: "01F8MGVVM1EDVYET710J27XY5R",
|
|
ClientID: "01F8MGW47HN8ZXNHNZ7E47CDMQ",
|
|
UserID: "01F8MH1VYJAE00TVVGMM5JNJ8X",
|
|
RedirectURI: "http://localhost:8080",
|
|
Scope: "read write follow push",
|
|
Access: "PIPINALKNNNFNF98717NAMNAMNFKIJKJ881818KJKJAKJJJA",
|
|
AccessCreateAt: time.Now(),
|
|
AccessExpiresAt: time.Now().Add(72 * time.Hour),
|
|
},
|
|
"admin_account": {
|
|
ID: "01FS4TP8ANA5VE92EAPA9E0M7Q",
|
|
ClientID: "01F8MGWSJCND9BWBD4WGJXBM93",
|
|
UserID: "01F8MGWYWKVKS3VS8DV1AMYPGE",
|
|
RedirectURI: "http://localhost:8080",
|
|
Scope: "read write follow push admin",
|
|
Access: "AININALKNENFNF98717NAMG4LWE4NJITMWUXM2M4MTRHZDEX",
|
|
AccessCreateAt: time.Now(),
|
|
AccessExpiresAt: time.Now().Add(72 * time.Hour),
|
|
},
|
|
}
|
|
return tokens
|
|
}
|
|
|
|
// NewTestClients returns a map of Clients keyed according to which account they are used by.
|
|
func NewTestClients() map[string]*gtsmodel.Client {
|
|
clients := map[string]*gtsmodel.Client{
|
|
"admin_account": {
|
|
ID: "01F8MGWSJCND9BWBD4WGJXBM93",
|
|
Secret: "dda8e835-2c9c-4bd2-9b8b-77c2e26d7a7a",
|
|
Domain: "http://localhost:8080",
|
|
UserID: "01F8MGWYWKVKS3VS8DV1AMYPGE", // admin_account
|
|
},
|
|
"local_account_1": {
|
|
ID: "01F8MGV8AC3NGSJW0FE8W1BV70",
|
|
Secret: "c3724c74-dc3b-41b2-a108-0ea3d8399830",
|
|
Domain: "http://localhost:8080",
|
|
UserID: "01F8MGVGPHQ2D3P3X0454H54Z5", // local_account_1
|
|
},
|
|
"local_account_2": {
|
|
ID: "01F8MGW47HN8ZXNHNZ7E47CDMQ",
|
|
Secret: "8f5603a5-c721-46cd-8f1b-2e368f51379f",
|
|
Domain: "http://localhost:8080",
|
|
UserID: "01F8MH1VYJAE00TVVGMM5JNJ8X", // local_account_2
|
|
},
|
|
}
|
|
return clients
|
|
}
|
|
|
|
// NewTestApplications returns a map of applications keyed to which number application they are.
|
|
func NewTestApplications() map[string]*gtsmodel.Application {
|
|
apps := map[string]*gtsmodel.Application{
|
|
"admin_account": {
|
|
ID: "01F8MGXQRHYF5QPMTMXP78QC2F",
|
|
Name: "superseriousbusiness",
|
|
Website: "https://superserious.business",
|
|
RedirectURI: "http://localhost:8080",
|
|
ClientID: "01F8MGWSJCND9BWBD4WGJXBM93", // admin client
|
|
ClientSecret: "dda8e835-2c9c-4bd2-9b8b-77c2e26d7a7a", // admin client
|
|
Scopes: "read write follow push",
|
|
},
|
|
"application_1": {
|
|
ID: "01F8MGY43H3N2C8EWPR2FPYEXG",
|
|
Name: "really cool gts application",
|
|
Website: "https://reallycool.app",
|
|
RedirectURI: "http://localhost:8080",
|
|
ClientID: "01F8MGV8AC3NGSJW0FE8W1BV70", // client_1
|
|
ClientSecret: "c3724c74-dc3b-41b2-a108-0ea3d8399830", // client_1
|
|
Scopes: "read write follow push",
|
|
},
|
|
"application_2": {
|
|
ID: "01F8MGYG9E893WRHW0TAEXR8GJ",
|
|
Name: "kindaweird",
|
|
Website: "https://kindaweird.app",
|
|
RedirectURI: "http://localhost:8080",
|
|
ClientID: "01F8MGW47HN8ZXNHNZ7E47CDMQ", // client_2
|
|
ClientSecret: "8f5603a5-c721-46cd-8f1b-2e368f51379f", // client_2
|
|
Scopes: "read write follow push",
|
|
},
|
|
}
|
|
return apps
|
|
}
|
|
|
|
// NewTestUsers returns a map of Users keyed by which account belongs to them.
|
|
func NewTestUsers() map[string]*gtsmodel.User {
|
|
users := map[string]*gtsmodel.User{
|
|
"unconfirmed_account": {
|
|
ID: "01F8MGYG9E893WRHW0TAEXR8GJ",
|
|
Email: "",
|
|
AccountID: "01F8MH0BBE4FHXPH513MBVFHB0",
|
|
EncryptedPassword: "$2y$10$ggWz5QWwnx6kzb9g0tnIJurFtE0dhr5Zfeaqs9iFuUIXzafQlJVZS", // 'password'
|
|
CreatedAt: time.Now(),
|
|
SignUpIP: net.ParseIP("199.222.111.89"),
|
|
UpdatedAt: time.Time{},
|
|
CurrentSignInAt: time.Time{},
|
|
CurrentSignInIP: nil,
|
|
LastSignInAt: time.Time{},
|
|
LastSignInIP: nil,
|
|
SignInCount: 0,
|
|
InviteID: "",
|
|
ChosenLanguages: []string{},
|
|
FilteredLanguages: []string{},
|
|
Locale: "en",
|
|
CreatedByApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG",
|
|
LastEmailedAt: time.Time{},
|
|
ConfirmationToken: "a5a280bd-34be-44a3-8330-a57eaf61b8dd",
|
|
ConfirmedAt: time.Time{},
|
|
ConfirmationSentAt: time.Now(),
|
|
UnconfirmedEmail: "weed_lord420@example.org",
|
|
Moderator: false,
|
|
Admin: false,
|
|
Disabled: false,
|
|
Approved: false,
|
|
ResetPasswordToken: "",
|
|
ResetPasswordSentAt: time.Time{},
|
|
},
|
|
"admin_account": {
|
|
ID: "01F8MGWYWKVKS3VS8DV1AMYPGE",
|
|
Email: "admin@example.org",
|
|
AccountID: "01F8MH17FWEB39HZJ76B6VXSKF",
|
|
EncryptedPassword: "$2y$10$ggWz5QWwnx6kzb9g0tnIJurFtE0dhr5Zfeaqs9iFuUIXzafQlJVZS", // 'password'
|
|
CreatedAt: time.Now().Add(-72 * time.Hour),
|
|
SignUpIP: net.ParseIP("89.22.189.19"),
|
|
UpdatedAt: time.Now().Add(-72 * time.Hour),
|
|
CurrentSignInAt: time.Now().Add(-10 * time.Minute),
|
|
CurrentSignInIP: net.ParseIP("89.122.255.1"),
|
|
LastSignInAt: time.Now().Add(-2 * time.Hour),
|
|
LastSignInIP: net.ParseIP("89.122.255.1"),
|
|
SignInCount: 78,
|
|
InviteID: "",
|
|
ChosenLanguages: []string{"en"},
|
|
FilteredLanguages: []string{},
|
|
Locale: "en",
|
|
CreatedByApplicationID: "01F8MGXQRHYF5QPMTMXP78QC2F",
|
|
LastEmailedAt: time.Now().Add(-30 * time.Minute),
|
|
ConfirmationToken: "",
|
|
ConfirmedAt: time.Now().Add(-72 * time.Hour),
|
|
ConfirmationSentAt: time.Time{},
|
|
UnconfirmedEmail: "",
|
|
Moderator: true,
|
|
Admin: true,
|
|
Disabled: false,
|
|
Approved: true,
|
|
ResetPasswordToken: "",
|
|
ResetPasswordSentAt: time.Time{},
|
|
},
|
|
"local_account_1": {
|
|
ID: "01F8MGVGPHQ2D3P3X0454H54Z5",
|
|
Email: "zork@example.org",
|
|
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
EncryptedPassword: "$2y$10$ggWz5QWwnx6kzb9g0tnIJurFtE0dhr5Zfeaqs9iFuUIXzafQlJVZS", // 'password'
|
|
CreatedAt: time.Now().Add(-36 * time.Hour),
|
|
SignUpIP: net.ParseIP("59.99.19.172"),
|
|
UpdatedAt: time.Now().Add(-72 * time.Hour),
|
|
CurrentSignInAt: time.Now().Add(-30 * time.Minute),
|
|
CurrentSignInIP: net.ParseIP("88.234.118.16"),
|
|
LastSignInAt: time.Now().Add(-2 * time.Hour),
|
|
LastSignInIP: net.ParseIP("147.111.231.154"),
|
|
SignInCount: 9,
|
|
InviteID: "",
|
|
ChosenLanguages: []string{"en"},
|
|
FilteredLanguages: []string{},
|
|
Locale: "en",
|
|
CreatedByApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG",
|
|
LastEmailedAt: time.Now().Add(-55 * time.Minute),
|
|
ConfirmationToken: "",
|
|
ConfirmedAt: time.Now().Add(-34 * time.Hour),
|
|
ConfirmationSentAt: time.Now().Add(-36 * time.Hour),
|
|
UnconfirmedEmail: "",
|
|
Moderator: false,
|
|
Admin: false,
|
|
Disabled: false,
|
|
Approved: true,
|
|
ResetPasswordToken: "",
|
|
ResetPasswordSentAt: time.Time{},
|
|
},
|
|
"local_account_2": {
|
|
ID: "01F8MH1VYJAE00TVVGMM5JNJ8X",
|
|
Email: "tortle.dude@example.org",
|
|
AccountID: "01F8MH5NBDF2MV7CTC4Q5128HF",
|
|
EncryptedPassword: "$2y$10$ggWz5QWwnx6kzb9g0tnIJurFtE0dhr5Zfeaqs9iFuUIXzafQlJVZS", // 'password'
|
|
CreatedAt: time.Now().Add(-36 * time.Hour),
|
|
SignUpIP: net.ParseIP("59.99.19.172"),
|
|
UpdatedAt: time.Now().Add(-72 * time.Hour),
|
|
CurrentSignInAt: time.Now().Add(-30 * time.Minute),
|
|
CurrentSignInIP: net.ParseIP("118.44.18.196"),
|
|
LastSignInAt: time.Now().Add(-2 * time.Hour),
|
|
LastSignInIP: net.ParseIP("198.98.21.15"),
|
|
SignInCount: 9,
|
|
InviteID: "",
|
|
ChosenLanguages: []string{"en"},
|
|
FilteredLanguages: []string{},
|
|
Locale: "en",
|
|
CreatedByApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG",
|
|
LastEmailedAt: time.Now().Add(-55 * time.Minute),
|
|
ConfirmationToken: "",
|
|
ConfirmedAt: time.Now().Add(-34 * time.Hour),
|
|
ConfirmationSentAt: time.Now().Add(-36 * time.Hour),
|
|
UnconfirmedEmail: "",
|
|
Moderator: false,
|
|
Admin: false,
|
|
Disabled: false,
|
|
Approved: true,
|
|
ResetPasswordToken: "",
|
|
ResetPasswordSentAt: time.Time{},
|
|
},
|
|
}
|
|
|
|
return users
|
|
}
|
|
|
|
// NewTestAccounts returns a map of accounts keyed by what type of account they are.
|
|
func NewTestAccounts() map[string]*gtsmodel.Account {
|
|
accounts := map[string]*gtsmodel.Account{
|
|
"unconfirmed_account": {
|
|
ID: "01F8MH0BBE4FHXPH513MBVFHB0",
|
|
Username: "weed_lord420",
|
|
AvatarMediaAttachmentID: "",
|
|
HeaderMediaAttachmentID: "",
|
|
DisplayName: "",
|
|
Fields: []gtsmodel.Field{},
|
|
Note: "",
|
|
Memorial: false,
|
|
MovedToAccountID: "",
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
Bot: false,
|
|
Reason: "hi, please let me in! I'm looking for somewhere neato bombeato to hang out.",
|
|
Locked: false,
|
|
Discoverable: false,
|
|
Privacy: gtsmodel.VisibilityPublic,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
URI: "http://localhost:8080/users/weed_lord420",
|
|
URL: "http://localhost:8080/@weed_lord420",
|
|
LastWebfingeredAt: time.Time{},
|
|
InboxURI: "http://localhost:8080/users/weed_lord420/inbox",
|
|
OutboxURI: "http://localhost:8080/users/weed_lord420/outbox",
|
|
FollowersURI: "http://localhost:8080/users/weed_lord420/followers",
|
|
FollowingURI: "http://localhost:8080/users/weed_lord420/following",
|
|
FeaturedCollectionURI: "http://localhost:8080/users/weed_lord420/collections/featured",
|
|
ActorType: ap.ActorPerson,
|
|
AlsoKnownAs: "",
|
|
PrivateKey: &rsa.PrivateKey{},
|
|
PublicKey: &rsa.PublicKey{},
|
|
PublicKeyURI: "http://localhost:8080/users/weed_lord420#main-key",
|
|
SensitizedAt: time.Time{},
|
|
SilencedAt: time.Time{},
|
|
SuspendedAt: time.Time{},
|
|
HideCollections: false,
|
|
SuspensionOrigin: "",
|
|
},
|
|
"admin_account": {
|
|
ID: "01F8MH17FWEB39HZJ76B6VXSKF",
|
|
Username: "admin",
|
|
AvatarMediaAttachmentID: "",
|
|
HeaderMediaAttachmentID: "",
|
|
DisplayName: "",
|
|
Fields: []gtsmodel.Field{},
|
|
Note: "",
|
|
NoteRaw: "",
|
|
Memorial: false,
|
|
MovedToAccountID: "",
|
|
CreatedAt: TimeMustParse("2022-05-17T13:10:59Z"),
|
|
UpdatedAt: TimeMustParse("2022-05-17T13:10:59Z"),
|
|
Bot: false,
|
|
Reason: "",
|
|
Locked: false,
|
|
Discoverable: true,
|
|
Privacy: gtsmodel.VisibilityPublic,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
URI: "http://localhost:8080/users/admin",
|
|
URL: "http://localhost:8080/@admin",
|
|
PublicKeyURI: "http://localhost:8080/users/admin#main-key",
|
|
LastWebfingeredAt: time.Time{},
|
|
InboxURI: "http://localhost:8080/users/admin/inbox",
|
|
OutboxURI: "http://localhost:8080/users/admin/outbox",
|
|
FollowersURI: "http://localhost:8080/users/admin/followers",
|
|
FollowingURI: "http://localhost:8080/users/admin/following",
|
|
FeaturedCollectionURI: "http://localhost:8080/users/admin/collections/featured",
|
|
ActorType: ap.ActorPerson,
|
|
AlsoKnownAs: "",
|
|
PrivateKey: &rsa.PrivateKey{},
|
|
PublicKey: &rsa.PublicKey{},
|
|
SensitizedAt: time.Time{},
|
|
SilencedAt: time.Time{},
|
|
SuspendedAt: time.Time{},
|
|
HideCollections: false,
|
|
SuspensionOrigin: "",
|
|
},
|
|
"local_account_1": {
|
|
ID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
Username: "the_mighty_zork",
|
|
AvatarMediaAttachmentID: "01F8MH58A357CV5K7R7TJMSH6S",
|
|
HeaderMediaAttachmentID: "01PFPMWK2FF0D9WMHEJHR07C3Q",
|
|
DisplayName: "original zork (he/they)",
|
|
Fields: []gtsmodel.Field{},
|
|
Note: "<p>hey yo this is my profile!</p>",
|
|
NoteRaw: "hey yo this is my profile!",
|
|
Memorial: false,
|
|
MovedToAccountID: "",
|
|
CreatedAt: TimeMustParse("2022-05-20T11:09:18Z"),
|
|
UpdatedAt: TimeMustParse("2022-05-20T11:09:18Z"),
|
|
Bot: false,
|
|
Reason: "I wanna be on this damned webbed site so bad! Please! Wow",
|
|
Locked: false,
|
|
Discoverable: true,
|
|
Privacy: gtsmodel.VisibilityPublic,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
URI: "http://localhost:8080/users/the_mighty_zork",
|
|
URL: "http://localhost:8080/@the_mighty_zork",
|
|
LastWebfingeredAt: time.Time{},
|
|
InboxURI: "http://localhost:8080/users/the_mighty_zork/inbox",
|
|
OutboxURI: "http://localhost:8080/users/the_mighty_zork/outbox",
|
|
FollowersURI: "http://localhost:8080/users/the_mighty_zork/followers",
|
|
FollowingURI: "http://localhost:8080/users/the_mighty_zork/following",
|
|
FeaturedCollectionURI: "http://localhost:8080/users/the_mighty_zork/collections/featured",
|
|
ActorType: ap.ActorPerson,
|
|
AlsoKnownAs: "",
|
|
PrivateKey: &rsa.PrivateKey{},
|
|
PublicKey: &rsa.PublicKey{},
|
|
PublicKeyURI: "http://localhost:8080/users/the_mighty_zork/main-key",
|
|
SensitizedAt: time.Time{},
|
|
SilencedAt: time.Time{},
|
|
SuspendedAt: time.Time{},
|
|
HideCollections: false,
|
|
SuspensionOrigin: "",
|
|
},
|
|
"local_account_2": {
|
|
ID: "01F8MH5NBDF2MV7CTC4Q5128HF",
|
|
Username: "1happyturtle",
|
|
AvatarMediaAttachmentID: "",
|
|
HeaderMediaAttachmentID: "",
|
|
DisplayName: "happy little turtle :3",
|
|
Fields: []gtsmodel.Field{},
|
|
Note: "<p>i post about things that concern me</p>",
|
|
NoteRaw: "i post about things that concern me",
|
|
Memorial: false,
|
|
MovedToAccountID: "",
|
|
CreatedAt: time.Now().Add(-190 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-36 * time.Hour),
|
|
Bot: false,
|
|
Reason: "",
|
|
Locked: true,
|
|
Discoverable: false,
|
|
Privacy: gtsmodel.VisibilityFollowersOnly,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
URI: "http://localhost:8080/users/1happyturtle",
|
|
URL: "http://localhost:8080/@1happyturtle",
|
|
LastWebfingeredAt: time.Time{},
|
|
InboxURI: "http://localhost:8080/users/1happyturtle/inbox",
|
|
OutboxURI: "http://localhost:8080/users/1happyturtle/outbox",
|
|
FollowersURI: "http://localhost:8080/users/1happyturtle/followers",
|
|
FollowingURI: "http://localhost:8080/users/1happyturtle/following",
|
|
FeaturedCollectionURI: "http://localhost:8080/users/1happyturtle/collections/featured",
|
|
ActorType: ap.ActorPerson,
|
|
AlsoKnownAs: "",
|
|
PrivateKey: &rsa.PrivateKey{},
|
|
PublicKey: &rsa.PublicKey{},
|
|
PublicKeyURI: "http://localhost:8080/users/1happyturtle#main-key",
|
|
SensitizedAt: time.Time{},
|
|
SilencedAt: time.Time{},
|
|
SuspendedAt: time.Time{},
|
|
HideCollections: false,
|
|
SuspensionOrigin: "",
|
|
},
|
|
"remote_account_1": {
|
|
ID: "01F8MH5ZK5VRH73AKHQM6Y9VNX",
|
|
Username: "foss_satan",
|
|
Domain: "fossbros-anonymous.io",
|
|
DisplayName: "big gerald",
|
|
Fields: []gtsmodel.Field{},
|
|
Note: "i post about like, i dunno, stuff, or whatever!!!!",
|
|
Memorial: false,
|
|
MovedToAccountID: "",
|
|
CreatedAt: TimeMustParse("2021-09-26T12:52:36+02:00"),
|
|
UpdatedAt: time.Now().Add(-36 * time.Hour),
|
|
Bot: false,
|
|
Locked: false,
|
|
Discoverable: true,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
URI: "http://fossbros-anonymous.io/users/foss_satan",
|
|
URL: "http://fossbros-anonymous.io/@foss_satan",
|
|
LastWebfingeredAt: time.Time{},
|
|
InboxURI: "http://fossbros-anonymous.io/users/foss_satan/inbox",
|
|
OutboxURI: "http://fossbros-anonymous.io/users/foss_satan/outbox",
|
|
FollowersURI: "http://fossbros-anonymous.io/users/foss_satan/followers",
|
|
FollowingURI: "http://fossbros-anonymous.io/users/foss_satan/following",
|
|
FeaturedCollectionURI: "http://fossbros-anonymous.io/users/foss_satan/collections/featured",
|
|
ActorType: ap.ActorPerson,
|
|
AlsoKnownAs: "",
|
|
PrivateKey: &rsa.PrivateKey{},
|
|
PublicKey: &rsa.PublicKey{},
|
|
PublicKeyURI: "http://fossbros-anonymous.io/users/foss_satan/main-key",
|
|
SensitizedAt: time.Time{},
|
|
SilencedAt: time.Time{},
|
|
SuspendedAt: time.Time{},
|
|
HideCollections: false,
|
|
SuspensionOrigin: "",
|
|
},
|
|
"remote_account_2": {
|
|
ID: "01FHMQX3GAABWSM0S2VZEC2SWC",
|
|
Username: "some_user",
|
|
Domain: "example.org",
|
|
DisplayName: "some user",
|
|
Fields: []gtsmodel.Field{},
|
|
Note: "i'm a real son of a gun",
|
|
Memorial: false,
|
|
MovedToAccountID: "",
|
|
CreatedAt: TimeMustParse("2020-08-10T14:13:28+02:00"),
|
|
UpdatedAt: time.Now().Add(-1 * time.Hour),
|
|
Bot: false,
|
|
Locked: true,
|
|
Discoverable: true,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
URI: "http://example.org/users/some_user",
|
|
URL: "http://example.org/@some_user",
|
|
LastWebfingeredAt: time.Time{},
|
|
InboxURI: "http://example.org/users/some_user/inbox",
|
|
OutboxURI: "http://example.org/users/some_user/outbox",
|
|
FollowersURI: "http://example.org/users/some_user/followers",
|
|
FollowingURI: "http://example.org/users/some_user/following",
|
|
FeaturedCollectionURI: "http://example.org/users/some_user/collections/featured",
|
|
ActorType: ap.ActorPerson,
|
|
AlsoKnownAs: "",
|
|
PrivateKey: &rsa.PrivateKey{},
|
|
PublicKey: &rsa.PublicKey{},
|
|
PublicKeyURI: "http://example.org/users/some_user#main-key",
|
|
SensitizedAt: time.Time{},
|
|
SilencedAt: time.Time{},
|
|
SuspendedAt: time.Time{},
|
|
HideCollections: false,
|
|
SuspensionOrigin: "",
|
|
},
|
|
}
|
|
|
|
var accountsSorted []*gtsmodel.Account
|
|
for _, a := range accounts {
|
|
accountsSorted = append(accountsSorted, a)
|
|
}
|
|
|
|
sort.Slice(accountsSorted, func(i, j int) bool {
|
|
return accountsSorted[i].ID > accountsSorted[j].ID
|
|
})
|
|
|
|
preserializedKeys := []string{
|
|
"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",
|
|
}
|
|
|
|
if diff := len(accountsSorted) - len(preserializedKeys); diff > 0 {
|
|
keyStrings := make([]string, diff)
|
|
for i := 0; i < diff; i++ {
|
|
priv, _ := rsa.GenerateKey(rand.Reader, 2048)
|
|
key, _ := x509.MarshalPKCS8PrivateKey(priv)
|
|
keyStrings = append(keyStrings, base64.StdEncoding.EncodeToString(key))
|
|
}
|
|
panic(fmt.Sprintf("mismatch between number of hardcoded test RSA keys and accounts used for test data. Insert the following generated key[s]: \n%+v", keyStrings))
|
|
}
|
|
|
|
for i, v := range accountsSorted {
|
|
premadeBytes, err := base64.StdEncoding.DecodeString(preserializedKeys[i])
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
key, err := x509.ParsePKCS8PrivateKey(premadeBytes)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
priv, ok := key.(*rsa.PrivateKey)
|
|
if !ok {
|
|
panic(fmt.Sprintf("generated key at index %d is of incorrect type", i))
|
|
}
|
|
v.PrivateKey = priv
|
|
v.PublicKey = &priv.PublicKey
|
|
}
|
|
|
|
return accounts
|
|
}
|
|
|
|
// NewTestAttachments returns a map of attachments keyed according to which account
|
|
// and status they belong to, and which attachment number of that status they are.
|
|
func NewTestAttachments() map[string]*gtsmodel.MediaAttachment {
|
|
return map[string]*gtsmodel.MediaAttachment{
|
|
"admin_account_status_1_attachment_1": {
|
|
ID: "01F8MH6NEM8D7527KZAECTCR76",
|
|
StatusID: "01F8MH75CBF9JFX4ZAD54N0W0R",
|
|
URL: "http://localhost:8080/fileserver/01F8MH17FWEB39HZJ76B6VXSKF/attachment/original/01F8MH6NEM8D7527KZAECTCR76.jpeg",
|
|
RemoteURL: "",
|
|
CreatedAt: time.Now().Add(-71 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-71 * time.Hour),
|
|
Type: gtsmodel.FileTypeImage,
|
|
FileMeta: gtsmodel.FileMeta{
|
|
Original: gtsmodel.Original{
|
|
Width: 1200,
|
|
Height: 630,
|
|
Size: 756000,
|
|
Aspect: 1.9047619047619047,
|
|
},
|
|
Small: gtsmodel.Small{
|
|
Width: 256,
|
|
Height: 134,
|
|
Size: 34304,
|
|
Aspect: 1.9104477611940298,
|
|
},
|
|
},
|
|
AccountID: "01F8MH17FWEB39HZJ76B6VXSKF",
|
|
Description: "Black and white image of some 50's style text saying: Welcome On Board",
|
|
ScheduledStatusID: "",
|
|
Blurhash: "LNJRdVM{00Rj%Mayt7j[4nWBofRj",
|
|
Processing: 2,
|
|
File: gtsmodel.File{
|
|
Path: "01F8MH17FWEB39HZJ76B6VXSKF/attachment/original/01F8MH6NEM8D7527KZAECTCR76.jpeg",
|
|
ContentType: "image/jpeg",
|
|
FileSize: 62529,
|
|
UpdatedAt: time.Now().Add(-71 * time.Hour),
|
|
},
|
|
Thumbnail: gtsmodel.Thumbnail{
|
|
Path: "01F8MH17FWEB39HZJ76B6VXSKF/attachment/small/01F8MH6NEM8D7527KZAECTCR76.jpeg",
|
|
ContentType: "image/jpeg",
|
|
FileSize: 6872,
|
|
UpdatedAt: time.Now().Add(-71 * time.Hour),
|
|
URL: "http://localhost:8080/fileserver/01F8MH17FWEB39HZJ76B6VXSKF/attachment/small/01F8MH6NEM8D7527KZAECTCR76.jpeg",
|
|
RemoteURL: "",
|
|
},
|
|
Avatar: false,
|
|
Header: false,
|
|
Cached: true,
|
|
},
|
|
"local_account_1_status_4_attachment_1": {
|
|
ID: "01F8MH7TDVANYKWVE8VVKFPJTJ",
|
|
StatusID: "01F8MH82FYRXD2RC6108DAJ5HB",
|
|
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/original/01F8MH7TDVANYKWVE8VVKFPJTJ.gif",
|
|
RemoteURL: "",
|
|
CreatedAt: time.Now().Add(-1 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-1 * time.Hour),
|
|
Type: gtsmodel.FileTypeGif,
|
|
FileMeta: gtsmodel.FileMeta{
|
|
Original: gtsmodel.Original{
|
|
Width: 400,
|
|
Height: 280,
|
|
Size: 756000,
|
|
Aspect: 1.4285714285714286,
|
|
},
|
|
Small: gtsmodel.Small{
|
|
Width: 256,
|
|
Height: 179,
|
|
Size: 45824,
|
|
Aspect: 1.4301675977653632,
|
|
},
|
|
Focus: gtsmodel.Focus{
|
|
X: 0,
|
|
Y: 0,
|
|
},
|
|
},
|
|
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
Description: "90's Trent Reznor turning to the camera",
|
|
ScheduledStatusID: "",
|
|
Blurhash: "LEDara58O=t5EMSOENEN9]}?aK%0",
|
|
Processing: 2,
|
|
File: gtsmodel.File{
|
|
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/original/01F8MH7TDVANYKWVE8VVKFPJTJ.gif",
|
|
ContentType: "image/gif",
|
|
FileSize: 1109138,
|
|
UpdatedAt: time.Now().Add(-1 * time.Hour),
|
|
},
|
|
Thumbnail: gtsmodel.Thumbnail{
|
|
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01F8MH7TDVANYKWVE8VVKFPJTJ.jpeg",
|
|
ContentType: "image/jpeg",
|
|
FileSize: 8803,
|
|
UpdatedAt: time.Now().Add(-1 * time.Hour),
|
|
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01F8MH7TDVANYKWVE8VVKFPJTJ.jpeg",
|
|
RemoteURL: "",
|
|
},
|
|
Avatar: false,
|
|
Header: false,
|
|
Cached: true,
|
|
},
|
|
"local_account_1_unattached_1": {
|
|
ID: "01F8MH8RMYQ6MSNY3JM2XT1CQ5",
|
|
StatusID: "", // this attachment isn't connected to a status YET
|
|
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/original/01F8MH8RMYQ6MSNY3JM2XT1CQ5.jpeg",
|
|
RemoteURL: "",
|
|
CreatedAt: time.Now().Add(30 * time.Second),
|
|
UpdatedAt: time.Now().Add(30 * time.Second),
|
|
Type: gtsmodel.FileTypeGif,
|
|
FileMeta: gtsmodel.FileMeta{
|
|
Original: gtsmodel.Original{
|
|
Width: 800,
|
|
Height: 450,
|
|
Size: 360000,
|
|
Aspect: 1.7777777777777777,
|
|
},
|
|
Small: gtsmodel.Small{
|
|
Width: 256,
|
|
Height: 144,
|
|
Size: 36864,
|
|
Aspect: 1.7777777777777777,
|
|
},
|
|
Focus: gtsmodel.Focus{
|
|
X: 0,
|
|
Y: 0,
|
|
},
|
|
},
|
|
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
Description: "the oh you meme",
|
|
ScheduledStatusID: "",
|
|
Blurhash: "LSAd]9ogDge-R:M|j=xWIto0xXWX",
|
|
Processing: 2,
|
|
File: gtsmodel.File{
|
|
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/original/01F8MH8RMYQ6MSNY3JM2XT1CQ5.jpeg",
|
|
ContentType: "image/jpeg",
|
|
FileSize: 27759,
|
|
UpdatedAt: time.Now().Add(30 * time.Second),
|
|
},
|
|
Thumbnail: gtsmodel.Thumbnail{
|
|
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01F8MH8RMYQ6MSNY3JM2XT1CQ5.jpeg",
|
|
ContentType: "image/jpeg",
|
|
FileSize: 6177,
|
|
UpdatedAt: time.Now().Add(30 * time.Second),
|
|
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01F8MH8RMYQ6MSNY3JM2XT1CQ5.jpeg",
|
|
RemoteURL: "",
|
|
},
|
|
Avatar: false,
|
|
Header: false,
|
|
Cached: true,
|
|
},
|
|
"local_account_1_avatar": {
|
|
ID: "01F8MH58A357CV5K7R7TJMSH6S",
|
|
StatusID: "", // this attachment isn't connected to a status
|
|
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/avatar/original/01F8MH58A357CV5K7R7TJMSH6S.jpeg",
|
|
RemoteURL: "",
|
|
CreatedAt: time.Now().Add(-47 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-47 * time.Hour),
|
|
Type: gtsmodel.FileTypeImage,
|
|
FileMeta: gtsmodel.FileMeta{
|
|
Original: gtsmodel.Original{
|
|
Width: 1092,
|
|
Height: 1800,
|
|
Size: 1965600,
|
|
Aspect: 0.6066666666666667,
|
|
},
|
|
Small: gtsmodel.Small{
|
|
Width: 155,
|
|
Height: 256,
|
|
Size: 39680,
|
|
Aspect: 0.60546875,
|
|
},
|
|
Focus: gtsmodel.Focus{
|
|
X: 0,
|
|
Y: 0,
|
|
},
|
|
},
|
|
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
Description: "a green goblin looking nasty",
|
|
ScheduledStatusID: "",
|
|
Blurhash: "LKK9MT,p|YSNDkJ-5rsmvnwcOoe:",
|
|
Processing: 2,
|
|
File: gtsmodel.File{
|
|
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/avatar/original/01F8MH58A357CV5K7R7TJMSH6S.jpeg",
|
|
ContentType: "image/jpeg",
|
|
FileSize: 457680,
|
|
UpdatedAt: time.Now().Add(-47 * time.Hour),
|
|
},
|
|
Thumbnail: gtsmodel.Thumbnail{
|
|
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/avatar/small/01F8MH58A357CV5K7R7TJMSH6S.jpeg",
|
|
ContentType: "image/jpeg",
|
|
FileSize: 15374,
|
|
UpdatedAt: time.Now().Add(-47 * time.Hour),
|
|
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/avatar/small/01F8MH58A357CV5K7R7TJMSH6S.jpeg",
|
|
RemoteURL: "",
|
|
},
|
|
Avatar: true,
|
|
Header: false,
|
|
Cached: true,
|
|
},
|
|
"local_account_1_header": {
|
|
ID: "01PFPMWK2FF0D9WMHEJHR07C3Q",
|
|
StatusID: "",
|
|
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/header/original/01PFPMWK2FF0D9WMHEJHR07C3Q.jpeg",
|
|
RemoteURL: "",
|
|
CreatedAt: time.Now().Add(-47 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-47 * time.Hour),
|
|
Type: gtsmodel.FileTypeImage,
|
|
FileMeta: gtsmodel.FileMeta{
|
|
Original: gtsmodel.Original{
|
|
Width: 1018,
|
|
Height: 764,
|
|
Size: 777752,
|
|
Aspect: 1.3324607329842932,
|
|
},
|
|
Small: gtsmodel.Small{
|
|
Width: 256,
|
|
Height: 192,
|
|
Size: 49152,
|
|
Aspect: 1.3333333333333333,
|
|
},
|
|
Focus: gtsmodel.Focus{
|
|
X: 0,
|
|
Y: 0,
|
|
},
|
|
},
|
|
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
Description: "A very old-school screenshot of the original team fortress mod for quake ",
|
|
ScheduledStatusID: "",
|
|
Blurhash: "L26j{^WCs+R-N}jsxWj@4;WWxDoK",
|
|
Processing: 2,
|
|
File: gtsmodel.File{
|
|
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/header/original/01PFPMWK2FF0D9WMHEJHR07C3Q.jpeg",
|
|
ContentType: "image/jpeg",
|
|
FileSize: 517226,
|
|
UpdatedAt: time.Now().Add(-47 * time.Hour),
|
|
},
|
|
Thumbnail: gtsmodel.Thumbnail{
|
|
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/header/small/01PFPMWK2FF0D9WMHEJHR07C3Q.jpeg",
|
|
ContentType: "image/jpeg",
|
|
FileSize: 42308,
|
|
UpdatedAt: time.Now().Add(-47 * time.Hour),
|
|
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/header/small/01PFPMWK2FF0D9WMHEJHR07C3Q.jpeg",
|
|
RemoteURL: "",
|
|
},
|
|
Avatar: false,
|
|
Header: true,
|
|
Cached: true,
|
|
},
|
|
"remote_account_1_status_1_attachment_1": {
|
|
ID: "01FVW7RXPQ8YJHTEXYPE7Q8ZY0",
|
|
StatusID: "01FVW7JHQFSFK166WWKR8CBA6M",
|
|
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/original/01FVW7RXPQ8YJHTEXYPE7Q8ZY0.jpeg",
|
|
RemoteURL: "http://fossbros-anonymous.io/attachments/original/13bbc3f8-2b5e-46ea-9531-40b4974d9912.jpeg",
|
|
CreatedAt: TimeMustParse("2021-09-20T12:40:37+02:00"),
|
|
UpdatedAt: TimeMustParse("2021-09-20T12:40:37+02:00"),
|
|
Type: gtsmodel.FileTypeImage,
|
|
FileMeta: gtsmodel.FileMeta{
|
|
Original: gtsmodel.Original{
|
|
Width: 472,
|
|
Height: 291,
|
|
Size: 137352,
|
|
Aspect: 1.6219931271477663,
|
|
},
|
|
Small: gtsmodel.Small{
|
|
Width: 472,
|
|
Height: 291,
|
|
Size: 137352,
|
|
Aspect: 1.6219931271477663,
|
|
},
|
|
Focus: gtsmodel.Focus{
|
|
X: 0,
|
|
Y: 0,
|
|
},
|
|
},
|
|
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
Description: "tweet from thoughts of dog: i drank. all the water. in my bowl. earlier. but just now. i returned. to the same bowl. and it was. full again.. the bowl. is haunted",
|
|
ScheduledStatusID: "",
|
|
Blurhash: "LARysgM_IU_3~pD%M_Rj_39FIAt6",
|
|
Processing: 2,
|
|
File: gtsmodel.File{
|
|
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/original/01FVW7RXPQ8YJHTEXYPE7Q8ZY0.jpeg",
|
|
ContentType: "image/jpeg",
|
|
FileSize: 19310,
|
|
UpdatedAt: TimeMustParse("2021-09-20T12:40:37+02:00"),
|
|
},
|
|
Thumbnail: gtsmodel.Thumbnail{
|
|
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01FVW7RXPQ8YJHTEXYPE7Q8ZY0.jpeg",
|
|
ContentType: "image/jpeg",
|
|
FileSize: 20395,
|
|
UpdatedAt: TimeMustParse("2021-09-20T12:40:37+02:00"),
|
|
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01FVW7RXPQ8YJHTEXYPE7Q8ZY0.jpeg",
|
|
RemoteURL: "http://fossbros-anonymous.io/attachments/small/a499f55b-2d1e-4acd-98d2-1ac2ba6d79b9.jpeg",
|
|
},
|
|
Avatar: false,
|
|
Header: false,
|
|
Cached: true,
|
|
},
|
|
"remote_account_1_status_1_attachment_2": {
|
|
ID: "01FVW7RXPQ8YJHTEXYPE7Q8ZY1",
|
|
StatusID: "01FVW7JHQFSFK166WWKR8CBA6M",
|
|
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/original/01FVW7RXPQ8YJHTEXYPE7Q8ZY0.jpeg",
|
|
RemoteURL: "http://fossbros-anonymous.io/attachments/original/13bbc3f8-2b5e-46ea-9531-40b4974d9912.jpeg",
|
|
CreatedAt: time.Now().Add(-48 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-48 * time.Hour),
|
|
Type: gtsmodel.FileTypeImage,
|
|
FileMeta: gtsmodel.FileMeta{
|
|
Original: gtsmodel.Original{
|
|
Width: 472,
|
|
Height: 291,
|
|
Size: 137352,
|
|
Aspect: 1.6219931271477663,
|
|
},
|
|
Small: gtsmodel.Small{
|
|
Width: 472,
|
|
Height: 291,
|
|
Size: 137352,
|
|
Aspect: 1.6219931271477663,
|
|
},
|
|
Focus: gtsmodel.Focus{
|
|
X: 0,
|
|
Y: 0,
|
|
},
|
|
},
|
|
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
Description: "tweet from thoughts of dog: i drank. all the water. in my bowl. earlier. but just now. i returned. to the same bowl. and it was. full again.. the bowl. is haunted",
|
|
ScheduledStatusID: "",
|
|
Blurhash: "LARysgM_IU_3~pD%M_Rj_39FIAt6",
|
|
Processing: 2,
|
|
File: gtsmodel.File{
|
|
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/original/01FVW7RXPQ8YJHTEXYPE7Q8ZY0.jpeg",
|
|
ContentType: "image/jpeg",
|
|
FileSize: 19310,
|
|
UpdatedAt: time.Now().Add(-48 * time.Hour),
|
|
},
|
|
Thumbnail: gtsmodel.Thumbnail{
|
|
Path: "01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01FVW7RXPQ8YJHTEXYPE7Q8ZY0.jpeg",
|
|
ContentType: "image/jpeg",
|
|
FileSize: 20395,
|
|
UpdatedAt: time.Now().Add(-48 * time.Hour),
|
|
URL: "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/attachment/small/01FVW7RXPQ8YJHTEXYPE7Q8ZY0.jpeg",
|
|
RemoteURL: "http://fossbros-anonymous.io/attachments/small/a499f55b-2d1e-4acd-98d2-1ac2ba6d79b9.jpeg",
|
|
},
|
|
Avatar: false,
|
|
Header: false,
|
|
Cached: true,
|
|
},
|
|
}
|
|
}
|
|
|
|
// NewTestEmojis returns a map of gts emojis, keyed by the emoji shortcode
|
|
func NewTestEmojis() map[string]*gtsmodel.Emoji {
|
|
return map[string]*gtsmodel.Emoji{
|
|
"rainbow": {
|
|
ID: "01F8MH9H8E4VG3KDYJR9EGPXCQ",
|
|
Shortcode: "rainbow",
|
|
Domain: "",
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
ImageRemoteURL: "",
|
|
ImageStaticRemoteURL: "",
|
|
ImageURL: "http://localhost:8080/fileserver/01F8MH261H1KSV3GW3016GZRY3/emoji/original/01F8MH9H8E4VG3KDYJR9EGPXCQ.png",
|
|
ImagePath: "/tmp/gotosocial/01F8MH261H1KSV3GW3016GZRY3/emoji/original/01F8MH9H8E4VG3KDYJR9EGPXCQ.png",
|
|
ImageStaticURL: "http://localhost:8080/fileserver/01F8MH261H1KSV3GW3016GZRY3/emoji/static/01F8MH9H8E4VG3KDYJR9EGPXCQ.png",
|
|
ImageStaticPath: "/tmp/gotosocial/01F8MH261H1KSV3GW3016GZRY3/emoji/static/01F8MH9H8E4VG3KDYJR9EGPXCQ.png",
|
|
ImageContentType: "image/png",
|
|
ImageStaticContentType: "image/png",
|
|
ImageFileSize: 36702,
|
|
ImageStaticFileSize: 10413,
|
|
ImageUpdatedAt: time.Now(),
|
|
Disabled: false,
|
|
URI: "http://localhost:8080/emoji/01F8MH9H8E4VG3KDYJR9EGPXCQ",
|
|
VisibleInPicker: true,
|
|
CategoryID: "",
|
|
},
|
|
}
|
|
}
|
|
|
|
func NewTestDomainBlocks() map[string]*gtsmodel.DomainBlock {
|
|
return map[string]*gtsmodel.DomainBlock{
|
|
"replyguys.com": {
|
|
ID: "01FF22EQM7X8E3RX1XGPN7S87D",
|
|
Domain: "replyguys.com",
|
|
CreatedByAccountID: "01F8MH17FWEB39HZJ76B6VXSKF",
|
|
PrivateComment: "i blocked this domain because they keep replying with pushy + unwarranted linux advice",
|
|
PublicComment: "reply-guying to tech posts",
|
|
Obfuscate: false,
|
|
},
|
|
}
|
|
}
|
|
|
|
type filenames struct {
|
|
Original string
|
|
Small string
|
|
Static string
|
|
}
|
|
|
|
// newTestStoredAttachments returns a map of filenames, keyed according to which attachment they pertain to.
|
|
func newTestStoredAttachments() map[string]filenames {
|
|
return map[string]filenames{
|
|
"admin_account_status_1_attachment_1": {
|
|
Original: "welcome-original.jpeg",
|
|
Small: "welcome-small.jpeg",
|
|
},
|
|
"local_account_1_status_4_attachment_1": {
|
|
Original: "trent-original.gif",
|
|
Small: "trent-small.jpeg",
|
|
},
|
|
"local_account_1_unattached_1": {
|
|
Original: "ohyou-original.jpeg",
|
|
Small: "ohyou-small.jpeg",
|
|
},
|
|
"local_account_1_avatar": {
|
|
Original: "zork-original.jpeg",
|
|
Small: "zork-small.jpeg",
|
|
},
|
|
"local_account_1_header": {
|
|
Original: "team-fortress-original.jpeg",
|
|
Small: "team-fortress-small.jpeg",
|
|
},
|
|
"remote_account_1_status_1_attachment_1": {
|
|
Original: "thoughtsofdog-original.jpeg",
|
|
Small: "thoughtsofdog-small.jpeg",
|
|
},
|
|
}
|
|
}
|
|
|
|
// newTestStoredEmoji returns a map of filenames, keyed according to which emoji they pertain to
|
|
func newTestStoredEmoji() map[string]filenames {
|
|
return map[string]filenames{
|
|
"rainbow": {
|
|
Original: "rainbow-original.png",
|
|
Static: "rainbow-static.png",
|
|
},
|
|
}
|
|
}
|
|
|
|
// NewTestStatuses returns a map of statuses keyed according to which account
|
|
// and status they are.
|
|
func NewTestStatuses() map[string]*gtsmodel.Status {
|
|
return map[string]*gtsmodel.Status{
|
|
"admin_account_status_1": {
|
|
ID: "01F8MH75CBF9JFX4ZAD54N0W0R",
|
|
URI: "http://localhost:8080/users/admin/statuses/01F8MH75CBF9JFX4ZAD54N0W0R",
|
|
URL: "http://localhost:8080/@admin/statuses/01F8MH75CBF9JFX4ZAD54N0W0R",
|
|
Content: "hello world! #welcome ! first post on the instance :rainbow: !",
|
|
AttachmentIDs: []string{"01F8MH6NEM8D7527KZAECTCR76"},
|
|
TagIDs: []string{"01F8MHA1A2NF9MJ3WCCQ3K8BSZ"},
|
|
MentionIDs: []string{},
|
|
EmojiIDs: []string{"01F8MH9H8E4VG3KDYJR9EGPXCQ"},
|
|
CreatedAt: TimeMustParse("2021-10-20T11:36:45Z"),
|
|
UpdatedAt: TimeMustParse("2021-10-20T11:36:45Z"),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/admin",
|
|
AccountID: "01F8MH17FWEB39HZJ76B6VXSKF",
|
|
InReplyToID: "",
|
|
BoostOfID: "",
|
|
ContentWarning: "",
|
|
Visibility: gtsmodel.VisibilityPublic,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGXQRHYF5QPMTMXP78QC2F",
|
|
Federated: true,
|
|
Boostable: true,
|
|
Replyable: true,
|
|
Likeable: true,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"admin_account_status_2": {
|
|
ID: "01F8MHAAY43M6RJ473VQFCVH37",
|
|
URI: "http://localhost:8080/users/admin/statuses/01F8MHAAY43M6RJ473VQFCVH37",
|
|
URL: "http://localhost:8080/@admin/statuses/01F8MHAAY43M6RJ473VQFCVH37",
|
|
Content: "🐕🐕🐕🐕🐕",
|
|
CreatedAt: TimeMustParse("2021-10-20T12:36:45Z"),
|
|
UpdatedAt: TimeMustParse("2021-10-20T12:36:45Z"),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/admin",
|
|
AccountID: "01F8MH17FWEB39HZJ76B6VXSKF",
|
|
InReplyToID: "",
|
|
BoostOfID: "",
|
|
ContentWarning: "open to see some puppies",
|
|
Visibility: gtsmodel.VisibilityPublic,
|
|
Sensitive: true,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGXQRHYF5QPMTMXP78QC2F",
|
|
Federated: true,
|
|
Boostable: true,
|
|
Replyable: true,
|
|
Likeable: true,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"admin_account_status_3": {
|
|
ID: "01FF25D5Q0DH7CHD57CTRS6WK0",
|
|
URI: "http://localhost:8080/users/admin/statuses/01FF25D5Q0DH7CHD57CTRS6WK0",
|
|
URL: "http://localhost:8080/@admin/statuses/01FF25D5Q0DH7CHD57CTRS6WK0",
|
|
Content: "hi @the_mighty_zork welcome to the instance!",
|
|
CreatedAt: TimeMustParse("2021-11-20T13:32:16Z"),
|
|
UpdatedAt: TimeMustParse("2021-11-20T13:32:16Z"),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/admin",
|
|
MentionIDs: []string{"01FF26A6BGEKCZFWNEHXB2ZZ6M"},
|
|
AccountID: "01F8MH17FWEB39HZJ76B6VXSKF",
|
|
InReplyToID: "01F8MHAMCHF6Y650WCRSCP4WMY",
|
|
InReplyToAccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
InReplyToURI: "http://localhost:8080/users/the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY",
|
|
BoostOfID: "",
|
|
Visibility: gtsmodel.VisibilityPublic,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGXQRHYF5QPMTMXP78QC2F",
|
|
Federated: true,
|
|
Boostable: true,
|
|
Replyable: true,
|
|
Likeable: true,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"admin_account_status_4": {
|
|
ID: "01G36SF3V6Y6V5BF9P4R7PQG7G",
|
|
URI: "http://localhost:8080/users/admin/statuses/01G36SF3V6Y6V5BF9P4R7PQG7G",
|
|
URL: "http://localhost:8080/@admin/statuses/01G36SF3V6Y6V5BF9P4R7PQG7G",
|
|
Content: "hello everyone!",
|
|
CreatedAt: TimeMustParse("2021-10-20T12:41:37+02:00"),
|
|
UpdatedAt: TimeMustParse("2021-10-20T12:41:37+02:00"),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/admin",
|
|
AccountID: "01F8MH17FWEB39HZJ76B6VXSKF",
|
|
InReplyToID: "",
|
|
InReplyToAccountID: "",
|
|
InReplyToURI: "",
|
|
BoostOfID: "01F8MHAMCHF6Y650WCRSCP4WMY",
|
|
BoostOfAccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
ContentWarning: "introduction post",
|
|
Visibility: gtsmodel.VisibilityPublic,
|
|
Sensitive: true,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGXQRHYF5QPMTMXP78QC2F",
|
|
Federated: true,
|
|
Boostable: true,
|
|
Replyable: true,
|
|
Likeable: true,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"local_account_1_status_1": {
|
|
ID: "01F8MHAMCHF6Y650WCRSCP4WMY",
|
|
URI: "http://localhost:8080/users/the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY",
|
|
URL: "http://localhost:8080/@the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY",
|
|
Content: "hello everyone!",
|
|
CreatedAt: TimeMustParse("2021-10-20T12:40:37+02:00"),
|
|
UpdatedAt: TimeMustParse("2021-10-20T12:40:37+02:00"),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/the_mighty_zork",
|
|
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
InReplyToID: "",
|
|
BoostOfID: "",
|
|
ContentWarning: "introduction post",
|
|
Visibility: gtsmodel.VisibilityPublic,
|
|
Sensitive: true,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG",
|
|
Federated: true,
|
|
Boostable: true,
|
|
Replyable: true,
|
|
Likeable: true,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"local_account_1_status_2": {
|
|
ID: "01F8MHAYFKS4KMXF8K5Y1C0KRN",
|
|
URI: "http://localhost:8080/users/the_mighty_zork/statuses/01F8MHAYFKS4KMXF8K5Y1C0KRN",
|
|
URL: "http://localhost:8080/@the_mighty_zork/statuses/01F8MHAYFKS4KMXF8K5Y1C0KRN",
|
|
Content: "this is an unlocked local-only post that shouldn't federate, but it's still boostable, replyable, and likeable",
|
|
CreatedAt: time.Now().Add(-46 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-46 * time.Hour),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/the_mighty_zork",
|
|
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
InReplyToID: "",
|
|
BoostOfID: "",
|
|
ContentWarning: "",
|
|
Visibility: gtsmodel.VisibilityUnlocked,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG",
|
|
Federated: false,
|
|
Boostable: true,
|
|
Replyable: true,
|
|
Likeable: true,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"local_account_1_status_3": {
|
|
ID: "01F8MHBBN8120SYH7D5S050MGK",
|
|
URI: "http://localhost:8080/users/the_mighty_zork/statuses/01F8MHBBN8120SYH7D5S050MGK",
|
|
URL: "http://localhost:8080/@the_mighty_zork/statuses/01F8MHBBN8120SYH7D5S050MGK",
|
|
Content: "this is a very personal post that I don't want anyone to interact with at all, and i only want mutuals to see it",
|
|
CreatedAt: time.Now().Add(-45 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-45 * time.Hour),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/the_mighty_zork",
|
|
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
InReplyToID: "",
|
|
BoostOfID: "",
|
|
ContentWarning: "test: you shouldn't be able to interact with this post in any way",
|
|
Visibility: gtsmodel.VisibilityMutualsOnly,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG",
|
|
Federated: true,
|
|
Boostable: false,
|
|
Replyable: false,
|
|
Likeable: false,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"local_account_1_status_4": {
|
|
ID: "01F8MH82FYRXD2RC6108DAJ5HB",
|
|
URI: "http://localhost:8080/users/the_mighty_zork/statuses/01F8MH82FYRXD2RC6108DAJ5HB",
|
|
URL: "http://localhost:8080/@the_mighty_zork/statuses/01F8MH82FYRXD2RC6108DAJ5HB",
|
|
Content: "here's a little gif of trent",
|
|
AttachmentIDs: []string{"01F8MH7TDVANYKWVE8VVKFPJTJ"},
|
|
CreatedAt: time.Now().Add(-1 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-1 * time.Hour),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/the_mighty_zork",
|
|
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
InReplyToID: "",
|
|
BoostOfID: "",
|
|
ContentWarning: "eye contact, trent reznor gif",
|
|
Visibility: gtsmodel.VisibilityMutualsOnly,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG",
|
|
Federated: true,
|
|
Boostable: true,
|
|
Replyable: true,
|
|
Likeable: true,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"local_account_1_status_5": {
|
|
ID: "01FCTA44PW9H1TB328S9AQXKDS",
|
|
URI: "http://localhost:8080/users/the_mighty_zork/statuses/01FCTA44PW9H1TB328S9AQXKDS",
|
|
URL: "http://localhost:8080/@the_mighty_zork/statuses/01FCTA44PW9H1TB328S9AQXKDS",
|
|
Content: "hi!",
|
|
AttachmentIDs: []string{},
|
|
CreatedAt: TimeMustParse("2022-05-20T11:37:55Z"),
|
|
UpdatedAt: TimeMustParse("2022-05-20T11:37:55Z"),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/the_mighty_zork",
|
|
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
InReplyToID: "",
|
|
BoostOfID: "",
|
|
ContentWarning: "",
|
|
Visibility: gtsmodel.VisibilityFollowersOnly,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG",
|
|
Federated: true,
|
|
Boostable: true,
|
|
Replyable: true,
|
|
Likeable: true,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"local_account_2_status_1": {
|
|
ID: "01F8MHBQCBTDKN6X5VHGMMN4MA",
|
|
URI: "http://localhost:8080/users/1happyturtle/statuses/01F8MHBQCBTDKN6X5VHGMMN4MA",
|
|
URL: "http://localhost:8080/@1happyturtle/statuses/01F8MHBQCBTDKN6X5VHGMMN4MA",
|
|
Content: "🐢 hi everyone i post about turtles 🐢",
|
|
CreatedAt: time.Now().Add(-189 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-189 * time.Hour),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/1happyturtle",
|
|
AccountID: "01F8MH5NBDF2MV7CTC4Q5128HF",
|
|
InReplyToID: "",
|
|
BoostOfID: "",
|
|
ContentWarning: "introduction post",
|
|
Visibility: gtsmodel.VisibilityPublic,
|
|
Sensitive: true,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGYG9E893WRHW0TAEXR8GJ",
|
|
Federated: true,
|
|
Boostable: true,
|
|
Replyable: true,
|
|
Likeable: true,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"local_account_2_status_2": {
|
|
ID: "01F8MHC0H0A7XHTVH5F596ZKBM",
|
|
URI: "http://localhost:8080/users/1happyturtle/statuses/01F8MHC0H0A7XHTVH5F596ZKBM",
|
|
URL: "http://localhost:8080/@1happyturtle/statuses/01F8MHC0H0A7XHTVH5F596ZKBM",
|
|
Content: "🐢 this one is federated, likeable, and boostable but not replyable 🐢",
|
|
CreatedAt: time.Now().Add(-1 * time.Minute),
|
|
UpdatedAt: time.Now().Add(-1 * time.Minute),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/1happyturtle",
|
|
AccountID: "01F8MH5NBDF2MV7CTC4Q5128HF",
|
|
InReplyToID: "",
|
|
BoostOfID: "",
|
|
ContentWarning: "",
|
|
Visibility: gtsmodel.VisibilityPublic,
|
|
Sensitive: true,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGYG9E893WRHW0TAEXR8GJ",
|
|
Federated: true,
|
|
Boostable: true,
|
|
Replyable: false,
|
|
Likeable: true,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"local_account_2_status_3": {
|
|
ID: "01F8MHC8VWDRBQR0N1BATDDEM5",
|
|
URI: "http://localhost:8080/users/1happyturtle/statuses/01F8MHC8VWDRBQR0N1BATDDEM5",
|
|
URL: "http://localhost:8080/@1happyturtle/statuses/01F8MHC8VWDRBQR0N1BATDDEM5",
|
|
Content: "🐢 i don't mind people sharing this one but I don't want likes or replies to it because cba🐢",
|
|
CreatedAt: time.Now().Add(-2 * time.Minute),
|
|
UpdatedAt: time.Now().Add(-2 * time.Minute),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/1happyturtle",
|
|
AccountID: "01F8MH5NBDF2MV7CTC4Q5128HF",
|
|
InReplyToID: "",
|
|
BoostOfID: "",
|
|
ContentWarning: "you won't be able to like or reply to this",
|
|
Visibility: gtsmodel.VisibilityUnlocked,
|
|
Sensitive: true,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGYG9E893WRHW0TAEXR8GJ",
|
|
Federated: true,
|
|
Boostable: true,
|
|
Replyable: false,
|
|
Likeable: false,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"local_account_2_status_4": {
|
|
ID: "01F8MHCP5P2NWYQ416SBA0XSEV",
|
|
URI: "http://localhost:8080/users/1happyturtle/statuses/01F8MHCP5P2NWYQ416SBA0XSEV",
|
|
URL: "http://localhost:8080/@1happyturtle/statuses/01F8MHCP5P2NWYQ416SBA0XSEV",
|
|
Content: "🐢 this is a public status but I want it local only and not boostable 🐢",
|
|
CreatedAt: time.Now().Add(-1 * time.Minute),
|
|
UpdatedAt: time.Now().Add(-1 * time.Minute),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/1happyturtle",
|
|
AccountID: "01F8MH5NBDF2MV7CTC4Q5128HF",
|
|
InReplyToID: "",
|
|
BoostOfID: "",
|
|
ContentWarning: "",
|
|
Visibility: gtsmodel.VisibilityPublic,
|
|
Sensitive: true,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGYG9E893WRHW0TAEXR8GJ",
|
|
Federated: false,
|
|
Boostable: false,
|
|
Replyable: true,
|
|
Likeable: true,
|
|
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"local_account_2_status_5": {
|
|
ID: "01FCQSQ667XHJ9AV9T27SJJSX5",
|
|
URI: "http://localhost:8080/users/1happyturtle/statuses/01FCQSQ667XHJ9AV9T27SJJSX5",
|
|
URL: "http://localhost:8080/@1happyturtle/statuses/01FCQSQ667XHJ9AV9T27SJJSX5",
|
|
Content: "🐢 @the_mighty_zork hi zork! 🐢",
|
|
CreatedAt: time.Now().Add(-1 * time.Minute),
|
|
UpdatedAt: time.Now().Add(-1 * time.Minute),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/1happyturtle",
|
|
MentionIDs: []string{"01FDF2HM2NF6FSRZCDEDV451CN"},
|
|
AccountID: "01F8MH5NBDF2MV7CTC4Q5128HF",
|
|
InReplyToID: "01F8MHAMCHF6Y650WCRSCP4WMY",
|
|
InReplyToAccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
InReplyToURI: "http://localhost:8080/users/the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY",
|
|
BoostOfID: "",
|
|
ContentWarning: "",
|
|
Visibility: gtsmodel.VisibilityPublic,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGYG9E893WRHW0TAEXR8GJ",
|
|
Federated: true,
|
|
Boostable: true,
|
|
Replyable: true,
|
|
Likeable: true,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"local_account_2_status_6": {
|
|
ID: "01FN3VJGFH10KR7S2PB0GFJZYG",
|
|
URI: "http://localhost:8080/users/1happyturtle/statuses/01FN3VJGFH10KR7S2PB0GFJZYG",
|
|
URL: "http://localhost:8080/@1happyturtle/statuses/01FN3VJGFH10KR7S2PB0GFJZYG",
|
|
Content: "🐢 @the_mighty_zork hi zork, this is a direct message, shhhhhh! 🐢",
|
|
CreatedAt: time.Now().Add(-1 * time.Minute),
|
|
UpdatedAt: time.Now().Add(-1 * time.Minute),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/1happyturtle",
|
|
MentionIDs: []string{"01FDF2HM2NF6FSRZCDEDV451CN"},
|
|
AccountID: "01F8MH5NBDF2MV7CTC4Q5128HF",
|
|
InReplyToID: "",
|
|
InReplyToAccountID: "",
|
|
InReplyToURI: "",
|
|
BoostOfID: "",
|
|
ContentWarning: "",
|
|
Visibility: gtsmodel.VisibilityDirect,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGYG9E893WRHW0TAEXR8GJ",
|
|
Federated: true,
|
|
Boostable: true,
|
|
Replyable: true,
|
|
Likeable: true,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"local_account_2_status_7": {
|
|
ID: "01G20ZM733MGN8J344T4ZDDFY1",
|
|
URI: "http://localhost:8080/users/1happyturtle/statuses/01G20ZM733MGN8J344T4ZDDFY1",
|
|
URL: "http://localhost:8080/@1happyturtle/statuses/01G20ZM733MGN8J344T4ZDDFY1",
|
|
Content: "🐢 hi followers! did u know i'm a turtle? 🐢",
|
|
AttachmentIDs: []string{},
|
|
CreatedAt: time.Now().Add(-1 * time.Minute),
|
|
UpdatedAt: time.Now().Add(-1 * time.Minute),
|
|
Local: true,
|
|
AccountURI: "http://localhost:8080/users/1happyturtle",
|
|
AccountID: "01F8MH5NBDF2MV7CTC4Q5128HF",
|
|
InReplyToID: "",
|
|
BoostOfID: "",
|
|
ContentWarning: "",
|
|
Visibility: gtsmodel.VisibilityFollowersOnly,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "01F8MGYG9E893WRHW0TAEXR8GJ",
|
|
Federated: true,
|
|
Boostable: true,
|
|
Replyable: true,
|
|
Likeable: true,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
"remote_account_1_status_1": {
|
|
ID: "01FVW7JHQFSFK166WWKR8CBA6M",
|
|
URI: "http://fossbros-anonymous.io/users/foss_satan/statuses/01FVW7JHQFSFK166WWKR8CBA6M",
|
|
URL: "http://fossbros-anonymous.io/@foss_satan/statuses/01FVW7JHQFSFK166WWKR8CBA6M",
|
|
Content: "dark souls status bot: \"thoughts of dog\"",
|
|
AttachmentIDs: []string{"01FVW7RXPQ8YJHTEXYPE7Q8ZY0"},
|
|
CreatedAt: TimeMustParse("2021-09-20T12:40:37+02:00"),
|
|
UpdatedAt: TimeMustParse("2021-09-20T12:40:37+02:00"),
|
|
Local: false,
|
|
AccountURI: "http://fossbros-anonymous.io/users/foss_satan",
|
|
MentionIDs: []string{},
|
|
AccountID: "01F8MH5ZK5VRH73AKHQM6Y9VNX",
|
|
InReplyToID: "",
|
|
InReplyToAccountID: "",
|
|
InReplyToURI: "",
|
|
BoostOfID: "",
|
|
ContentWarning: "",
|
|
Visibility: gtsmodel.VisibilityUnlocked,
|
|
Sensitive: false,
|
|
Language: "en",
|
|
CreatedWithApplicationID: "",
|
|
Federated: true,
|
|
Boostable: true,
|
|
Replyable: true,
|
|
Likeable: true,
|
|
ActivityStreamsType: ap.ObjectNote,
|
|
},
|
|
}
|
|
}
|
|
|
|
// NewTestTags returns a map of gts model tags keyed by their name
|
|
func NewTestTags() map[string]*gtsmodel.Tag {
|
|
return map[string]*gtsmodel.Tag{
|
|
"welcome": {
|
|
ID: "01F8MHA1A2NF9MJ3WCCQ3K8BSZ",
|
|
URL: "http://localhost:8080/tags/welcome",
|
|
Name: "welcome",
|
|
FirstSeenFromAccountID: "",
|
|
CreatedAt: time.Now().Add(-71 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-71 * time.Hour),
|
|
Useable: true,
|
|
Listable: true,
|
|
LastStatusAt: time.Now().Add(-71 * time.Hour),
|
|
},
|
|
"Hashtag": {
|
|
ID: "01FCT9SGYA71487N8D0S1M638G",
|
|
URL: "http://localhost:8080/tags/Hashtag",
|
|
Name: "Hashtag",
|
|
FirstSeenFromAccountID: "",
|
|
CreatedAt: time.Now().Add(-71 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-71 * time.Hour),
|
|
Useable: true,
|
|
Listable: true,
|
|
LastStatusAt: time.Now().Add(-71 * time.Hour),
|
|
},
|
|
}
|
|
}
|
|
|
|
// NewTestMentions returns a map of gts model mentions keyed by their name.
|
|
func NewTestMentions() map[string]*gtsmodel.Mention {
|
|
return map[string]*gtsmodel.Mention{
|
|
"zork_mention_foss_satan": {
|
|
ID: "01FCTA2Y6FGHXQA4ZE6N5NMNEX",
|
|
StatusID: "01FCTA44PW9H1TB328S9AQXKDS",
|
|
CreatedAt: time.Now().Add(-1 * time.Minute),
|
|
UpdatedAt: time.Now().Add(-1 * time.Minute),
|
|
OriginAccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
OriginAccountURI: "http://localhost:8080/users/the_mighty_zork",
|
|
TargetAccountID: "01F8MH5ZK5VRH73AKHQM6Y9VNX",
|
|
NameString: "@foss_satan@fossbros-anonymous.io",
|
|
TargetAccountURI: "http://fossbros-anonymous.io/users/foss_satan",
|
|
TargetAccountURL: "http://fossbros-anonymous.io/@foss_satan",
|
|
},
|
|
"local_user_2_mention_zork": {
|
|
ID: "01FDF2HM2NF6FSRZCDEDV451CN",
|
|
StatusID: "01FCQSQ667XHJ9AV9T27SJJSX5",
|
|
CreatedAt: time.Now().Add(-1 * time.Minute),
|
|
UpdatedAt: time.Now().Add(-1 * time.Minute),
|
|
OriginAccountID: "01F8MH5NBDF2MV7CTC4Q5128HF",
|
|
OriginAccountURI: "http://localhost:8080/users/1happyturtle",
|
|
TargetAccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
NameString: "@the_mighty_zork",
|
|
TargetAccountURI: "http://localhost:8080/users/the_mighty_zork",
|
|
TargetAccountURL: "http://localhost:8080/@the_mighty_zork",
|
|
},
|
|
"local_user_2_mention_zork_direct_message": {
|
|
ID: "01FN3VKDEF4CN2W9TKX339BEHB",
|
|
StatusID: "01FN3VJGFH10KR7S2PB0GFJZYG",
|
|
CreatedAt: time.Now().Add(-1 * time.Minute),
|
|
UpdatedAt: time.Now().Add(-1 * time.Minute),
|
|
OriginAccountID: "01F8MH5NBDF2MV7CTC4Q5128HF",
|
|
OriginAccountURI: "http://localhost:8080/users/1happyturtle",
|
|
TargetAccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
NameString: "@the_mighty_zork",
|
|
TargetAccountURI: "http://localhost:8080/users/the_mighty_zork",
|
|
TargetAccountURL: "http://localhost:8080/@the_mighty_zork",
|
|
},
|
|
"admin_account_mention_zork": {
|
|
ID: "01FF26A6BGEKCZFWNEHXB2ZZ6M",
|
|
StatusID: "01FF25D5Q0DH7CHD57CTRS6WK0",
|
|
CreatedAt: time.Now().Add(-46 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-46 * time.Hour),
|
|
OriginAccountID: "01F8MH17FWEB39HZJ76B6VXSKF",
|
|
OriginAccountURI: "http://localhost:8080/users/admin",
|
|
TargetAccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
NameString: "@the_mighty_zork",
|
|
TargetAccountURI: "http://localhost:8080/users/the_mighty_zork",
|
|
TargetAccountURL: "http://localhost:8080/@the_mighty_zork",
|
|
},
|
|
}
|
|
}
|
|
|
|
// NewTestFaves returns a map of gts model faves, keyed in the format [faving_account]_[target_status]
|
|
func NewTestFaves() map[string]*gtsmodel.StatusFave {
|
|
return map[string]*gtsmodel.StatusFave{
|
|
"local_account_1_admin_account_status_1": {
|
|
ID: "01F8MHD2QCZSZ6WQS2ATVPEYJ9",
|
|
CreatedAt: time.Now().Add(-47 * time.Hour),
|
|
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF", // local account 1
|
|
TargetAccountID: "01F8MH17FWEB39HZJ76B6VXSKF", // admin account
|
|
StatusID: "01F8MH75CBF9JFX4ZAD54N0W0R", // admin account status 1
|
|
URI: "http://localhost:8080/users/the_mighty_zork/liked/01F8MHD2QCZSZ6WQS2ATVPEYJ9",
|
|
},
|
|
"admin_account_local_account_1_status_1": {
|
|
ID: "01F8Q0486ANTDWKG02A7DS1Q24",
|
|
CreatedAt: time.Now().Add(-46 * time.Hour),
|
|
AccountID: "01F8MH17FWEB39HZJ76B6VXSKF", // admin account
|
|
TargetAccountID: "01F8MH1H7YV1Z7D2C8K2730QBF", // local account 1
|
|
StatusID: "01F8MHAMCHF6Y650WCRSCP4WMY", // local account status 1
|
|
URI: "http://localhost:8080/users/admin/liked/01F8Q0486ANTDWKG02A7DS1Q24",
|
|
},
|
|
}
|
|
}
|
|
|
|
// NewTestNotifications returns some notifications for use in testing.
|
|
func NewTestNotifications() map[string]*gtsmodel.Notification {
|
|
return map[string]*gtsmodel.Notification{
|
|
"local_account_1_like": {
|
|
ID: "01F8Q0ANPTWW10DAKTX7BRPBJP",
|
|
NotificationType: gtsmodel.NotificationFave,
|
|
CreatedAt: time.Now().Add(-46 * time.Hour),
|
|
TargetAccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
OriginAccountID: "01F8MH17FWEB39HZJ76B6VXSKF",
|
|
StatusID: "01F8MHAMCHF6Y650WCRSCP4WMY",
|
|
Read: false,
|
|
},
|
|
}
|
|
}
|
|
|
|
// NewTestFollows returns some follows for use in testing.
|
|
func NewTestFollows() map[string]*gtsmodel.Follow {
|
|
return map[string]*gtsmodel.Follow{
|
|
"local_account_1_admin_account": {
|
|
ID: "01F8PY8RHWRQZV038T4E8T9YK8",
|
|
CreatedAt: time.Now().Add(-46 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-46 * time.Hour),
|
|
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
TargetAccountID: "01F8MH17FWEB39HZJ76B6VXSKF",
|
|
ShowReblogs: true,
|
|
URI: "http://localhost:8080/users/the_mighty_zork/follow/01F8PY8RHWRQZV038T4E8T9YK8",
|
|
Notify: false,
|
|
},
|
|
"local_account_1_local_account_2": {
|
|
ID: "01F8PYDCE8XE23GRE5DPZJDZDP",
|
|
CreatedAt: time.Now().Add(-1 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-1 * time.Hour),
|
|
AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
TargetAccountID: "01F8MH5NBDF2MV7CTC4Q5128HF",
|
|
ShowReblogs: true,
|
|
URI: "http://localhost:8080/users/the_mighty_zork/follow/01F8PYDCE8XE23GRE5DPZJDZDP",
|
|
Notify: false,
|
|
},
|
|
"local_account_2_local_account_1": {
|
|
ID: "01G1TK1RS4K3E0MSFTXBFWAH9Q",
|
|
CreatedAt: time.Now().Add(-1 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-1 * time.Hour),
|
|
AccountID: "01F8MH5NBDF2MV7CTC4Q5128HF",
|
|
TargetAccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
ShowReblogs: true,
|
|
URI: "http://localhost:8080/users/1happyturtle/follow/01F8PYDCE8XE23GRE5DPZJDZDP",
|
|
Notify: false,
|
|
},
|
|
"admin_account_local_account_1": {
|
|
ID: "01G1TK3PQKFW1BQZ9WVYRTFECK",
|
|
CreatedAt: time.Now().Add(-46 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-46 * time.Hour),
|
|
AccountID: "01F8MH17FWEB39HZJ76B6VXSKF",
|
|
TargetAccountID: "01F8MH1H7YV1Z7D2C8K2730QBF",
|
|
ShowReblogs: true,
|
|
URI: "http://localhost:8080/users/admin/follow/01G1TK3PQKFW1BQZ9WVYRTFECK",
|
|
Notify: false,
|
|
},
|
|
}
|
|
}
|
|
|
|
func NewTestBlocks() map[string]*gtsmodel.Block {
|
|
return map[string]*gtsmodel.Block{
|
|
"local_account_2_block_remote_account_1": {
|
|
ID: "01FEXXET6XXMF7G2V3ASZP3YQW",
|
|
CreatedAt: time.Now().Add(-1 * time.Hour),
|
|
UpdatedAt: time.Now().Add(-1 * time.Hour),
|
|
URI: "http://localhost:8080/users/1happyturtle/blocks/01FEXXET6XXMF7G2V3ASZP3YQW",
|
|
AccountID: "01F8MH5NBDF2MV7CTC4Q5128HF",
|
|
TargetAccountID: "01F8MH5ZK5VRH73AKHQM6Y9VNX",
|
|
},
|
|
}
|
|
}
|
|
|
|
// ActivityWithSignature wraps a pub.Activity along with its signature headers, for testing.
|
|
type ActivityWithSignature struct {
|
|
Activity pub.Activity
|
|
SignatureHeader string
|
|
DigestHeader string
|
|
DateHeader string
|
|
}
|
|
|
|
// NewTestActivities returns a bunch of pub.Activity types for use in testing the federation protocols.
|
|
// A struct of accounts needs to be passed in because the activities will also be bundled along with
|
|
// their requesting signatures.
|
|
func NewTestActivities(accounts map[string]*gtsmodel.Account) map[string]ActivityWithSignature {
|
|
dmForZork := NewAPNote(
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan/statuses/5424b153-4553-4f30-9358-7b92f7cd42f6"),
|
|
URLMustParse("http://fossbros-anonymous.io/@foss_satan/5424b153-4553-4f30-9358-7b92f7cd42f6"),
|
|
time.Now(),
|
|
"hey zork here's a new private note for you",
|
|
"new note for zork",
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan"),
|
|
[]*url.URL{URLMustParse("http://localhost:8080/users/the_mighty_zork")},
|
|
nil,
|
|
true,
|
|
[]vocab.ActivityStreamsMention{},
|
|
nil,
|
|
)
|
|
createDmForZork := WrapAPNoteInCreate(
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan/statuses/5424b153-4553-4f30-9358-7b92f7cd42f6/activity"),
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan"),
|
|
time.Now(),
|
|
dmForZork)
|
|
createDmForZorkSig, createDmForZorkDigest, creatDmForZorkDate := GetSignatureForActivity(createDmForZork, accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, URLMustParse(accounts["local_account_1"].InboxURI))
|
|
|
|
replyToTurtle := NewAPNote(
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan/statuses/2f1195a6-5cb0-4475-adf5-92ab9a0147fe"),
|
|
URLMustParse("http://fossbros-anonymous.io/@foss_satan/2f1195a6-5cb0-4475-adf5-92ab9a0147fe"),
|
|
time.Now(),
|
|
"@1happyturtle@localhost:8080 u suck lol",
|
|
"",
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan"),
|
|
[]*url.URL{URLMustParse("http://fossbros-anonymous.io/users/foss_satan/followers")},
|
|
[]*url.URL{URLMustParse("http://localhost:8080/users/1happyturtle")},
|
|
false,
|
|
[]vocab.ActivityStreamsMention{newAPMention(
|
|
URLMustParse("http://localhost:8080/users/1happyturtle"),
|
|
"@1happyturtle@localhost:8080",
|
|
)},
|
|
nil,
|
|
)
|
|
createReplyToTurtle := WrapAPNoteInCreate(
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan/statuses/2f1195a6-5cb0-4475-adf5-92ab9a0147fe"),
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan"),
|
|
time.Now(),
|
|
replyToTurtle)
|
|
createReplyToTurtleForZorkSig, createReplyToTurtleForZorkDigest, createReplyToTurtleForZorkDate := GetSignatureForActivity(createReplyToTurtle, accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, URLMustParse(accounts["local_account_1"].InboxURI))
|
|
createReplyToTurtleForTurtleSig, createReplyToTurtleForTurtleDigest, createReplyToTurtleForTurtleDate := GetSignatureForActivity(createReplyToTurtle, accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, URLMustParse(accounts["local_account_2"].InboxURI))
|
|
|
|
forwardedMessage := NewAPNote(
|
|
URLMustParse("http://example.org/users/some_user/statuses/afaba698-5740-4e32-a702-af61aa543bc1"),
|
|
URLMustParse("http://example.org/@some_user/afaba698-5740-4e32-a702-af61aa543bc1"),
|
|
time.Now(),
|
|
"this is a public status, please forward it!",
|
|
"",
|
|
URLMustParse("http://example.org/users/some_user"),
|
|
[]*url.URL{URLMustParse(pub.PublicActivityPubIRI)},
|
|
nil,
|
|
false,
|
|
[]vocab.ActivityStreamsMention{},
|
|
[]vocab.ActivityStreamsImage{
|
|
newAPImage(
|
|
URLMustParse("http://example.org/users/some_user/statuses/afaba698-5740-4e32-a702-af61aa543bc1/attachment1.jpeg"),
|
|
"image/jpeg",
|
|
"trent reznor looking handsome as balls",
|
|
"LEDara58O=t5EMSOENEN9]}?aK%0"),
|
|
},
|
|
)
|
|
createForwardedMessage := WrapAPNoteInCreate(
|
|
URLMustParse("http://example.org/users/some_user/statuses/afaba698-5740-4e32-a702-af61aa543bc1/activity"),
|
|
URLMustParse("http://example.org/users/some_user"),
|
|
time.Now(),
|
|
forwardedMessage)
|
|
createForwardedMessageSig, createForwardedMessageDigest, createForwardedMessageDate := GetSignatureForActivity(createForwardedMessage, accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, URLMustParse(accounts["local_account_1"].InboxURI))
|
|
|
|
announceForwarded1Zork := newAPAnnounce(
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan/first_announce"),
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan"),
|
|
time.Now(),
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan/followers"),
|
|
forwardedMessage,
|
|
)
|
|
announceForwarded1ZorkSig, announceForwarded1ZorkDigest, announceForwarded1ZorkDate := GetSignatureForActivity(announceForwarded1Zork, accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, URLMustParse(accounts["local_account_1"].InboxURI))
|
|
|
|
announceForwarded1Turtle := newAPAnnounce(
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan/first_announce"),
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan"),
|
|
time.Now(),
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan/followers"),
|
|
forwardedMessage,
|
|
)
|
|
announceForwarded1TurtleSig, announceForwarded1TurtleDigest, announceForwarded1TurtleDate := GetSignatureForActivity(announceForwarded1Turtle, accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, URLMustParse(accounts["local_account_2"].InboxURI))
|
|
|
|
announceForwarded2Zork := newAPAnnounce(
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan/second_announce"),
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan"),
|
|
time.Now(),
|
|
URLMustParse("http://fossbros-anonymous.io/users/foss_satan/followers"),
|
|
forwardedMessage,
|
|
)
|
|
announceForwarded2ZorkSig, announceForwarded2ZorkDigest, announceForwarded2ZorkDate := GetSignatureForActivity(announceForwarded2Zork, accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, URLMustParse(accounts["local_account_1"].InboxURI))
|
|
|
|
return map[string]ActivityWithSignature{
|
|
"dm_for_zork": {
|
|
Activity: createDmForZork,
|
|
SignatureHeader: createDmForZorkSig,
|
|
DigestHeader: createDmForZorkDigest,
|
|
DateHeader: creatDmForZorkDate,
|
|
},
|
|
"reply_to_turtle_for_zork": {
|
|
Activity: createReplyToTurtle,
|
|
SignatureHeader: createReplyToTurtleForZorkSig,
|
|
DigestHeader: createReplyToTurtleForZorkDigest,
|
|
DateHeader: createReplyToTurtleForZorkDate,
|
|
},
|
|
"reply_to_turtle_for_turtle": {
|
|
Activity: createReplyToTurtle,
|
|
SignatureHeader: createReplyToTurtleForTurtleSig,
|
|
DigestHeader: createReplyToTurtleForTurtleDigest,
|
|
DateHeader: createReplyToTurtleForTurtleDate,
|
|
},
|
|
"forwarded_message": {
|
|
Activity: createForwardedMessage,
|
|
SignatureHeader: createForwardedMessageSig,
|
|
DigestHeader: createForwardedMessageDigest,
|
|
DateHeader: createForwardedMessageDate,
|
|
},
|
|
"announce_forwarded_1_zork": {
|
|
Activity: announceForwarded1Zork,
|
|
SignatureHeader: announceForwarded1ZorkSig,
|
|
DigestHeader: announceForwarded1ZorkDigest,
|
|
DateHeader: announceForwarded1ZorkDate,
|
|
},
|
|
"announce_forwarded_1_turtle": {
|
|
Activity: announceForwarded1Turtle,
|
|
SignatureHeader: announceForwarded1TurtleSig,
|
|
DigestHeader: announceForwarded1TurtleDigest,
|
|
DateHeader: announceForwarded1TurtleDate,
|
|
},
|
|
"announce_forwarded_2_zork": {
|
|
Activity: announceForwarded2Zork,
|
|
SignatureHeader: announceForwarded2ZorkSig,
|
|
DigestHeader: announceForwarded2ZorkDigest,
|
|
DateHeader: announceForwarded2ZorkDate,
|
|
},
|
|
}
|
|
}
|
|
|
|
// NewTestFediPeople returns a bunch of activity pub Person representations for testing converters and so on.
|
|
func NewTestFediPeople() map[string]vocab.ActivityStreamsPerson {
|
|
newPerson1Priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
newPerson1Pub := &newPerson1Priv.PublicKey
|
|
|
|
turnipLover6969Priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
turnipLover6969Pub := &turnipLover6969Priv.PublicKey
|
|
|
|
return map[string]vocab.ActivityStreamsPerson{
|
|
"https://unknown-instance.com/users/brand_new_person": newAPPerson(
|
|
URLMustParse("https://unknown-instance.com/users/brand_new_person"),
|
|
URLMustParse("https://unknown-instance.com/users/brand_new_person/following"),
|
|
URLMustParse("https://unknown-instance.com/users/brand_new_person/followers"),
|
|
URLMustParse("https://unknown-instance.com/users/brand_new_person/inbox"),
|
|
URLMustParse("https://unknown-instance.com/users/brand_new_person/outbox"),
|
|
URLMustParse("https://unknown-instance.com/users/brand_new_person/collections/featured"),
|
|
"brand_new_person",
|
|
"Geoff Brando New Personson",
|
|
"hey I'm a new person, your instance hasn't seen me yet uwu",
|
|
URLMustParse("https://unknown-instance.com/@brand_new_person"),
|
|
true,
|
|
URLMustParse("https://unknown-instance.com/users/brand_new_person#main-key"),
|
|
newPerson1Pub,
|
|
nil,
|
|
"image/jpeg",
|
|
nil,
|
|
"image/png",
|
|
false,
|
|
),
|
|
"https://turnip.farm/users/turniplover6969": newAPPerson(
|
|
URLMustParse("https://turnip.farm/users/turniplover6969"),
|
|
URLMustParse("https://turnip.farm/users/turniplover6969/following"),
|
|
URLMustParse("https://turnip.farm/users/turniplover6969/followers"),
|
|
URLMustParse("https://turnip.farm/users/turniplover6969/inbox"),
|
|
URLMustParse("https://turnip.farm/users/turniplover6969/outbox"),
|
|
URLMustParse("https://turnip.farm/users/turniplover6969/collections/featured"),
|
|
"turniplover6969",
|
|
"Turnip Lover 6969",
|
|
"I just think they're neat",
|
|
URLMustParse("https://turnip.farm/@turniplover6969"),
|
|
true,
|
|
URLMustParse("https://turnip.farm/users/turniplover6969#main-key"),
|
|
turnipLover6969Pub,
|
|
nil,
|
|
"image/jpeg",
|
|
nil,
|
|
"image/png",
|
|
false,
|
|
),
|
|
}
|
|
}
|
|
|
|
func NewTestFediGroups() map[string]vocab.ActivityStreamsGroup {
|
|
newGroup1Priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
newGroup1Pub := &newGroup1Priv.PublicKey
|
|
|
|
return map[string]vocab.ActivityStreamsGroup{
|
|
"https://unknown-instance.com/groups/some_group": newAPGroup(
|
|
URLMustParse("https://unknown-instance.com/groups/some_group"),
|
|
URLMustParse("https://unknown-instance.com/groups/some_group/following"),
|
|
URLMustParse("https://unknown-instance.com/groups/some_group/followers"),
|
|
URLMustParse("https://unknown-instance.com/groups/some_group/inbox"),
|
|
URLMustParse("https://unknown-instance.com/groups/some_group/outbox"),
|
|
URLMustParse("https://unknown-instance.com/groups/some_group/collections/featured"),
|
|
"some_group",
|
|
"This is a group about... something?",
|
|
"",
|
|
URLMustParse("https://unknown-instance.com/@some_group"),
|
|
true,
|
|
URLMustParse("https://unknown-instance.com/groups/some_group#main-key"),
|
|
newGroup1Pub,
|
|
nil,
|
|
"image/jpeg",
|
|
nil,
|
|
"image/png",
|
|
false,
|
|
),
|
|
}
|
|
}
|
|
|
|
func NewTestFediServices() map[string]vocab.ActivityStreamsService {
|
|
newService1Priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
newService1Pub := &newService1Priv.PublicKey
|
|
|
|
return map[string]vocab.ActivityStreamsService{
|
|
"https://owncast.example.org/federation/user/rgh": newAPService(
|
|
URLMustParse("https://owncast.example.org/federation/user/rgh"),
|
|
nil,
|
|
URLMustParse("https://owncast.example.org/federation/user/rgh/followers"),
|
|
URLMustParse("https://owncast.example.org/federation/user/rgh/inbox"),
|
|
URLMustParse("https://owncast.example.org/federation/user/rgh/outbox"),
|
|
nil,
|
|
"rgh",
|
|
"linux audio stuff ",
|
|
"",
|
|
URLMustParse("https://owncast.example.org/federation/user/rgh"),
|
|
true,
|
|
URLMustParse("https://owncast.example.org/federation/user/rgh#main-key"),
|
|
newService1Pub,
|
|
nil,
|
|
"image/jpeg",
|
|
nil,
|
|
"image/png",
|
|
false,
|
|
),
|
|
}
|
|
}
|
|
|
|
// RemoteAttachmentFile mimics a remote (federated) attachment
|
|
type RemoteAttachmentFile struct {
|
|
Data []byte
|
|
ContentType string
|
|
}
|
|
|
|
func NewTestFediAttachments(relativePath string) map[string]RemoteAttachmentFile {
|
|
beeBytes, err := os.ReadFile(fmt.Sprintf("%s/beeplushie.jpg", relativePath))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
thoughtsOfDogBytes, err := os.ReadFile(fmt.Sprintf("%s/thoughtsofdog-original.jpeg", relativePath))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
massiveFuckingTurnipBytes, err := os.ReadFile(fmt.Sprintf("%s/giant-turnip-world-record.jpg", relativePath))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return map[string]RemoteAttachmentFile{
|
|
"https://s3-us-west-2.amazonaws.com/plushcity/media_attachments/files/106/867/380/219/163/828/original/88e8758c5f011439.jpg": {
|
|
Data: beeBytes,
|
|
ContentType: "image/jpeg",
|
|
},
|
|
"http://fossbros-anonymous.io/attachments/original/13bbc3f8-2b5e-46ea-9531-40b4974d9912.jpeg": {
|
|
Data: thoughtsOfDogBytes,
|
|
ContentType: "image/jpeg",
|
|
},
|
|
"https://turnip.farm/attachments/f17843c7-015e-4251-9b5a-91389c49ee57.jpg": {
|
|
Data: massiveFuckingTurnipBytes,
|
|
ContentType: "image/jpeg",
|
|
},
|
|
}
|
|
}
|
|
|
|
func NewTestFediStatuses() map[string]vocab.ActivityStreamsNote {
|
|
return map[string]vocab.ActivityStreamsNote{
|
|
"http://example.org/users/some_user/statuses/afaba698-5740-4e32-a702-af61aa543bc1": NewAPNote(
|
|
URLMustParse("http://example.org/users/some_user/statuses/afaba698-5740-4e32-a702-af61aa543bc1"),
|
|
URLMustParse("http://example.org/@some_user/afaba698-5740-4e32-a702-af61aa543bc1"),
|
|
time.Now(),
|
|
"this is a public status, please forward it!",
|
|
"",
|
|
URLMustParse("http://example.org/users/some_user"),
|
|
[]*url.URL{URLMustParse(pub.PublicActivityPubIRI)},
|
|
nil,
|
|
false,
|
|
[]vocab.ActivityStreamsMention{},
|
|
[]vocab.ActivityStreamsImage{
|
|
newAPImage(
|
|
URLMustParse("http://example.org/users/some_user/statuses/afaba698-5740-4e32-a702-af61aa543bc1/attachment1.jpeg"),
|
|
"image/jpeg",
|
|
"trent reznor looking handsome as balls",
|
|
"LEDara58O=t5EMSOENEN9]}?aK%0"),
|
|
},
|
|
),
|
|
"https://unknown-instance.com/users/brand_new_person/statuses/01FE4NTHKWW7THT67EF10EB839": NewAPNote(
|
|
URLMustParse("https://unknown-instance.com/users/brand_new_person/statuses/01FE4NTHKWW7THT67EF10EB839"),
|
|
URLMustParse("https://unknown-instance.com/users/@brand_new_person/01FE4NTHKWW7THT67EF10EB839"),
|
|
time.Now(),
|
|
"Hello world!",
|
|
"",
|
|
URLMustParse("https://unknown-instance.com/users/brand_new_person"),
|
|
[]*url.URL{
|
|
URLMustParse(pub.PublicActivityPubIRI),
|
|
},
|
|
[]*url.URL{},
|
|
false,
|
|
nil,
|
|
nil,
|
|
),
|
|
"https://unknown-instance.com/users/brand_new_person/statuses/01FE5Y30E3W4P7TRE0R98KAYQV": NewAPNote(
|
|
URLMustParse("https://unknown-instance.com/users/brand_new_person/statuses/01FE5Y30E3W4P7TRE0R98KAYQV"),
|
|
URLMustParse("https://unknown-instance.com/users/@brand_new_person/01FE5Y30E3W4P7TRE0R98KAYQV"),
|
|
time.Now(),
|
|
"Hey @the_mighty_zork@localhost:8080 how's it going?",
|
|
"",
|
|
URLMustParse("https://unknown-instance.com/users/brand_new_person"),
|
|
[]*url.URL{
|
|
URLMustParse(pub.PublicActivityPubIRI),
|
|
},
|
|
[]*url.URL{},
|
|
false,
|
|
[]vocab.ActivityStreamsMention{
|
|
newAPMention(
|
|
URLMustParse("http://localhost:8080/users/the_mighty_zork"),
|
|
"@the_mighty_zork@localhost:8080",
|
|
),
|
|
},
|
|
nil,
|
|
),
|
|
"https://turnip.farm/users/turniplover6969/statuses/70c53e54-3146-42d5-a630-83c8b6c7c042": NewAPNote(
|
|
URLMustParse("https://turnip.farm/users/turniplover6969/statuses/70c53e54-3146-42d5-a630-83c8b6c7c042"),
|
|
URLMustParse("https://turnip.farm/@turniplover6969/70c53e54-3146-42d5-a630-83c8b6c7c042"),
|
|
time.Now(),
|
|
"",
|
|
"",
|
|
URLMustParse("https://turnip.farm/users/turniplover6969"),
|
|
[]*url.URL{
|
|
URLMustParse(pub.PublicActivityPubIRI),
|
|
},
|
|
[]*url.URL{},
|
|
false,
|
|
nil,
|
|
[]vocab.ActivityStreamsImage{
|
|
newAPImage(
|
|
URLMustParse("https://turnip.farm/attachments/f17843c7-015e-4251-9b5a-91389c49ee57.jpg"),
|
|
"image/jpeg",
|
|
"",
|
|
"",
|
|
),
|
|
},
|
|
),
|
|
}
|
|
}
|
|
|
|
// NewTestDereferenceRequests returns a map of incoming dereference requests, with their signatures.
|
|
func NewTestDereferenceRequests(accounts map[string]*gtsmodel.Account) map[string]ActivityWithSignature {
|
|
var sig, digest, date string
|
|
var target *url.URL
|
|
statuses := NewTestStatuses()
|
|
|
|
target = URLMustParse(accounts["local_account_1"].URI)
|
|
sig, digest, date = GetSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target)
|
|
fossSatanDereferenceZork := ActivityWithSignature{
|
|
SignatureHeader: sig,
|
|
DigestHeader: digest,
|
|
DateHeader: date,
|
|
}
|
|
|
|
target = URLMustParse(accounts["local_account_1"].PublicKeyURI)
|
|
sig, digest, date = GetSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target)
|
|
fossSatanDereferenceZorkPublicKey := ActivityWithSignature{
|
|
SignatureHeader: sig,
|
|
DigestHeader: digest,
|
|
DateHeader: date,
|
|
}
|
|
|
|
target = URLMustParse(statuses["local_account_1_status_1"].URI)
|
|
sig, digest, date = GetSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target)
|
|
fossSatanDereferenceLocalAccount1Status1 := ActivityWithSignature{
|
|
SignatureHeader: sig,
|
|
DigestHeader: digest,
|
|
DateHeader: date,
|
|
}
|
|
|
|
target = URLMustParse(strings.ToLower(statuses["local_account_1_status_1"].URI))
|
|
sig, digest, date = GetSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target)
|
|
fossSatanDereferenceLocalAccount1Status1Lowercase := ActivityWithSignature{
|
|
SignatureHeader: sig,
|
|
DigestHeader: digest,
|
|
DateHeader: date,
|
|
}
|
|
|
|
target = URLMustParse(statuses["local_account_1_status_1"].URI + "/replies")
|
|
sig, digest, date = GetSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target)
|
|
fossSatanDereferenceLocalAccount1Status1Replies := ActivityWithSignature{
|
|
SignatureHeader: sig,
|
|
DigestHeader: digest,
|
|
DateHeader: date,
|
|
}
|
|
|
|
target = URLMustParse(statuses["local_account_1_status_1"].URI + "/replies?only_other_accounts=false&page=true")
|
|
sig, digest, date = GetSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target)
|
|
fossSatanDereferenceLocalAccount1Status1RepliesNext := ActivityWithSignature{
|
|
SignatureHeader: sig,
|
|
DigestHeader: digest,
|
|
DateHeader: date,
|
|
}
|
|
|
|
target = URLMustParse(statuses["local_account_1_status_1"].URI + "/replies?only_other_accounts=false&page=true&min_id=01FF25D5Q0DH7CHD57CTRS6WK0")
|
|
sig, digest, date = GetSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target)
|
|
fossSatanDereferenceLocalAccount1Status1RepliesLast := ActivityWithSignature{
|
|
SignatureHeader: sig,
|
|
DigestHeader: digest,
|
|
DateHeader: date,
|
|
}
|
|
|
|
target = URLMustParse(accounts["local_account_1"].OutboxURI)
|
|
sig, digest, date = GetSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target)
|
|
fossSatanDereferenceZorkOutbox := ActivityWithSignature{
|
|
SignatureHeader: sig,
|
|
DigestHeader: digest,
|
|
DateHeader: date,
|
|
}
|
|
|
|
target = URLMustParse(accounts["local_account_1"].OutboxURI + "?page=true")
|
|
sig, digest, date = GetSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target)
|
|
fossSatanDereferenceZorkOutboxFirst := ActivityWithSignature{
|
|
SignatureHeader: sig,
|
|
DigestHeader: digest,
|
|
DateHeader: date,
|
|
}
|
|
|
|
target = URLMustParse(accounts["local_account_1"].OutboxURI + "?page=true&max_id=01F8MHAMCHF6Y650WCRSCP4WMY")
|
|
sig, digest, date = GetSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target)
|
|
fossSatanDereferenceZorkOutboxNext := ActivityWithSignature{
|
|
SignatureHeader: sig,
|
|
DigestHeader: digest,
|
|
DateHeader: date,
|
|
}
|
|
|
|
return map[string]ActivityWithSignature{
|
|
"foss_satan_dereference_zork": fossSatanDereferenceZork,
|
|
"foss_satan_dereference_zork_public_key": fossSatanDereferenceZorkPublicKey,
|
|
"foss_satan_dereference_local_account_1_status_1": fossSatanDereferenceLocalAccount1Status1,
|
|
"foss_satan_dereference_local_account_1_status_1_lowercase": fossSatanDereferenceLocalAccount1Status1Lowercase,
|
|
"foss_satan_dereference_local_account_1_status_1_replies": fossSatanDereferenceLocalAccount1Status1Replies,
|
|
"foss_satan_dereference_local_account_1_status_1_replies_next": fossSatanDereferenceLocalAccount1Status1RepliesNext,
|
|
"foss_satan_dereference_local_account_1_status_1_replies_last": fossSatanDereferenceLocalAccount1Status1RepliesLast,
|
|
"foss_satan_dereference_zork_outbox": fossSatanDereferenceZorkOutbox,
|
|
"foss_satan_dereference_zork_outbox_first": fossSatanDereferenceZorkOutboxFirst,
|
|
"foss_satan_dereference_zork_outbox_next": fossSatanDereferenceZorkOutboxNext,
|
|
}
|
|
}
|
|
|
|
// GetSignatureForActivity prepares a mock HTTP request as if it were going to deliver activity to destination signed for privkey and pubKeyID, signs the request and returns the header values.
|
|
func GetSignatureForActivity(activity pub.Activity, pubKeyID string, privkey *rsa.PrivateKey, destination *url.URL) (signatureHeader string, digestHeader string, dateHeader string) {
|
|
// convert the activity into json bytes
|
|
m, err := activity.Serialize()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
b, err := json.Marshal(m)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Prepare HTTP request signer
|
|
sig, err := transport.NewPOSTSigner(120)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Prepare a mock request ready for signing
|
|
r, err := http.NewRequest("POST", destination.String(), bytes.NewReader(b))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
r.Header.Set("Host", destination.Host)
|
|
r.Header.Set("Date", time.Now().Format("Mon, 02 Jan 2006 15:04:05")+" GMT")
|
|
|
|
// Sign this new HTTP request
|
|
if err := sig.SignRequest(privkey, pubKeyID, r, b); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Load signed data from request
|
|
signatureHeader = r.Header.Get("Signature")
|
|
digestHeader = r.Header.Get("Digest")
|
|
dateHeader = r.Header.Get("Date")
|
|
|
|
// headers should now be populated
|
|
return
|
|
}
|
|
|
|
// GetSignatureForDereference prepares a mock HTTP request as if it were going to dereference destination signed for privkey and pubKeyID, signs the request and returns the header values.
|
|
func GetSignatureForDereference(pubKeyID string, privkey *rsa.PrivateKey, destination *url.URL) (signatureHeader string, digestHeader string, dateHeader string) {
|
|
// Prepare HTTP request signer
|
|
sig, err := transport.NewGETSigner(120)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Prepare a mock request ready for signing
|
|
r, err := http.NewRequest("GET", destination.String(), nil)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
r.Header.Set("Host", destination.Host)
|
|
r.Header.Set("Date", time.Now().Format("Mon, 02 Jan 2006 15:04:05")+" GMT")
|
|
|
|
// Sign this new HTTP request
|
|
if err := sig.SignRequest(privkey, pubKeyID, r, nil); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Load signed data from request
|
|
signatureHeader = r.Header.Get("Signature")
|
|
digestHeader = r.Header.Get("Digest")
|
|
dateHeader = r.Header.Get("Date")
|
|
|
|
// headers should now be populated
|
|
return
|
|
}
|
|
|
|
func newAPPerson(
|
|
profileIDURI *url.URL,
|
|
followingURI *url.URL,
|
|
followersURI *url.URL,
|
|
inboxURI *url.URL,
|
|
outboxURI *url.URL,
|
|
featuredURI *url.URL,
|
|
username string,
|
|
displayName string,
|
|
note string,
|
|
profileURL *url.URL,
|
|
discoverable bool,
|
|
publicKeyURI *url.URL,
|
|
pkey *rsa.PublicKey,
|
|
avatarURL *url.URL,
|
|
avatarContentType string,
|
|
headerURL *url.URL,
|
|
headerContentType string,
|
|
manuallyApprovesFollowers bool,
|
|
) vocab.ActivityStreamsPerson {
|
|
person := streams.NewActivityStreamsPerson()
|
|
|
|
// id should be the activitypub URI of this user
|
|
// something like https://example.org/users/example_user
|
|
idProp := streams.NewJSONLDIdProperty()
|
|
idProp.SetIRI(profileIDURI)
|
|
person.SetJSONLDId(idProp)
|
|
|
|
// following
|
|
// The URI for retrieving a list of accounts this user is following
|
|
followingProp := streams.NewActivityStreamsFollowingProperty()
|
|
followingProp.SetIRI(followingURI)
|
|
person.SetActivityStreamsFollowing(followingProp)
|
|
|
|
// followers
|
|
// The URI for retrieving a list of this user's followers
|
|
followersProp := streams.NewActivityStreamsFollowersProperty()
|
|
followersProp.SetIRI(followersURI)
|
|
person.SetActivityStreamsFollowers(followersProp)
|
|
|
|
// inbox
|
|
// the activitypub inbox of this user for accepting messages
|
|
inboxProp := streams.NewActivityStreamsInboxProperty()
|
|
inboxProp.SetIRI(inboxURI)
|
|
person.SetActivityStreamsInbox(inboxProp)
|
|
|
|
// outbox
|
|
// the activitypub outbox of this user for serving messages
|
|
outboxProp := streams.NewActivityStreamsOutboxProperty()
|
|
outboxProp.SetIRI(outboxURI)
|
|
person.SetActivityStreamsOutbox(outboxProp)
|
|
|
|
// featured posts
|
|
// Pinned posts.
|
|
featuredProp := streams.NewTootFeaturedProperty()
|
|
featuredProp.SetIRI(featuredURI)
|
|
person.SetTootFeatured(featuredProp)
|
|
|
|
// featuredTags
|
|
// NOT IMPLEMENTED
|
|
|
|
// preferredUsername
|
|
// Used for Webfinger lookup. Must be unique on the domain, and must correspond to a Webfinger acct: URI.
|
|
preferredUsernameProp := streams.NewActivityStreamsPreferredUsernameProperty()
|
|
preferredUsernameProp.SetXMLSchemaString(username)
|
|
person.SetActivityStreamsPreferredUsername(preferredUsernameProp)
|
|
|
|
// name
|
|
// Used as profile display name.
|
|
nameProp := streams.NewActivityStreamsNameProperty()
|
|
if displayName != "" {
|
|
nameProp.AppendXMLSchemaString(displayName)
|
|
} else {
|
|
nameProp.AppendXMLSchemaString(username)
|
|
}
|
|
person.SetActivityStreamsName(nameProp)
|
|
|
|
// summary
|
|
// Used as profile bio.
|
|
if note != "" {
|
|
summaryProp := streams.NewActivityStreamsSummaryProperty()
|
|
summaryProp.AppendXMLSchemaString(note)
|
|
person.SetActivityStreamsSummary(summaryProp)
|
|
}
|
|
|
|
// url
|
|
// Used as profile link.
|
|
urlProp := streams.NewActivityStreamsUrlProperty()
|
|
urlProp.AppendIRI(profileURL)
|
|
person.SetActivityStreamsUrl(urlProp)
|
|
|
|
// manuallyApprovesFollowers
|
|
manuallyApprovesFollowersProp := streams.NewActivityStreamsManuallyApprovesFollowersProperty()
|
|
manuallyApprovesFollowersProp.Set(manuallyApprovesFollowers)
|
|
person.SetActivityStreamsManuallyApprovesFollowers(manuallyApprovesFollowersProp)
|
|
|
|
// discoverable
|
|
// Will be shown in the profile directory.
|
|
discoverableProp := streams.NewTootDiscoverableProperty()
|
|
discoverableProp.Set(discoverable)
|
|
person.SetTootDiscoverable(discoverableProp)
|
|
|
|
// devices
|
|
// NOT IMPLEMENTED, probably won't implement
|
|
|
|
// alsoKnownAs
|
|
// Required for Move activity.
|
|
// TODO: NOT IMPLEMENTED **YET** -- this needs to be added as an activitypub extension to https://github.com/go-fed/activity, see https://github.com/go-fed/activity/tree/master/astool
|
|
|
|
// publicKey
|
|
// Required for signatures.
|
|
publicKeyProp := streams.NewW3IDSecurityV1PublicKeyProperty()
|
|
|
|
// create the public key
|
|
publicKey := streams.NewW3IDSecurityV1PublicKey()
|
|
|
|
// set ID for the public key
|
|
publicKeyIDProp := streams.NewJSONLDIdProperty()
|
|
publicKeyIDProp.SetIRI(publicKeyURI)
|
|
publicKey.SetJSONLDId(publicKeyIDProp)
|
|
|
|
// set owner for the public key
|
|
publicKeyOwnerProp := streams.NewW3IDSecurityV1OwnerProperty()
|
|
publicKeyOwnerProp.SetIRI(profileIDURI)
|
|
publicKey.SetW3IDSecurityV1Owner(publicKeyOwnerProp)
|
|
|
|
// set the pem key itself
|
|
encodedPublicKey, err := x509.MarshalPKIXPublicKey(pkey)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
publicKeyBytes := pem.EncodeToMemory(&pem.Block{
|
|
Type: "PUBLIC KEY",
|
|
Bytes: encodedPublicKey,
|
|
})
|
|
publicKeyPEMProp := streams.NewW3IDSecurityV1PublicKeyPemProperty()
|
|
publicKeyPEMProp.Set(string(publicKeyBytes))
|
|
publicKey.SetW3IDSecurityV1PublicKeyPem(publicKeyPEMProp)
|
|
|
|
// append the public key to the public key property
|
|
publicKeyProp.AppendW3IDSecurityV1PublicKey(publicKey)
|
|
|
|
// set the public key property on the Person
|
|
person.SetW3IDSecurityV1PublicKey(publicKeyProp)
|
|
|
|
// tag
|
|
// TODO: Any tags used in the summary of this profile
|
|
|
|
// attachment
|
|
// Used for profile fields.
|
|
// TODO: The PropertyValue type has to be added: https://schema.org/PropertyValue
|
|
|
|
// endpoints
|
|
// NOT IMPLEMENTED -- this is for shared inbox which we don't use
|
|
|
|
// icon
|
|
// Used as profile avatar.
|
|
iconProperty := streams.NewActivityStreamsIconProperty()
|
|
iconImage := streams.NewActivityStreamsImage()
|
|
mediaType := streams.NewActivityStreamsMediaTypeProperty()
|
|
mediaType.Set(avatarContentType)
|
|
iconImage.SetActivityStreamsMediaType(mediaType)
|
|
avatarURLProperty := streams.NewActivityStreamsUrlProperty()
|
|
avatarURLProperty.AppendIRI(avatarURL)
|
|
iconImage.SetActivityStreamsUrl(avatarURLProperty)
|
|
iconProperty.AppendActivityStreamsImage(iconImage)
|
|
person.SetActivityStreamsIcon(iconProperty)
|
|
|
|
// image
|
|
// Used as profile header.
|
|
headerProperty := streams.NewActivityStreamsImageProperty()
|
|
headerImage := streams.NewActivityStreamsImage()
|
|
headerMediaType := streams.NewActivityStreamsMediaTypeProperty()
|
|
mediaType.Set(headerContentType)
|
|
headerImage.SetActivityStreamsMediaType(headerMediaType)
|
|
headerURLProperty := streams.NewActivityStreamsUrlProperty()
|
|
headerURLProperty.AppendIRI(headerURL)
|
|
headerImage.SetActivityStreamsUrl(headerURLProperty)
|
|
headerProperty.AppendActivityStreamsImage(headerImage)
|
|
person.SetActivityStreamsImage(headerProperty)
|
|
|
|
return person
|
|
}
|
|
|
|
func newAPGroup(
|
|
profileIDURI *url.URL,
|
|
followingURI *url.URL,
|
|
followersURI *url.URL,
|
|
inboxURI *url.URL,
|
|
outboxURI *url.URL,
|
|
featuredURI *url.URL,
|
|
username string,
|
|
displayName string,
|
|
note string,
|
|
profileURL *url.URL,
|
|
discoverable bool,
|
|
publicKeyURI *url.URL,
|
|
pkey *rsa.PublicKey,
|
|
avatarURL *url.URL,
|
|
avatarContentType string,
|
|
headerURL *url.URL,
|
|
headerContentType string,
|
|
manuallyApprovesFollowers bool,
|
|
) vocab.ActivityStreamsGroup {
|
|
group := streams.NewActivityStreamsGroup()
|
|
|
|
// id should be the activitypub URI of this group
|
|
// something like https://example.org/users/example_group
|
|
idProp := streams.NewJSONLDIdProperty()
|
|
idProp.SetIRI(profileIDURI)
|
|
group.SetJSONLDId(idProp)
|
|
|
|
// following
|
|
// The URI for retrieving a list of accounts this group is following
|
|
followingProp := streams.NewActivityStreamsFollowingProperty()
|
|
followingProp.SetIRI(followingURI)
|
|
group.SetActivityStreamsFollowing(followingProp)
|
|
|
|
// followers
|
|
// The URI for retrieving a list of this user's followers
|
|
followersProp := streams.NewActivityStreamsFollowersProperty()
|
|
followersProp.SetIRI(followersURI)
|
|
group.SetActivityStreamsFollowers(followersProp)
|
|
|
|
// inbox
|
|
// the activitypub inbox of this user for accepting messages
|
|
inboxProp := streams.NewActivityStreamsInboxProperty()
|
|
inboxProp.SetIRI(inboxURI)
|
|
group.SetActivityStreamsInbox(inboxProp)
|
|
|
|
// outbox
|
|
// the activitypub outbox of this user for serving messages
|
|
outboxProp := streams.NewActivityStreamsOutboxProperty()
|
|
outboxProp.SetIRI(outboxURI)
|
|
group.SetActivityStreamsOutbox(outboxProp)
|
|
|
|
// featured posts
|
|
// Pinned posts.
|
|
featuredProp := streams.NewTootFeaturedProperty()
|
|
featuredProp.SetIRI(featuredURI)
|
|
group.SetTootFeatured(featuredProp)
|
|
|
|
// featuredTags
|
|
// NOT IMPLEMENTED
|
|
|
|
// preferredUsername
|
|
// Used for Webfinger lookup. Must be unique on the domain, and must correspond to a Webfinger acct: URI.
|
|
preferredUsernameProp := streams.NewActivityStreamsPreferredUsernameProperty()
|
|
preferredUsernameProp.SetXMLSchemaString(username)
|
|
group.SetActivityStreamsPreferredUsername(preferredUsernameProp)
|
|
|
|
// name
|
|
// Used as profile display name.
|
|
nameProp := streams.NewActivityStreamsNameProperty()
|
|
if displayName != "" {
|
|
nameProp.AppendXMLSchemaString(displayName)
|
|
} else {
|
|
nameProp.AppendXMLSchemaString(username)
|
|
}
|
|
group.SetActivityStreamsName(nameProp)
|
|
|
|
// summary
|
|
// Used as profile bio.
|
|
if note != "" {
|
|
summaryProp := streams.NewActivityStreamsSummaryProperty()
|
|
summaryProp.AppendXMLSchemaString(note)
|
|
group.SetActivityStreamsSummary(summaryProp)
|
|
}
|
|
|
|
// url
|
|
// Used as profile link.
|
|
urlProp := streams.NewActivityStreamsUrlProperty()
|
|
urlProp.AppendIRI(profileURL)
|
|
group.SetActivityStreamsUrl(urlProp)
|
|
|
|
// manuallyApprovesFollowers
|
|
manuallyApprovesFollowersProp := streams.NewActivityStreamsManuallyApprovesFollowersProperty()
|
|
manuallyApprovesFollowersProp.Set(manuallyApprovesFollowers)
|
|
group.SetActivityStreamsManuallyApprovesFollowers(manuallyApprovesFollowersProp)
|
|
|
|
// discoverable
|
|
// Will be shown in the profile directory.
|
|
discoverableProp := streams.NewTootDiscoverableProperty()
|
|
discoverableProp.Set(discoverable)
|
|
group.SetTootDiscoverable(discoverableProp)
|
|
|
|
// devices
|
|
// NOT IMPLEMENTED, probably won't implement
|
|
|
|
// alsoKnownAs
|
|
// Required for Move activity.
|
|
// TODO: NOT IMPLEMENTED **YET** -- this needs to be added as an activitypub extension to https://github.com/go-fed/activity, see https://github.com/go-fed/activity/tree/master/astool
|
|
|
|
// publicKey
|
|
// Required for signatures.
|
|
publicKeyProp := streams.NewW3IDSecurityV1PublicKeyProperty()
|
|
|
|
// create the public key
|
|
publicKey := streams.NewW3IDSecurityV1PublicKey()
|
|
|
|
// set ID for the public key
|
|
publicKeyIDProp := streams.NewJSONLDIdProperty()
|
|
publicKeyIDProp.SetIRI(publicKeyURI)
|
|
publicKey.SetJSONLDId(publicKeyIDProp)
|
|
|
|
// set owner for the public key
|
|
publicKeyOwnerProp := streams.NewW3IDSecurityV1OwnerProperty()
|
|
publicKeyOwnerProp.SetIRI(profileIDURI)
|
|
publicKey.SetW3IDSecurityV1Owner(publicKeyOwnerProp)
|
|
|
|
// set the pem key itself
|
|
encodedPublicKey, err := x509.MarshalPKIXPublicKey(pkey)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
publicKeyBytes := pem.EncodeToMemory(&pem.Block{
|
|
Type: "PUBLIC KEY",
|
|
Bytes: encodedPublicKey,
|
|
})
|
|
publicKeyPEMProp := streams.NewW3IDSecurityV1PublicKeyPemProperty()
|
|
publicKeyPEMProp.Set(string(publicKeyBytes))
|
|
publicKey.SetW3IDSecurityV1PublicKeyPem(publicKeyPEMProp)
|
|
|
|
// append the public key to the public key property
|
|
publicKeyProp.AppendW3IDSecurityV1PublicKey(publicKey)
|
|
|
|
// set the public key property on the Person
|
|
group.SetW3IDSecurityV1PublicKey(publicKeyProp)
|
|
|
|
// tag
|
|
// TODO: Any tags used in the summary of this profile
|
|
|
|
// attachment
|
|
// Used for profile fields.
|
|
// TODO: The PropertyValue type has to be added: https://schema.org/PropertyValue
|
|
|
|
// endpoints
|
|
// NOT IMPLEMENTED -- this is for shared inbox which we don't use
|
|
|
|
// icon
|
|
// Used as profile avatar.
|
|
iconProperty := streams.NewActivityStreamsIconProperty()
|
|
iconImage := streams.NewActivityStreamsImage()
|
|
mediaType := streams.NewActivityStreamsMediaTypeProperty()
|
|
mediaType.Set(avatarContentType)
|
|
iconImage.SetActivityStreamsMediaType(mediaType)
|
|
avatarURLProperty := streams.NewActivityStreamsUrlProperty()
|
|
avatarURLProperty.AppendIRI(avatarURL)
|
|
iconImage.SetActivityStreamsUrl(avatarURLProperty)
|
|
iconProperty.AppendActivityStreamsImage(iconImage)
|
|
group.SetActivityStreamsIcon(iconProperty)
|
|
|
|
// image
|
|
// Used as profile header.
|
|
headerProperty := streams.NewActivityStreamsImageProperty()
|
|
headerImage := streams.NewActivityStreamsImage()
|
|
headerMediaType := streams.NewActivityStreamsMediaTypeProperty()
|
|
mediaType.Set(headerContentType)
|
|
headerImage.SetActivityStreamsMediaType(headerMediaType)
|
|
headerURLProperty := streams.NewActivityStreamsUrlProperty()
|
|
headerURLProperty.AppendIRI(headerURL)
|
|
headerImage.SetActivityStreamsUrl(headerURLProperty)
|
|
headerProperty.AppendActivityStreamsImage(headerImage)
|
|
group.SetActivityStreamsImage(headerProperty)
|
|
|
|
return group
|
|
}
|
|
|
|
func newAPService(
|
|
profileIDURI *url.URL,
|
|
followingURI *url.URL,
|
|
followersURI *url.URL,
|
|
inboxURI *url.URL,
|
|
outboxURI *url.URL,
|
|
featuredURI *url.URL,
|
|
username string,
|
|
displayName string,
|
|
note string,
|
|
profileURL *url.URL,
|
|
discoverable bool,
|
|
publicKeyURI *url.URL,
|
|
pkey *rsa.PublicKey,
|
|
avatarURL *url.URL,
|
|
avatarContentType string,
|
|
headerURL *url.URL,
|
|
headerContentType string,
|
|
manuallyApprovesFollowers bool,
|
|
) vocab.ActivityStreamsService {
|
|
service := streams.NewActivityStreamsService()
|
|
|
|
// id should be the activitypub URI of this group
|
|
// something like https://example.org/users/example_group
|
|
idProp := streams.NewJSONLDIdProperty()
|
|
idProp.SetIRI(profileIDURI)
|
|
service.SetJSONLDId(idProp)
|
|
|
|
// following
|
|
// The URI for retrieving a list of accounts this group is following
|
|
followingProp := streams.NewActivityStreamsFollowingProperty()
|
|
followingProp.SetIRI(followingURI)
|
|
service.SetActivityStreamsFollowing(followingProp)
|
|
|
|
// followers
|
|
// The URI for retrieving a list of this user's followers
|
|
followersProp := streams.NewActivityStreamsFollowersProperty()
|
|
followersProp.SetIRI(followersURI)
|
|
service.SetActivityStreamsFollowers(followersProp)
|
|
|
|
// inbox
|
|
// the activitypub inbox of this user for accepting messages
|
|
inboxProp := streams.NewActivityStreamsInboxProperty()
|
|
inboxProp.SetIRI(inboxURI)
|
|
service.SetActivityStreamsInbox(inboxProp)
|
|
|
|
// outbox
|
|
// the activitypub outbox of this user for serving messages
|
|
outboxProp := streams.NewActivityStreamsOutboxProperty()
|
|
outboxProp.SetIRI(outboxURI)
|
|
service.SetActivityStreamsOutbox(outboxProp)
|
|
|
|
// featured posts
|
|
// Pinned posts.
|
|
featuredProp := streams.NewTootFeaturedProperty()
|
|
featuredProp.SetIRI(featuredURI)
|
|
service.SetTootFeatured(featuredProp)
|
|
|
|
// featuredTags
|
|
// NOT IMPLEMENTED
|
|
|
|
// preferredUsername
|
|
// Used for Webfinger lookup. Must be unique on the domain, and must correspond to a Webfinger acct: URI.
|
|
preferredUsernameProp := streams.NewActivityStreamsPreferredUsernameProperty()
|
|
preferredUsernameProp.SetXMLSchemaString(username)
|
|
service.SetActivityStreamsPreferredUsername(preferredUsernameProp)
|
|
|
|
// name
|
|
// Used as profile display name.
|
|
nameProp := streams.NewActivityStreamsNameProperty()
|
|
if displayName != "" {
|
|
nameProp.AppendXMLSchemaString(displayName)
|
|
} else {
|
|
nameProp.AppendXMLSchemaString(username)
|
|
}
|
|
service.SetActivityStreamsName(nameProp)
|
|
|
|
// summary
|
|
// Used as profile bio.
|
|
if note != "" {
|
|
summaryProp := streams.NewActivityStreamsSummaryProperty()
|
|
summaryProp.AppendXMLSchemaString(note)
|
|
service.SetActivityStreamsSummary(summaryProp)
|
|
}
|
|
|
|
// url
|
|
// Used as profile link.
|
|
urlProp := streams.NewActivityStreamsUrlProperty()
|
|
urlProp.AppendIRI(profileURL)
|
|
service.SetActivityStreamsUrl(urlProp)
|
|
|
|
// manuallyApprovesFollowers
|
|
manuallyApprovesFollowersProp := streams.NewActivityStreamsManuallyApprovesFollowersProperty()
|
|
manuallyApprovesFollowersProp.Set(manuallyApprovesFollowers)
|
|
service.SetActivityStreamsManuallyApprovesFollowers(manuallyApprovesFollowersProp)
|
|
|
|
// discoverable
|
|
// Will be shown in the profile directory.
|
|
discoverableProp := streams.NewTootDiscoverableProperty()
|
|
discoverableProp.Set(discoverable)
|
|
service.SetTootDiscoverable(discoverableProp)
|
|
|
|
// devices
|
|
// NOT IMPLEMENTED, probably won't implement
|
|
|
|
// alsoKnownAs
|
|
// Required for Move activity.
|
|
// TODO: NOT IMPLEMENTED **YET** -- this needs to be added as an activitypub extension to https://github.com/go-fed/activity, see https://github.com/go-fed/activity/tree/master/astool
|
|
|
|
// publicKey
|
|
// Required for signatures.
|
|
publicKeyProp := streams.NewW3IDSecurityV1PublicKeyProperty()
|
|
|
|
// create the public key
|
|
publicKey := streams.NewW3IDSecurityV1PublicKey()
|
|
|
|
// set ID for the public key
|
|
publicKeyIDProp := streams.NewJSONLDIdProperty()
|
|
publicKeyIDProp.SetIRI(publicKeyURI)
|
|
publicKey.SetJSONLDId(publicKeyIDProp)
|
|
|
|
// set owner for the public key
|
|
publicKeyOwnerProp := streams.NewW3IDSecurityV1OwnerProperty()
|
|
publicKeyOwnerProp.SetIRI(profileIDURI)
|
|
publicKey.SetW3IDSecurityV1Owner(publicKeyOwnerProp)
|
|
|
|
// set the pem key itself
|
|
encodedPublicKey, err := x509.MarshalPKIXPublicKey(pkey)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
publicKeyBytes := pem.EncodeToMemory(&pem.Block{
|
|
Type: "PUBLIC KEY",
|
|
Bytes: encodedPublicKey,
|
|
})
|
|
publicKeyPEMProp := streams.NewW3IDSecurityV1PublicKeyPemProperty()
|
|
publicKeyPEMProp.Set(string(publicKeyBytes))
|
|
publicKey.SetW3IDSecurityV1PublicKeyPem(publicKeyPEMProp)
|
|
|
|
// append the public key to the public key property
|
|
publicKeyProp.AppendW3IDSecurityV1PublicKey(publicKey)
|
|
|
|
// set the public key property on the Person
|
|
service.SetW3IDSecurityV1PublicKey(publicKeyProp)
|
|
|
|
// tag
|
|
// TODO: Any tags used in the summary of this profile
|
|
|
|
// attachment
|
|
// Used for profile fields.
|
|
// TODO: The PropertyValue type has to be added: https://schema.org/PropertyValue
|
|
|
|
// endpoints
|
|
// NOT IMPLEMENTED -- this is for shared inbox which we don't use
|
|
|
|
// icon
|
|
// Used as profile avatar.
|
|
iconProperty := streams.NewActivityStreamsIconProperty()
|
|
iconImage := streams.NewActivityStreamsImage()
|
|
mediaType := streams.NewActivityStreamsMediaTypeProperty()
|
|
mediaType.Set(avatarContentType)
|
|
iconImage.SetActivityStreamsMediaType(mediaType)
|
|
avatarURLProperty := streams.NewActivityStreamsUrlProperty()
|
|
avatarURLProperty.AppendIRI(avatarURL)
|
|
iconImage.SetActivityStreamsUrl(avatarURLProperty)
|
|
iconProperty.AppendActivityStreamsImage(iconImage)
|
|
service.SetActivityStreamsIcon(iconProperty)
|
|
|
|
// image
|
|
// Used as profile header.
|
|
headerProperty := streams.NewActivityStreamsImageProperty()
|
|
headerImage := streams.NewActivityStreamsImage()
|
|
headerMediaType := streams.NewActivityStreamsMediaTypeProperty()
|
|
mediaType.Set(headerContentType)
|
|
headerImage.SetActivityStreamsMediaType(headerMediaType)
|
|
headerURLProperty := streams.NewActivityStreamsUrlProperty()
|
|
headerURLProperty.AppendIRI(headerURL)
|
|
headerImage.SetActivityStreamsUrl(headerURLProperty)
|
|
headerProperty.AppendActivityStreamsImage(headerImage)
|
|
service.SetActivityStreamsImage(headerProperty)
|
|
|
|
return service
|
|
}
|
|
|
|
func newAPMention(uri *url.URL, namestring string) vocab.ActivityStreamsMention {
|
|
mention := streams.NewActivityStreamsMention()
|
|
|
|
hrefProp := streams.NewActivityStreamsHrefProperty()
|
|
hrefProp.SetIRI(uri)
|
|
mention.SetActivityStreamsHref(hrefProp)
|
|
|
|
nameProp := streams.NewActivityStreamsNameProperty()
|
|
nameProp.AppendXMLSchemaString(namestring)
|
|
mention.SetActivityStreamsName(nameProp)
|
|
|
|
return mention
|
|
}
|
|
|
|
func newAPImage(url *url.URL, mediaType string, imageDescription string, blurhash string) vocab.ActivityStreamsImage {
|
|
image := streams.NewActivityStreamsImage()
|
|
|
|
if url != nil {
|
|
urlProp := streams.NewActivityStreamsUrlProperty()
|
|
urlProp.AppendIRI(url)
|
|
image.SetActivityStreamsUrl(urlProp)
|
|
}
|
|
|
|
if mediaType != "" {
|
|
mediaTypeProp := streams.NewActivityStreamsMediaTypeProperty()
|
|
mediaTypeProp.Set(mediaType)
|
|
image.SetActivityStreamsMediaType(mediaTypeProp)
|
|
}
|
|
|
|
if imageDescription != "" {
|
|
nameProp := streams.NewActivityStreamsNameProperty()
|
|
nameProp.AppendXMLSchemaString(imageDescription)
|
|
image.SetActivityStreamsName(nameProp)
|
|
}
|
|
|
|
if blurhash != "" {
|
|
blurhashProp := streams.NewTootBlurhashProperty()
|
|
blurhashProp.Set(blurhash)
|
|
image.SetTootBlurhash(blurhashProp)
|
|
}
|
|
|
|
return image
|
|
}
|
|
|
|
// NewAPNote returns a new activity streams note for the given parameters
|
|
func NewAPNote(
|
|
noteID *url.URL,
|
|
noteURL *url.URL,
|
|
noteCreatedAt time.Time,
|
|
noteContent string,
|
|
noteSummary string,
|
|
noteAttributedTo *url.URL,
|
|
noteTo []*url.URL,
|
|
noteCC []*url.URL,
|
|
noteSensitive bool,
|
|
noteMentions []vocab.ActivityStreamsMention,
|
|
noteAttachments []vocab.ActivityStreamsImage,
|
|
) vocab.ActivityStreamsNote {
|
|
// create the note itself
|
|
note := streams.NewActivityStreamsNote()
|
|
|
|
// set id
|
|
if noteID != nil {
|
|
id := streams.NewJSONLDIdProperty()
|
|
id.Set(noteID)
|
|
note.SetJSONLDId(id)
|
|
}
|
|
|
|
// set noteURL
|
|
if noteURL != nil {
|
|
url := streams.NewActivityStreamsUrlProperty()
|
|
url.AppendIRI(noteURL)
|
|
note.SetActivityStreamsUrl(url)
|
|
}
|
|
|
|
if noteCreatedAt.IsZero() {
|
|
noteCreatedAt = time.Now()
|
|
}
|
|
published := streams.NewActivityStreamsPublishedProperty()
|
|
published.Set(noteCreatedAt)
|
|
note.SetActivityStreamsPublished(published)
|
|
|
|
// set noteContent
|
|
if noteContent != "" {
|
|
content := streams.NewActivityStreamsContentProperty()
|
|
content.AppendXMLSchemaString(noteContent)
|
|
note.SetActivityStreamsContent(content)
|
|
}
|
|
|
|
// set noteSummary (aka content warning)
|
|
if noteSummary != "" {
|
|
summary := streams.NewActivityStreamsSummaryProperty()
|
|
summary.AppendXMLSchemaString(noteSummary)
|
|
note.SetActivityStreamsSummary(summary)
|
|
}
|
|
|
|
// set noteAttributedTo (the url of the author of the note)
|
|
if noteAttributedTo != nil {
|
|
attributedTo := streams.NewActivityStreamsAttributedToProperty()
|
|
attributedTo.AppendIRI(noteAttributedTo)
|
|
note.SetActivityStreamsAttributedTo(attributedTo)
|
|
}
|
|
|
|
// set noteTO
|
|
if noteTo != nil {
|
|
to := streams.NewActivityStreamsToProperty()
|
|
for _, r := range noteTo {
|
|
to.AppendIRI(r)
|
|
}
|
|
note.SetActivityStreamsTo(to)
|
|
}
|
|
|
|
// set noteCC
|
|
if noteCC != nil {
|
|
cc := streams.NewActivityStreamsCcProperty()
|
|
for _, r := range noteCC {
|
|
cc.AppendIRI(r)
|
|
}
|
|
note.SetActivityStreamsCc(cc)
|
|
}
|
|
|
|
// mentions
|
|
tag := streams.NewActivityStreamsTagProperty()
|
|
for _, m := range noteMentions {
|
|
tag.AppendActivityStreamsMention(m)
|
|
}
|
|
note.SetActivityStreamsTag(tag)
|
|
|
|
// append any attachments as ActivityStreamsImage
|
|
if noteAttachments != nil {
|
|
attachmentProperty := streams.NewActivityStreamsAttachmentProperty()
|
|
for _, a := range noteAttachments {
|
|
attachmentProperty.AppendActivityStreamsImage(a)
|
|
}
|
|
note.SetActivityStreamsAttachment(attachmentProperty)
|
|
}
|
|
|
|
return note
|
|
}
|
|
|
|
// WrapAPNoteInCreate wraps the given activity streams note in a Create activity streams action
|
|
func WrapAPNoteInCreate(createID *url.URL, createActor *url.URL, createPublished time.Time, createNote vocab.ActivityStreamsNote) vocab.ActivityStreamsCreate {
|
|
// create the.... create
|
|
create := streams.NewActivityStreamsCreate()
|
|
|
|
// set createID
|
|
if createID != nil {
|
|
id := streams.NewJSONLDIdProperty()
|
|
id.Set(createID)
|
|
create.SetJSONLDId(id)
|
|
}
|
|
|
|
// set createActor
|
|
if createActor != nil {
|
|
actor := streams.NewActivityStreamsActorProperty()
|
|
actor.AppendIRI(createActor)
|
|
create.SetActivityStreamsActor(actor)
|
|
}
|
|
|
|
// set createPublished (time)
|
|
if !createPublished.IsZero() {
|
|
published := streams.NewActivityStreamsPublishedProperty()
|
|
published.Set(createPublished)
|
|
create.SetActivityStreamsPublished(published)
|
|
}
|
|
|
|
// setCreateTo
|
|
if createNote.GetActivityStreamsTo() != nil {
|
|
create.SetActivityStreamsTo(createNote.GetActivityStreamsTo())
|
|
}
|
|
|
|
// setCreateCC
|
|
if createNote.GetActivityStreamsCc() != nil {
|
|
create.SetActivityStreamsCc(createNote.GetActivityStreamsCc())
|
|
}
|
|
|
|
// set createNote
|
|
if createNote != nil {
|
|
note := streams.NewActivityStreamsObjectProperty()
|
|
note.AppendActivityStreamsNote(createNote)
|
|
create.SetActivityStreamsObject(note)
|
|
}
|
|
|
|
return create
|
|
}
|
|
|
|
func newAPAnnounce(announceID *url.URL, announceActor *url.URL, announcePublished time.Time, announceTo *url.URL, announceNote vocab.ActivityStreamsNote) vocab.ActivityStreamsAnnounce {
|
|
announce := streams.NewActivityStreamsAnnounce()
|
|
|
|
if announceID != nil {
|
|
id := streams.NewJSONLDIdProperty()
|
|
id.Set(announceID)
|
|
announce.SetJSONLDId(id)
|
|
}
|
|
|
|
if announceActor != nil {
|
|
actor := streams.NewActivityStreamsActorProperty()
|
|
actor.AppendIRI(announceActor)
|
|
announce.SetActivityStreamsActor(actor)
|
|
}
|
|
|
|
if !announcePublished.IsZero() {
|
|
published := streams.NewActivityStreamsPublishedProperty()
|
|
published.Set(announcePublished)
|
|
announce.SetActivityStreamsPublished(published)
|
|
}
|
|
|
|
to := streams.NewActivityStreamsToProperty()
|
|
to.AppendIRI(announceTo)
|
|
announce.SetActivityStreamsTo(announceNote.GetActivityStreamsTo())
|
|
|
|
cc := streams.NewActivityStreamsCcProperty()
|
|
cc.AppendIRI(announceNote.GetActivityStreamsAttributedTo().Begin().GetIRI())
|
|
announce.SetActivityStreamsCc(cc)
|
|
|
|
if announceNote != nil {
|
|
noteIRI := streams.NewActivityStreamsObjectProperty()
|
|
noteIRI.AppendIRI(announceNote.GetJSONLDId().Get())
|
|
announce.SetActivityStreamsObject(noteIRI)
|
|
}
|
|
|
|
return announce
|
|
}
|