diff --git a/internal/apimodule/status/statuscreate.go b/internal/apimodule/status/statuscreate.go index 97354e767..7d9b2fdbb 100644 --- a/internal/apimodule/status/statuscreate.go +++ b/internal/apimodule/status/statuscreate.go @@ -93,7 +93,7 @@ func (m *Module) StatusCreatePOSTHandler(c *gin.Context) { // So now we can start digging a bit deeper into the form and building up the new status from it. // first we create a new status and add some basic info to it - uris := util.GenerateURIs(authed.Account.Username, m.config.Protocol, m.config.Host) + uris := util.GenerateURIsForAccount(authed.Account.Username, m.config.Protocol, m.config.Host) thisStatusID := uuid.NewString() thisStatusURI := fmt.Sprintf("%s/%s", uris.StatusesURI, thisStatusID) thisStatusURL := fmt.Sprintf("%s/%s", uris.StatusesURL, thisStatusID) diff --git a/internal/db/pg.go b/internal/db/pg.go index 24a57d8a5..e8a4b4004 100644 --- a/internal/db/pg.go +++ b/internal/db/pg.go @@ -456,21 +456,21 @@ func (ps *postgresService) NewSignup(username string, reason string, requireAppr return nil, err } - uris := util.GenerateURIs(username, ps.config.Protocol, ps.config.Host) + newAccountURIs := util.GenerateURIsForAccount(username, ps.config.Protocol, ps.config.Host) a := >smodel.Account{ Username: username, DisplayName: username, Reason: reason, - URL: uris.UserURL, + URL: newAccountURIs.UserURL, PrivateKey: key, PublicKey: &key.PublicKey, ActorType: gtsmodel.ActivityStreamsPerson, - URI: uris.UserURI, - InboxURL: uris.InboxURI, - OutboxURL: uris.OutboxURI, - FollowersURL: uris.FollowersURI, - FeaturedCollectionURL: uris.CollectionURI, + URI: newAccountURIs.UserURI, + InboxURL: newAccountURIs.InboxURI, + OutboxURL: newAccountURIs.OutboxURI, + FollowersURL: newAccountURIs.FollowersURI, + FeaturedCollectionURL: newAccountURIs.CollectionURI, } if _, err = ps.conn.Model(a).Insert(); err != nil { return nil, err diff --git a/internal/util/status.go b/internal/util/statustools.go similarity index 90% rename from internal/util/status.go rename to internal/util/statustools.go index e4b3ec6a5..fd9bb9c24 100644 --- a/internal/util/status.go +++ b/internal/util/statustools.go @@ -34,7 +34,7 @@ func DeriveMentions(status string) []string { for _, m := range mentionRegex.FindAllStringSubmatch(status, -1) { mentionedAccounts = append(mentionedAccounts, m[1]) } - return Lower(Unique(mentionedAccounts)) + return lower(unique(mentionedAccounts)) } // DeriveHashtags takes a plaintext (ie., not html-formatted) status, @@ -46,7 +46,7 @@ func DeriveHashtags(status string) []string { for _, m := range hashtagRegex.FindAllStringSubmatch(status, -1) { tags = append(tags, m[1]) } - return Lower(Unique(tags)) + return lower(unique(tags)) } // DeriveEmojis takes a plaintext (ie., not html-formatted) status, @@ -58,11 +58,11 @@ func DeriveEmojis(status string) []string { for _, m := range emojiRegex.FindAllStringSubmatch(status, -1) { emojis = append(emojis, m[1]) } - return Lower(Unique(emojis)) + return lower(unique(emojis)) } -// Unique returns a deduplicated version of a given string slice. -func Unique(s []string) []string { +// unique returns a deduplicated version of a given string slice. +func unique(s []string) []string { keys := make(map[string]bool) list := []string{} for _, entry := range s { @@ -74,8 +74,8 @@ func Unique(s []string) []string { return list } -// Lower lowercases all strings in a given string slice -func Lower(s []string) []string { +// lower lowercases all strings in a given string slice +func lower(s []string) []string { new := []string{} for _, i := range s { new = append(new, strings.ToLower(i)) diff --git a/internal/util/status_test.go b/internal/util/statustools_test.go similarity index 91% rename from internal/util/status_test.go rename to internal/util/statustools_test.go index 72bd3e885..7c9af2cbd 100644 --- a/internal/util/status_test.go +++ b/internal/util/statustools_test.go @@ -16,13 +16,14 @@ along with this program. If not, see . */ -package util +package util_test import ( "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" + "github.com/superseriousbusiness/gotosocial/internal/util" ) type StatusTestSuite struct { @@ -41,7 +42,7 @@ func (suite *StatusTestSuite) TestDeriveMentionsOK() { here is a duplicate mention: @hello@test.lgbt ` - menchies := DeriveMentions(statusText) + menchies := util.DeriveMentions(statusText) assert.Len(suite.T(), menchies, 4) assert.Equal(suite.T(), "@dumpsterqueer@example.org", menchies[0]) assert.Equal(suite.T(), "@someone_else@testing.best-horse.com", menchies[1]) @@ -51,7 +52,7 @@ func (suite *StatusTestSuite) TestDeriveMentionsOK() { func (suite *StatusTestSuite) TestDeriveMentionsEmpty() { statusText := `` - menchies := DeriveMentions(statusText) + menchies := util.DeriveMentions(statusText) assert.Len(suite.T(), menchies, 0) } @@ -66,7 +67,7 @@ func (suite *StatusTestSuite) TestDeriveHashtagsOK() { #111111 thisalsoshouldn'twork#### ##` - tags := DeriveHashtags(statusText) + tags := util.DeriveHashtags(statusText) assert.Len(suite.T(), tags, 5) assert.Equal(suite.T(), "testing123", tags[0]) assert.Equal(suite.T(), "also", tags[1]) @@ -89,7 +90,7 @@ Here's some normal text with an :emoji: at the end :underscores_ok_too: ` - tags := DeriveEmojis(statusText) + tags := util.DeriveEmojis(statusText) assert.Len(suite.T(), tags, 7) assert.Equal(suite.T(), "test", tags[0]) assert.Equal(suite.T(), "another", tags[1]) diff --git a/internal/util/uri.go b/internal/util/uri.go new file mode 100644 index 000000000..8617c58c7 --- /dev/null +++ b/internal/util/uri.go @@ -0,0 +1,96 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +package util + +import ( + "fmt" + "net/url" +) + +const ( + // UsersPath is for serving users info + UsersPath = "users" + // StatusesPath is for serving statuses + StatusesPath = "statuses" + // InboxPath represents the webfinger inbox location + InboxPath = "inbox" + // OutboxPath represents the webfinger outbox location + OutboxPath = "outbox" + // FollowersPath represents the webfinger followers location + FollowersPath = "followers" + // CollectionsPath represents the webfinger collections location + CollectionsPath = "collections" + // FeaturedPath represents the webfinger featured location + FeaturedPath = "featured" +) + +// UserURIs contains a bunch of UserURIs and URLs for a user, host, account, etc. +type UserURIs struct { + // The web URL of the instance host, eg https://example.org + HostURL string + // The web URL of the user, eg., https://example.org/@example_user + UserURL string + // The web URL for statuses of this user, eg., https://example.org/@example_user/statuses + StatusesURL string + + // The webfinger URI of this user, eg., https://example.org/users/example_user + UserURI string + // The webfinger URI for this user's statuses, eg., https://example.org/users/example_user/statuses + StatusesURI string + // The webfinger URI for this user's activitypub inbox, eg., https://example.org/users/example_user/inbox + InboxURI string + // The webfinger URI for this user's activitypub outbox, eg., https://example.org/users/example_user/outbox + OutboxURI string + // The webfinger URI for this user's followers, eg., https://example.org/users/example_user/followers + FollowersURI string + // The webfinger URI for this user's featured collections, eg., https://example.org/users/example_user/collections/featured + CollectionURI string +} + +// GenerateURIsForAccount throws together a bunch of URIs for the given username, with the given protocol and host. +func GenerateURIsForAccount(username string, protocol string, host string) *UserURIs { + // The below URLs are used for serving web requests + hostURL := fmt.Sprintf("%s://%s", protocol, host) + userURL := fmt.Sprintf("%s/@%s", hostURL, username) + statusesURL := fmt.Sprintf("%s/%s", userURL, StatusesPath) + + // the below URIs are used in ActivityPub and Webfinger + userURI := fmt.Sprintf("%s/%s/%s", hostURL, UsersPath, username) + statusesURI := fmt.Sprintf("%s/%s", userURI, StatusesPath) + inboxURI := fmt.Sprintf("%s/%s", userURI, InboxPath) + outboxURI := fmt.Sprintf("%s/%s", userURI, OutboxPath) + followersURI := fmt.Sprintf("%s/%s", userURI, FollowersPath) + collectionURI := fmt.Sprintf("%s/%s/%s", userURI, CollectionsPath, FeaturedPath) + return &UserURIs{ + HostURL: hostURL, + UserURL: userURL, + StatusesURL: statusesURL, + + UserURI: userURI, + StatusesURI: statusesURI, + InboxURI: inboxURI, + OutboxURI: outboxURI, + FollowersURI: followersURI, + CollectionURI: collectionURI, + } +} + +func ParseActivityPubRequestURL(id *url.URL) error { + return nil +} diff --git a/internal/util/parse.go b/internal/util/visibility.go similarity index 60% rename from internal/util/parse.go rename to internal/util/visibility.go index f0bcff5dc..c847ef980 100644 --- a/internal/util/parse.go +++ b/internal/util/visibility.go @@ -19,52 +19,10 @@ package util import ( - "fmt" - "github.com/superseriousbusiness/gotosocial/internal/db/gtsmodel" mastotypes "github.com/superseriousbusiness/gotosocial/internal/mastotypes/mastomodel" ) -// URIs contains a bunch of URIs and URLs for a user, host, account, etc. -type URIs struct { - HostURL string - UserURL string - StatusesURL string - - UserURI string - StatusesURI string - InboxURI string - OutboxURI string - FollowersURI string - CollectionURI string -} - -// GenerateURIs throws together a bunch of URIs for the given username, with the given protocol and host. -func GenerateURIs(username string, protocol string, host string) *URIs { - hostURL := fmt.Sprintf("%s://%s", protocol, host) - userURL := fmt.Sprintf("%s/@%s", hostURL, username) - statusesURL := fmt.Sprintf("%s/statuses", userURL) - - userURI := fmt.Sprintf("%s/users/%s", hostURL, username) - statusesURI := fmt.Sprintf("%s/statuses", userURI) - inboxURI := fmt.Sprintf("%s/inbox", userURI) - outboxURI := fmt.Sprintf("%s/outbox", userURI) - followersURI := fmt.Sprintf("%s/followers", userURI) - collectionURI := fmt.Sprintf("%s/collections/featured", userURI) - return &URIs{ - HostURL: hostURL, - UserURL: userURL, - StatusesURL: statusesURL, - - UserURI: userURI, - StatusesURI: statusesURI, - InboxURI: inboxURI, - OutboxURI: outboxURI, - FollowersURI: followersURI, - CollectionURI: collectionURI, - } -} - // ParseGTSVisFromMastoVis converts a mastodon visibility into its gts equivalent. func ParseGTSVisFromMastoVis(m mastotypes.Visibility) gtsmodel.Visibility { switch m {