mirror of
1
Fork 0

Remove unnecessary storage config variables (#344)

* rewire config to not use extraneous serve vars

* rename 'file' to 'local' for consistency

* use Type and Size again
This commit is contained in:
tobi 2021-12-20 15:19:53 +01:00 committed by GitHub
parent 2582515b4d
commit cb8688f429
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 310 additions and 408 deletions

View File

@ -98,7 +98,7 @@ var Start action.GTSAction = func(ctx context.Context) error {
timelineManager := timelineprocessing.NewManager(dbService, typeConverter) timelineManager := timelineprocessing.NewManager(dbService, typeConverter)
// Open the storage backend // Open the storage backend
storageBasePath := viper.GetString(config.Keys.StorageBasePath) storageBasePath := viper.GetString(config.Keys.StorageLocalBasePath)
storage, err := kv.OpenFile(storageBasePath, nil) storage, err := kv.OpenFile(storageBasePath, nil)
if err != nil { if err != nil {
return fmt.Errorf("error creating storage backend: %s", err) return fmt.Errorf("error creating storage backend: %s", err)

View File

@ -68,10 +68,7 @@ func Media(cmd *cobra.Command, values config.Values) {
// Storage attaches flags pertaining to storage config. // Storage attaches flags pertaining to storage config.
func Storage(cmd *cobra.Command, values config.Values) { func Storage(cmd *cobra.Command, values config.Values) {
cmd.Flags().String(config.Keys.StorageBackend, values.StorageBackend, usage.StorageBackend) cmd.Flags().String(config.Keys.StorageBackend, values.StorageBackend, usage.StorageBackend)
cmd.Flags().String(config.Keys.StorageBasePath, values.StorageBasePath, usage.StorageBasePath) cmd.Flags().String(config.Keys.StorageLocalBasePath, values.StorageLocalBasePath, usage.StorageLocalBasePath)
cmd.Flags().String(config.Keys.StorageServeProtocol, values.StorageServeProtocol, usage.StorageServeProtocol)
cmd.Flags().String(config.Keys.StorageServeHost, values.StorageServeHost, usage.StorageServeHost)
cmd.Flags().String(config.Keys.StorageServeBasePath, values.StorageServeBasePath, usage.StorageServeBasePath)
} }
// Statuses attaches flags pertaining to statuses config. // Statuses attaches flags pertaining to statuses config.

View File

@ -48,10 +48,7 @@ var usage = config.KeyNames{
MediaDescriptionMinChars: "Min required chars for an image description", MediaDescriptionMinChars: "Min required chars for an image description",
MediaDescriptionMaxChars: "Max permitted chars for an image description", MediaDescriptionMaxChars: "Max permitted chars for an image description",
StorageBackend: "Storage backend to use for media attachments", StorageBackend: "Storage backend to use for media attachments",
StorageBasePath: "Full path to an already-created directory where gts should store/retrieve media files. Subfolders will be created within this dir.", StorageLocalBasePath: "Full path to an already-created directory where gts should store/retrieve media files. Subfolders will be created within this dir.",
StorageServeProtocol: "Protocol to use for serving media attachments (use https if storage is local)",
StorageServeHost: "Hostname to serve media attachments from (use the same value as host if storage is local)",
StorageServeBasePath: "Path to append to protocol and hostname to create the base path from which media files will be served (default will mostly be fine)",
StatusesMaxChars: "Max permitted characters for posted statuses", StatusesMaxChars: "Max permitted characters for posted statuses",
StatusesCWMaxChars: "Max permitted characters for content/spoiler warnings on statuses", StatusesCWMaxChars: "Max permitted characters for content/spoiler warnings on statuses",
StatusesPollMaxOptions: "Max amount of options permitted on a poll", StatusesPollMaxOptions: "Max amount of options permitted on a poll",

View File

@ -20,25 +20,5 @@ storage-backend: "local"
# this directly, and create new subdirectories and files with in. # this directly, and create new subdirectories and files with in.
# Examples: ["/home/gotosocial/storage", "/opt/gotosocial/datastorage"] # Examples: ["/home/gotosocial/storage", "/opt/gotosocial/datastorage"]
# Default: "/gotosocial/storage" # Default: "/gotosocial/storage"
storage-base-path: "/gotosocial/storage" storage-local-base-path: "/gotosocial/storage"
# String. Protocol to use for serving stored files.
# It's very unlikely that you'll need to change this ever, but there might be edge cases.
# Examples: ["http", "https"]
storage-serve-protocol: "https"
# String. Host for serving stored files.
# If you're using local storage, this should be THE SAME as the value you've set for Host, above.
# It should only be a different value if you're serving stored files from a host
# other than the one your instance is running on.
# Examples: ["localhost", "example.org"]
# Default: "localhost" -- you should absolutely change this.
storage-serve-host: "localhost"
# String. Base path for serving stored files. This will be added to serveHost and serveProtocol
# to form the prefix url of your stored files. Eg., https://example.org/fileserver/.....
# It's unlikely that you will need to change this.
# Examples: ["/fileserver", "/media"]
# Default: "/fileserver"
storage-serve-base-path: "/fileserver"
``` ```

View File

@ -48,11 +48,10 @@ Now open the file in your text editor of choice so that you can set some importa
* Set `host` to whatever hostname you're going to be running the server on (eg., `example.org`). * Set `host` to whatever hostname you're going to be running the server on (eg., `example.org`).
* Set `port` to `443`. * Set `port` to `443`.
* Set `db.type` to `sqlite`. * Set `db-type` to `sqlite`.
* Set `db.address` to `sqlite.db`. * Set `db-address` to `sqlite.db`.
* Set `storage.basePath` to the storage directory you created above (eg., `/gotosocial/storage`). * Set `storage-local-base-path` to the storage directory you created above (eg., `/gotosocial/storage`).
* Set `storage.serveHost` to whatever you set the `host` value to above (eg., `example.org`). * Set `letsencrypt-cert-dir` to the certificate storage directory you created above (eg., `/gotosocial/storage/certs`).
* Set `letsEncrypt.certDir` to the certificate storage directory you created above (eg., `/gotosocial/storage/certs`).
The above options assume you're using SQLite as your database. If you want to use Postgres instead, see [here](../configuration/database.md) for the config options. The above options assume you're using SQLite as your database. If you want to use Postgres instead, see [here](../configuration/database.md) for the config options.

View File

@ -210,30 +210,10 @@ storage-backend: "local"
# String. Directory to use as a base path for storing files. # String. Directory to use as a base path for storing files.
# Make sure whatever user/group gotosocial is running as has permission to access # Make sure whatever user/group gotosocial is running as has permission to access
# this directly, and create new subdirectories and files with in. # this directory, and create new subdirectories and files within it.
# Examples: ["/home/gotosocial/storage", "/opt/gotosocial/datastorage"] # Examples: ["/home/gotosocial/storage", "/opt/gotosocial/datastorage"]
# Default: "/gotosocial/storage" # Default: "/gotosocial/storage"
storage-base-path: "/gotosocial/storage" storage-local-base-path: "/gotosocial/storage"
# String. Protocol to use for serving stored files.
# It's very unlikely that you'll need to change this ever, but there might be edge cases.
# Examples: ["http", "https"]
storage-serve-protocol: "https"
# String. Host for serving stored files.
# If you're using local storage, this should be THE SAME as the value you've set for Host, above.
# It should only be a different value if you're serving stored files from a host
# other than the one your instance is running on.
# Examples: ["localhost", "example.org"]
# Default: "localhost" -- you should absolutely change this.
storage-serve-host: "localhost"
# String. Base path for serving stored files. This will be added to serveHost and serveProtocol
# to form the prefix url of your stored files. Eg., https://example.org/fileserver/.....
# It's unlikely that you will need to change this.
# Examples: ["/fileserver", "/media"]
# Default: "/fileserver"
storage-serve-base-path: "/fileserver"
########################### ###########################
##### STATUSES CONFIG ##### ##### STATUSES CONFIG #####

41
internal/ap/contextkey.go Normal file
View File

@ -0,0 +1,41 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ap
// ContextKey is a type used specifically for settings values on contexts within go-fed AP request chains
type ContextKey string
const (
// ContextActivity can be used to set and retrieve the actual go-fed pub.Activity within a context.
ContextActivity ContextKey = "activity"
// ContextReceivingAccount can be used the set and retrieve the account being interacted with / receiving an activity in their inbox.
ContextReceivingAccount ContextKey = "account"
// ContextRequestingAccount can be used to set and retrieve the account of an incoming federation request.
// This will often be the actor of the instance that's posting the request.
ContextRequestingAccount ContextKey = "requestingAccount"
// ContextRequestingActorIRI can be used to set and retrieve the actor of an incoming federation request.
// This will usually be the owner of whatever activity is being posted.
ContextRequestingActorIRI ContextKey = "requestingActorIRI"
// ContextRequestingPublicKeyVerifier can be used to set and retrieve the public key verifier of an incoming federation request.
ContextRequestingPublicKeyVerifier ContextKey = "requestingPublicKeyVerifier"
// ContextRequestingPublicKeySignature can be used to set and retrieve the value of the signature header of an incoming federation request.
ContextRequestingPublicKeySignature ContextKey = "requestingPublicKeySignature"
// ContextFromFederatorChan can be used to pass a pointer to the fromFederator channel into the federator for use in callbacks.
ContextFromFederatorChan ContextKey = "fromFederatorChan"
)

View File

@ -22,14 +22,15 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/api" "github.com/superseriousbusiness/gotosocial/internal/api"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/processing" "github.com/superseriousbusiness/gotosocial/internal/processing"
"github.com/superseriousbusiness/gotosocial/internal/router" "github.com/superseriousbusiness/gotosocial/internal/router"
"github.com/superseriousbusiness/gotosocial/internal/uris"
) )
const ( const (
// FileServeBasePath forms the first part of the fileserver path.
FileServeBasePath = "/" + uris.FileserverPath
// AccountIDKey is the url key for account id (an account ulid) // AccountIDKey is the url key for account id (an account ulid)
AccountIDKey = "account_id" AccountIDKey = "account_id"
// MediaTypeKey is the url key for media type (usually something like attachment or header etc) // MediaTypeKey is the url key for media type (usually something like attachment or header etc)
@ -43,20 +44,20 @@ const (
// FileServer implements the RESTAPIModule interface. // FileServer implements the RESTAPIModule interface.
// The goal here is to serve requested media files if the gotosocial server is configured to use local storage. // The goal here is to serve requested media files if the gotosocial server is configured to use local storage.
type FileServer struct { type FileServer struct {
processor processing.Processor processor processing.Processor
storageServeBasePath string
} }
// New returns a new fileServer module // New returns a new fileServer module
func New(processor processing.Processor) api.ClientModule { func New(processor processing.Processor) api.ClientModule {
return &FileServer{ return &FileServer{
processor: processor, processor: processor,
storageServeBasePath: viper.GetString(config.Keys.StorageServeBasePath),
} }
} }
// Route satisfies the RESTAPIModule interface // Route satisfies the RESTAPIModule interface
func (m *FileServer) Route(s router.Router) error { func (m *FileServer) Route(s router.Router) error {
s.AttachHandler(http.MethodGet, fmt.Sprintf("%s/:%s/:%s/:%s/:%s", m.storageServeBasePath, AccountIDKey, MediaTypeKey, MediaSizeKey, FileNameKey), m.ServeFile) // something like "/fileserver/:account_id/:media_type/:media_size/:file_name"
fileServePath := fmt.Sprintf("%s/:%s/:%s/:%s/:%s", FileServeBasePath, AccountIDKey, MediaTypeKey, MediaSizeKey, FileNameKey)
s.AttachHandler(http.MethodGet, fileServePath, m.ServeFile)
return nil return nil
} }

View File

@ -134,11 +134,11 @@ func (suite *ServeFileTestSuite) TestServeOriginalFileSuccessful() {
}, },
gin.Param{ gin.Param{
Key: fileserver.MediaTypeKey, Key: fileserver.MediaTypeKey,
Value: string(media.Attachment), Value: string(media.TypeAttachment),
}, },
gin.Param{ gin.Param{
Key: fileserver.MediaSizeKey, Key: fileserver.MediaSizeKey,
Value: string(media.Original), Value: string(media.SizeOriginal),
}, },
gin.Param{ gin.Param{
Key: fileserver.FileNameKey, Key: fileserver.FileNameKey,

View File

@ -22,21 +22,21 @@ import (
"context" "context"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/ap"
) )
// transferContext transfers the signature verifier and signature from the gin context to the request context // transferContext transfers the signature verifier and signature from the gin context to the request context
func transferContext(c *gin.Context) context.Context { func transferContext(c *gin.Context) context.Context {
ctx := c.Request.Context() ctx := c.Request.Context()
verifier, signed := c.Get(string(util.APRequestingPublicKeyVerifier)) verifier, signed := c.Get(string(ap.ContextRequestingPublicKeyVerifier))
if signed { if signed {
ctx = context.WithValue(ctx, util.APRequestingPublicKeyVerifier, verifier) ctx = context.WithValue(ctx, ap.ContextRequestingPublicKeyVerifier, verifier)
} }
signature, signed := c.Get(string(util.APRequestingPublicKeySignature)) signature, signed := c.Get(string(ap.ContextRequestingPublicKeySignature))
if signed { if signed {
ctx = context.WithValue(ctx, util.APRequestingPublicKeySignature, signature) ctx = context.WithValue(ctx, ap.ContextRequestingPublicKeySignature, signature)
} }
return ctx return ctx

View File

@ -24,7 +24,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/api" "github.com/superseriousbusiness/gotosocial/internal/api"
"github.com/superseriousbusiness/gotosocial/internal/processing" "github.com/superseriousbusiness/gotosocial/internal/processing"
"github.com/superseriousbusiness/gotosocial/internal/router" "github.com/superseriousbusiness/gotosocial/internal/router"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
const ( const (
@ -42,23 +42,23 @@ const (
PageKey = "page" PageKey = "page"
// UsersBasePath is the base path for serving information about Users eg https://example.org/users // UsersBasePath is the base path for serving information about Users eg https://example.org/users
UsersBasePath = "/" + util.UsersPath UsersBasePath = "/" + uris.UsersPath
// UsersBasePathWithUsername is just the users base path with the Username key in it. // UsersBasePathWithUsername is just the users base path with the Username key in it.
// Use this anywhere you need to know the username of the user being queried. // Use this anywhere you need to know the username of the user being queried.
// Eg https://example.org/users/:username // Eg https://example.org/users/:username
UsersBasePathWithUsername = UsersBasePath + "/:" + UsernameKey UsersBasePathWithUsername = UsersBasePath + "/:" + UsernameKey
// UsersPublicKeyPath is a path to a user's public key, for serving bare minimum AP representations. // UsersPublicKeyPath is a path to a user's public key, for serving bare minimum AP representations.
UsersPublicKeyPath = UsersBasePathWithUsername + "/" + util.PublicKeyPath UsersPublicKeyPath = UsersBasePathWithUsername + "/" + uris.PublicKeyPath
// UsersInboxPath is for serving POST requests to a user's inbox with the given username key. // UsersInboxPath is for serving POST requests to a user's inbox with the given username key.
UsersInboxPath = UsersBasePathWithUsername + "/" + util.InboxPath UsersInboxPath = UsersBasePathWithUsername + "/" + uris.InboxPath
// UsersOutboxPath is for serving GET requests to a user's outbox with the given username key. // UsersOutboxPath is for serving GET requests to a user's outbox with the given username key.
UsersOutboxPath = UsersBasePathWithUsername + "/" + util.OutboxPath UsersOutboxPath = UsersBasePathWithUsername + "/" + uris.OutboxPath
// UsersFollowersPath is for serving GET request's to a user's followers list, with the given username key. // UsersFollowersPath is for serving GET request's to a user's followers list, with the given username key.
UsersFollowersPath = UsersBasePathWithUsername + "/" + util.FollowersPath UsersFollowersPath = UsersBasePathWithUsername + "/" + uris.FollowersPath
// UsersFollowingPath is for serving GET request's to a user's following list, with the given username key. // UsersFollowingPath is for serving GET request's to a user's following list, with the given username key.
UsersFollowingPath = UsersBasePathWithUsername + "/" + util.FollowingPath UsersFollowingPath = UsersBasePathWithUsername + "/" + uris.FollowingPath
// UsersStatusPath is for serving GET requests to a particular status by a user, with the given username key and status ID // UsersStatusPath is for serving GET requests to a particular status by a user, with the given username key and status ID
UsersStatusPath = UsersBasePathWithUsername + "/" + util.StatusesPath + "/:" + StatusIDKey UsersStatusPath = UsersBasePathWithUsername + "/" + uris.StatusesPath + "/:" + StatusIDKey
// UsersStatusRepliesPath is for serving the replies collection of a status. // UsersStatusRepliesPath is for serving the replies collection of a status.
UsersStatusRepliesPath = UsersStatusPath + "/replies" UsersStatusRepliesPath = UsersStatusPath + "/replies"
) )

View File

@ -27,9 +27,9 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/superseriousbusiness/gotosocial/internal/api" "github.com/superseriousbusiness/gotosocial/internal/api"
"github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/util"
) )
// WebfingerGETRequest swagger:operation GET /.well-known/webfinger webfingerGet // WebfingerGETRequest swagger:operation GET /.well-known/webfinger webfingerGet
@ -107,9 +107,9 @@ func (m *Module) WebfingerGETRequest(c *gin.Context) {
// transfer the signature verifier from the gin context to the request context // transfer the signature verifier from the gin context to the request context
ctx := c.Request.Context() ctx := c.Request.Context()
verifier, signed := c.Get(string(util.APRequestingPublicKeyVerifier)) verifier, signed := c.Get(string(ap.ContextRequestingPublicKeyVerifier))
if signed { if signed {
ctx = context.WithValue(ctx, util.APRequestingPublicKeyVerifier, verifier) ctx = context.WithValue(ctx, ap.ContextRequestingPublicKeyVerifier, verifier)
} }
resp, err := m.processor.GetWebfingerAccount(ctx, username) resp, err := m.processor.GetWebfingerAccount(ctx, username)

View File

@ -1,13 +1,14 @@
package security package security
import ( import (
"github.com/sirupsen/logrus"
"net/http" "net/http"
"net/url" "net/url"
"github.com/sirupsen/logrus"
"github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/go-fed/httpsig" "github.com/go-fed/httpsig"
"github.com/superseriousbusiness/gotosocial/internal/util"
) )
// SignatureCheck checks whether an incoming http request has been signed. If so, it will check if the domain // SignatureCheck checks whether an incoming http request has been signed. If so, it will check if the domain
@ -42,10 +43,10 @@ func (m *Module) SignatureCheck(c *gin.Context) {
} }
// set the verifier and signature on the context here to save some work further down the line // set the verifier and signature on the context here to save some work further down the line
c.Set(string(util.APRequestingPublicKeyVerifier), verifier) c.Set(string(ap.ContextRequestingPublicKeyVerifier), verifier)
signature := c.GetHeader("Signature") signature := c.GetHeader("Signature")
if signature != "" { if signature != "" {
c.Set(string(util.APRequestingPublicKeySignature), signature) c.Set(string(ap.ContextRequestingPublicKeySignature), signature)
} }
} }
} }

View File

@ -55,10 +55,7 @@ var Defaults = Values{
MediaDescriptionMaxChars: 500, MediaDescriptionMaxChars: 500,
StorageBackend: "local", StorageBackend: "local",
StorageBasePath: "/gotosocial/storage", StorageLocalBasePath: "/gotosocial/storage",
StorageServeProtocol: "https",
StorageServeHost: "localhost",
StorageServeBasePath: "/fileserver",
StatusesMaxChars: 5000, StatusesMaxChars: 5000,
StatusesCWMaxChars: 100, StatusesCWMaxChars: 100,

View File

@ -61,10 +61,7 @@ type KeyNames struct {
// storage // storage
StorageBackend string StorageBackend string
StorageBasePath string StorageLocalBasePath string
StorageServeProtocol string
StorageServeHost string
StorageServeBasePath string
// statuses // statuses
StatusesMaxChars string StatusesMaxChars string
@ -143,10 +140,7 @@ var Keys = KeyNames{
MediaDescriptionMaxChars: "media-description-max-chars", MediaDescriptionMaxChars: "media-description-max-chars",
StorageBackend: "storage-backend", StorageBackend: "storage-backend",
StorageBasePath: "storage-base-path", StorageLocalBasePath: "storage-local-base-path",
StorageServeProtocol: "storage-serve-protocol",
StorageServeHost: "storage-serve-host",
StorageServeBasePath: "storage-serve-base-path",
StatusesMaxChars: "statuses-max-chars", StatusesMaxChars: "statuses-max-chars",
StatusesCWMaxChars: "statuses-cw-max-chars", StatusesCWMaxChars: "statuses-cw-max-chars",

View File

@ -53,10 +53,7 @@ type Values struct {
MediaDescriptionMaxChars int MediaDescriptionMaxChars int
StorageBackend string StorageBackend string
StorageBasePath string StorageLocalBasePath string
StorageServeProtocol string
StorageServeHost string
StorageServeBasePath string
StatusesMaxChars int StatusesMaxChars int
StatusesCWMaxChars int StatusesCWMaxChars int

View File

@ -37,7 +37,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
) )
@ -100,30 +100,30 @@ func (a *adminDB) NewSignup(ctx context.Context, username string, reason string,
WhereGroup(" AND ", whereEmptyOrNull("domain")). WhereGroup(" AND ", whereEmptyOrNull("domain")).
Scan(ctx) Scan(ctx)
if err != nil { if err != nil {
// we just don't have an account yet create one // we just don't have an account yet so create one
newAccountURIs := util.GenerateURIsForAccount(username) accountURIs := uris.GenerateURIsForAccount(username)
newAccountID, err := id.NewRandomULID() accountID, err := id.NewRandomULID()
if err != nil { if err != nil {
return nil, err return nil, err
} }
acct = &gtsmodel.Account{ acct = &gtsmodel.Account{
ID: newAccountID, ID: accountID,
Username: username, Username: username,
DisplayName: username, DisplayName: username,
Reason: reason, Reason: reason,
Privacy: gtsmodel.VisibilityDefault, Privacy: gtsmodel.VisibilityDefault,
URL: newAccountURIs.UserURL, URL: accountURIs.UserURL,
PrivateKey: key, PrivateKey: key,
PublicKey: &key.PublicKey, PublicKey: &key.PublicKey,
PublicKeyURI: newAccountURIs.PublicKeyURI, PublicKeyURI: accountURIs.PublicKeyURI,
ActorType: ap.ActorPerson, ActorType: ap.ActorPerson,
URI: newAccountURIs.UserURI, URI: accountURIs.UserURI,
InboxURI: newAccountURIs.InboxURI, InboxURI: accountURIs.InboxURI,
OutboxURI: newAccountURIs.OutboxURI, OutboxURI: accountURIs.OutboxURI,
FollowersURI: newAccountURIs.FollowersURI, FollowersURI: accountURIs.FollowersURI,
FollowingURI: newAccountURIs.FollowingURI, FollowingURI: accountURIs.FollowingURI,
FeaturedCollectionURI: newAccountURIs.CollectionURI, FeaturedCollectionURI: accountURIs.CollectionURI,
} }
if _, err = a.conn. if _, err = a.conn.
NewInsert(). NewInsert().
@ -204,7 +204,7 @@ func (a *adminDB) CreateInstanceAccount(ctx context.Context) db.Error {
return err return err
} }
newAccountURIs := util.GenerateURIsForAccount(username) newAccountURIs := uris.GenerateURIsForAccount(username)
acct := &gtsmodel.Account{ acct := &gtsmodel.Account{
ID: aID, ID: aID,
Username: username, Username: username,

View File

@ -35,10 +35,10 @@ import (
"github.com/superseriousbusiness/activity/pub" "github.com/superseriousbusiness/activity/pub"
"github.com/superseriousbusiness/activity/streams" "github.com/superseriousbusiness/activity/streams"
"github.com/superseriousbusiness/activity/streams/vocab" "github.com/superseriousbusiness/activity/streams/vocab"
"github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/util"
) )
/* /*
@ -123,7 +123,7 @@ func (f *federator) AuthenticateFederatedRequest(ctx context.Context, requestedU
var err error var err error
// thanks to signaturecheck.go in the security package, we should already have a signature verifier set on the context // thanks to signaturecheck.go in the security package, we should already have a signature verifier set on the context
vi := ctx.Value(util.APRequestingPublicKeyVerifier) vi := ctx.Value(ap.ContextRequestingPublicKeyVerifier)
if vi == nil { if vi == nil {
l.Debug("request wasn't signed") l.Debug("request wasn't signed")
return nil, false, nil // request wasn't signed return nil, false, nil // request wasn't signed
@ -136,7 +136,7 @@ func (f *federator) AuthenticateFederatedRequest(ctx context.Context, requestedU
} }
// we should have the signature itself set too // we should have the signature itself set too
si := ctx.Value(util.APRequestingPublicKeySignature) si := ctx.Value(ap.ContextRequestingPublicKeySignature)
if vi == nil { if vi == nil {
l.Debug("request wasn't signed") l.Debug("request wasn't signed")
return nil, false, nil // request wasn't signed return nil, false, nil // request wasn't signed

View File

@ -27,7 +27,7 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/ap" "github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
// DereferenceThread takes a statusable (something that has withReplies and withInReplyTo), // DereferenceThread takes a statusable (something that has withReplies and withInReplyTo),
@ -85,7 +85,7 @@ func (d *deref) iterateAncestors(ctx context.Context, username string, statusIRI
l.Debug("iri belongs to us, moving up to next ancestor") l.Debug("iri belongs to us, moving up to next ancestor")
// since this is our status, we know we can extract the id from the status path // since this is our status, we know we can extract the id from the status path
_, id, err := util.ParseStatusesPath(&statusIRI) _, id, err := uris.ParseStatusesPath(&statusIRI)
if err != nil { if err != nil {
return err return err
} }

View File

@ -29,7 +29,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/messages" "github.com/superseriousbusiness/gotosocial/internal/messages"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
func (f *federatingDB) Accept(ctx context.Context, accept vocab.ActivityStreamsAccept) error { func (f *federatingDB) Accept(ctx context.Context, accept vocab.ActivityStreamsAccept) error {
@ -66,7 +66,7 @@ func (f *federatingDB) Accept(ctx context.Context, accept vocab.ActivityStreamsA
if iter.IsIRI() { if iter.IsIRI() {
// we have just the URI of whatever is being accepted, so we need to find out what it is // we have just the URI of whatever is being accepted, so we need to find out what it is
acceptedObjectIRI := iter.GetIRI() acceptedObjectIRI := iter.GetIRI()
if util.IsFollowPath(acceptedObjectIRI) { if uris.IsFollowPath(acceptedObjectIRI) {
// ACCEPT FOLLOW // ACCEPT FOLLOW
gtsFollowRequest := &gtsmodel.FollowRequest{} gtsFollowRequest := &gtsmodel.FollowRequest{}
if err := f.db.GetWhere(ctx, []db.Where{{Key: "uri", Value: acceptedObjectIRI.String()}}, gtsFollowRequest); err != nil { if err := f.db.GetWhere(ctx, []db.Where{{Key: "uri", Value: acceptedObjectIRI.String()}}, gtsFollowRequest); err != nil {

View File

@ -22,12 +22,12 @@ import (
"context" "context"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/federation/federatingdb" "github.com/superseriousbusiness/gotosocial/internal/federation/federatingdb"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/messages" "github.com/superseriousbusiness/gotosocial/internal/messages"
"github.com/superseriousbusiness/gotosocial/internal/typeutils" "github.com/superseriousbusiness/gotosocial/internal/typeutils"
"github.com/superseriousbusiness/gotosocial/internal/util"
"github.com/superseriousbusiness/gotosocial/testrig" "github.com/superseriousbusiness/gotosocial/testrig"
) )
@ -75,8 +75,8 @@ func (suite *FederatingDBTestSuite) TearDownTest() {
func createTestContext(receivingAccount *gtsmodel.Account, requestingAccount *gtsmodel.Account, fromFederatorChan chan messages.FromFederator) context.Context { func createTestContext(receivingAccount *gtsmodel.Account, requestingAccount *gtsmodel.Account, fromFederatorChan chan messages.FromFederator) context.Context {
ctx := context.Background() ctx := context.Background()
ctx = context.WithValue(ctx, util.APReceivingAccount, receivingAccount) ctx = context.WithValue(ctx, ap.ContextReceivingAccount, receivingAccount)
ctx = context.WithValue(ctx, util.APRequestingAccount, requestingAccount) ctx = context.WithValue(ctx, ap.ContextRequestingAccount, requestingAccount)
ctx = context.WithValue(ctx, util.APFromFederatorChanKey, fromFederatorChan) ctx = context.WithValue(ctx, ap.ContextFromFederatorChan, fromFederatorChan)
return ctx return ctx
} }

View File

@ -25,7 +25,7 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/superseriousbusiness/activity/streams/vocab" "github.com/superseriousbusiness/activity/streams/vocab"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
// Get returns the database entry for the specified id. // Get returns the database entry for the specified id.
@ -40,7 +40,7 @@ func (f *federatingDB) Get(ctx context.Context, id *url.URL) (value vocab.Type,
) )
l.Debug("entering Get") l.Debug("entering Get")
if util.IsUserPath(id) { if uris.IsUserPath(id) {
acct, err := f.db.GetAccountByURI(ctx, id.String()) acct, err := f.db.GetAccountByURI(ctx, id.String())
if err != nil { if err != nil {
return nil, err return nil, err
@ -48,7 +48,7 @@ func (f *federatingDB) Get(ctx context.Context, id *url.URL) (value vocab.Type,
return f.typeConverter.AccountToAS(ctx, acct) return f.typeConverter.AccountToAS(ctx, acct)
} }
if util.IsStatusesPath(id) { if uris.IsStatusesPath(id) {
status, err := f.db.GetStatusByURI(ctx, id.String()) status, err := f.db.GetStatusByURI(ctx, id.String())
if err != nil { if err != nil {
return nil, err return nil, err
@ -56,11 +56,11 @@ func (f *federatingDB) Get(ctx context.Context, id *url.URL) (value vocab.Type,
return f.typeConverter.StatusToAS(ctx, status) return f.typeConverter.StatusToAS(ctx, status)
} }
if util.IsFollowersPath(id) { if uris.IsFollowersPath(id) {
return f.Followers(ctx, id) return f.Followers(ctx, id)
} }
if util.IsFollowingPath(id) { if uris.IsFollowingPath(id) {
return f.Following(ctx, id) return f.Following(ctx, id)
} }

View File

@ -28,7 +28,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
// Owns returns true if the IRI belongs to this instance, and if // Owns returns true if the IRI belongs to this instance, and if
@ -52,8 +52,8 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) {
// apparently it belongs to this host, so what *is* it? // apparently it belongs to this host, so what *is* it?
// check if it's a status, eg /users/example_username/statuses/SOME_UUID_OF_A_STATUS // check if it's a status, eg /users/example_username/statuses/SOME_UUID_OF_A_STATUS
if util.IsStatusesPath(id) { if uris.IsStatusesPath(id) {
_, uid, err := util.ParseStatusesPath(id) _, uid, err := uris.ParseStatusesPath(id)
if err != nil { if err != nil {
return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err) return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err)
} }
@ -69,8 +69,8 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) {
return status.Local, nil return status.Local, nil
} }
if util.IsUserPath(id) { if uris.IsUserPath(id) {
username, err := util.ParseUserPath(id) username, err := uris.ParseUserPath(id)
if err != nil { if err != nil {
return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err) return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err)
} }
@ -86,8 +86,8 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) {
return true, nil return true, nil
} }
if util.IsFollowersPath(id) { if uris.IsFollowersPath(id) {
username, err := util.ParseFollowersPath(id) username, err := uris.ParseFollowersPath(id)
if err != nil { if err != nil {
return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err) return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err)
} }
@ -103,8 +103,8 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) {
return true, nil return true, nil
} }
if util.IsFollowingPath(id) { if uris.IsFollowingPath(id) {
username, err := util.ParseFollowingPath(id) username, err := uris.ParseFollowingPath(id)
if err != nil { if err != nil {
return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err) return false, fmt.Errorf("error parsing statuses path for url %s: %s", id.String(), err)
} }
@ -120,8 +120,8 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) {
return true, nil return true, nil
} }
if util.IsLikePath(id) { if uris.IsLikePath(id) {
username, likeID, err := util.ParseLikedPath(id) username, likeID, err := uris.ParseLikedPath(id)
if err != nil { if err != nil {
return false, fmt.Errorf("error parsing like path for url %s: %s", id.String(), err) return false, fmt.Errorf("error parsing like path for url %s: %s", id.String(), err)
} }
@ -145,8 +145,8 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) {
return true, nil return true, nil
} }
if util.IsBlockPath(id) { if uris.IsBlockPath(id) {
username, blockID, err := util.ParseBlockPath(id) username, blockID, err := uris.ParseBlockPath(id)
if err != nil { if err != nil {
return false, fmt.Errorf("error parsing block path for url %s: %s", id.String(), err) return false, fmt.Errorf("error parsing block path for url %s: %s", id.String(), err)
} }

View File

@ -28,7 +28,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/ap" "github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
func (f *federatingDB) Reject(ctx context.Context, reject vocab.ActivityStreamsReject) error { func (f *federatingDB) Reject(ctx context.Context, reject vocab.ActivityStreamsReject) error {
@ -65,7 +65,7 @@ func (f *federatingDB) Reject(ctx context.Context, reject vocab.ActivityStreamsR
if iter.IsIRI() { if iter.IsIRI() {
// we have just the URI of whatever is being rejected, so we need to find out what it is // we have just the URI of whatever is being rejected, so we need to find out what it is
rejectedObjectIRI := iter.GetIRI() rejectedObjectIRI := iter.GetIRI()
if util.IsFollowPath(rejectedObjectIRI) { if uris.IsFollowPath(rejectedObjectIRI) {
// REJECT FOLLOW // REJECT FOLLOW
gtsFollowRequest := &gtsmodel.FollowRequest{} gtsFollowRequest := &gtsmodel.FollowRequest{}
if err := f.db.GetWhere(ctx, []db.Where{{Key: "uri", Value: rejectedObjectIRI.String()}}, gtsFollowRequest); err != nil { if err := f.db.GetWhere(ctx, []db.Where{{Key: "uri", Value: rejectedObjectIRI.String()}}, gtsFollowRequest); err != nil {

View File

@ -27,7 +27,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/messages" "github.com/superseriousbusiness/gotosocial/internal/messages"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
"github.com/superseriousbusiness/gotosocial/testrig" "github.com/superseriousbusiness/gotosocial/testrig"
) )
@ -48,7 +48,7 @@ func (suite *RejectTestSuite) TestRejectFollowRequest() {
ID: "01FJ1S8DX3STJJ6CEYPMZ1M0R3", ID: "01FJ1S8DX3STJJ6CEYPMZ1M0R3",
CreatedAt: time.Now(), CreatedAt: time.Now(),
UpdatedAt: time.Now(), UpdatedAt: time.Now(),
URI: util.GenerateURIForFollow(followingAccount.Username, "01FJ1S8DX3STJJ6CEYPMZ1M0R3"), URI: uris.GenerateURIForFollow(followingAccount.Username, "01FJ1S8DX3STJJ6CEYPMZ1M0R3"),
AccountID: followingAccount.ID, AccountID: followingAccount.ID,
TargetAccountID: followedAccount.ID, TargetAccountID: followedAccount.ID,
} }

View File

@ -30,7 +30,6 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/messages" "github.com/superseriousbusiness/gotosocial/internal/messages"
"github.com/superseriousbusiness/gotosocial/internal/util"
) )
// Update sets an existing entry to the database based on the value's // Update sets an existing entry to the database based on the value's
@ -66,7 +65,7 @@ func (f *federatingDB) Update(ctx context.Context, asType vocab.Type) error {
return nil return nil
} }
requestingAcctI := ctx.Value(util.APRequestingAccount) requestingAcctI := ctx.Value(ap.ContextRequestingAccount)
if requestingAcctI == nil { if requestingAcctI == nil {
l.Error("UPDATE: requesting account wasn't set on context") l.Error("UPDATE: requesting account wasn't set on context")
} }

View File

@ -35,7 +35,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/internal/messages" "github.com/superseriousbusiness/gotosocial/internal/messages"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
func sameActor(activityActor vocab.ActivityStreamsActorProperty, followActor vocab.ActivityStreamsActorProperty) bool { func sameActor(activityActor vocab.ActivityStreamsActorProperty, followActor vocab.ActivityStreamsActorProperty) bool {
@ -106,7 +106,7 @@ func (f *federatingDB) NewID(ctx context.Context, t vocab.Type) (idURL *url.URL,
if err != nil { if err != nil {
return nil, err return nil, err
} }
return url.Parse(util.GenerateURIForFollow(actorAccount.Username, newID)) return url.Parse(uris.GenerateURIForFollow(actorAccount.Username, newID))
} }
} }
} }
@ -241,7 +241,7 @@ func (f *federatingDB) ActorForInbox(ctx context.Context, inboxIRI *url.URL) (ac
func (f *federatingDB) getAccountForIRI(ctx context.Context, iri *url.URL) (account *gtsmodel.Account, err error) { func (f *federatingDB) getAccountForIRI(ctx context.Context, iri *url.URL) (account *gtsmodel.Account, err error) {
acct := &gtsmodel.Account{} acct := &gtsmodel.Account{}
if util.IsInboxPath(iri) { if uris.IsInboxPath(iri) {
if err := f.db.GetWhere(ctx, []db.Where{{Key: "inbox_uri", Value: iri.String()}}, acct); err != nil { if err := f.db.GetWhere(ctx, []db.Where{{Key: "inbox_uri", Value: iri.String()}}, acct); err != nil {
if err == db.ErrNoEntries { if err == db.ErrNoEntries {
return nil, fmt.Errorf("no actor found that corresponds to inbox %s", iri.String()) return nil, fmt.Errorf("no actor found that corresponds to inbox %s", iri.String())
@ -251,7 +251,7 @@ func (f *federatingDB) getAccountForIRI(ctx context.Context, iri *url.URL) (acco
return acct, nil return acct, nil
} }
if util.IsOutboxPath(iri) { if uris.IsOutboxPath(iri) {
if err := f.db.GetWhere(ctx, []db.Where{{Key: "outbox_uri", Value: iri.String()}}, acct); err != nil { if err := f.db.GetWhere(ctx, []db.Where{{Key: "outbox_uri", Value: iri.String()}}, acct); err != nil {
if err == db.ErrNoEntries { if err == db.ErrNoEntries {
return nil, fmt.Errorf("no actor found that corresponds to outbox %s", iri.String()) return nil, fmt.Errorf("no actor found that corresponds to outbox %s", iri.String())
@ -261,7 +261,7 @@ func (f *federatingDB) getAccountForIRI(ctx context.Context, iri *url.URL) (acco
return acct, nil return acct, nil
} }
if util.IsUserPath(iri) { if uris.IsUserPath(iri) {
if err := f.db.GetWhere(ctx, []db.Where{{Key: "uri", Value: iri.String()}}, acct); err != nil { if err := f.db.GetWhere(ctx, []db.Where{{Key: "uri", Value: iri.String()}}, acct); err != nil {
if err == db.ErrNoEntries { if err == db.ErrNoEntries {
return nil, fmt.Errorf("no actor found that corresponds to uri %s", iri.String()) return nil, fmt.Errorf("no actor found that corresponds to uri %s", iri.String())
@ -271,7 +271,7 @@ func (f *federatingDB) getAccountForIRI(ctx context.Context, iri *url.URL) (acco
return acct, nil return acct, nil
} }
if util.IsFollowersPath(iri) { if uris.IsFollowersPath(iri) {
if err := f.db.GetWhere(ctx, []db.Where{{Key: "followers_uri", Value: iri.String()}}, acct); err != nil { if err := f.db.GetWhere(ctx, []db.Where{{Key: "followers_uri", Value: iri.String()}}, acct); err != nil {
if err == db.ErrNoEntries { if err == db.ErrNoEntries {
return nil, fmt.Errorf("no actor found that corresponds to followers_uri %s", iri.String()) return nil, fmt.Errorf("no actor found that corresponds to followers_uri %s", iri.String())
@ -281,7 +281,7 @@ func (f *federatingDB) getAccountForIRI(ctx context.Context, iri *url.URL) (acco
return acct, nil return acct, nil
} }
if util.IsFollowingPath(iri) { if uris.IsFollowingPath(iri) {
if err := f.db.GetWhere(ctx, []db.Where{{Key: "following_uri", Value: iri.String()}}, acct); err != nil { if err := f.db.GetWhere(ctx, []db.Where{{Key: "following_uri", Value: iri.String()}}, acct); err != nil {
if err == db.ErrNoEntries { if err == db.ErrNoEntries {
return nil, fmt.Errorf("no actor found that corresponds to following_uri %s", iri.String()) return nil, fmt.Errorf("no actor found that corresponds to following_uri %s", iri.String())
@ -311,30 +311,30 @@ func (f *federatingDB) collectIRIs(ctx context.Context, iris []*url.URL) (vocab.
// - A channel that messages for the processor can be placed into. // - A channel that messages for the processor can be placed into.
// If a value is not present, nil will be returned for it. It's up to the caller to check this and respond appropriately. // If a value is not present, nil will be returned for it. It's up to the caller to check this and respond appropriately.
func extractFromCtx(ctx context.Context) (receivingAccount, requestingAccount *gtsmodel.Account, fromFederatorChan chan messages.FromFederator) { func extractFromCtx(ctx context.Context) (receivingAccount, requestingAccount *gtsmodel.Account, fromFederatorChan chan messages.FromFederator) {
receivingAccountI := ctx.Value(util.APReceivingAccount) receivingAccountI := ctx.Value(ap.ContextReceivingAccount)
if receivingAccountI != nil { if receivingAccountI != nil {
var ok bool var ok bool
receivingAccount, ok = receivingAccountI.(*gtsmodel.Account) receivingAccount, ok = receivingAccountI.(*gtsmodel.Account)
if !ok { if !ok {
logrus.Panicf("extractFromCtx: context entry with key %s could not be asserted to *gtsmodel.Account", util.APReceivingAccount) logrus.Panicf("extractFromCtx: context entry with key %s could not be asserted to *gtsmodel.Account", ap.ContextReceivingAccount)
} }
} }
requestingAcctI := ctx.Value(util.APRequestingAccount) requestingAcctI := ctx.Value(ap.ContextRequestingAccount)
if requestingAcctI != nil { if requestingAcctI != nil {
var ok bool var ok bool
requestingAccount, ok = requestingAcctI.(*gtsmodel.Account) requestingAccount, ok = requestingAcctI.(*gtsmodel.Account)
if !ok { if !ok {
logrus.Panicf("extractFromCtx: context entry with key %s could not be asserted to *gtsmodel.Account", util.APRequestingAccount) logrus.Panicf("extractFromCtx: context entry with key %s could not be asserted to *gtsmodel.Account", ap.ContextRequestingAccount)
} }
} }
fromFederatorChanI := ctx.Value(util.APFromFederatorChanKey) fromFederatorChanI := ctx.Value(ap.ContextFromFederatorChan)
if fromFederatorChanI != nil { if fromFederatorChanI != nil {
var ok bool var ok bool
fromFederatorChan, ok = fromFederatorChanI.(chan messages.FromFederator) fromFederatorChan, ok = fromFederatorChanI.(chan messages.FromFederator)
if !ok { if !ok {
logrus.Panicf("extractFromCtx: context entry with key %s could not be asserted to chan messages.FromFederator", util.APFromFederatorChanKey) logrus.Panicf("extractFromCtx: context entry with key %s could not be asserted to chan messages.FromFederator", ap.ContextFromFederatorChan)
} }
} }

View File

@ -29,9 +29,10 @@ import (
"github.com/superseriousbusiness/activity/pub" "github.com/superseriousbusiness/activity/pub"
"github.com/superseriousbusiness/activity/streams" "github.com/superseriousbusiness/activity/streams"
"github.com/superseriousbusiness/activity/streams/vocab" "github.com/superseriousbusiness/activity/streams/vocab"
"github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
/* /*
@ -73,7 +74,7 @@ func (f *federator) PostInboxRequestBodyHook(ctx context.Context, r *http.Reques
return nil, err return nil, err
} }
// set the activity on the context for use later on // set the activity on the context for use later on
return context.WithValue(ctx, util.APActivity, activity), nil return context.WithValue(ctx, ap.ContextActivity, activity), nil
} }
// AuthenticatePostInbox delegates the authentication of a POST to an // AuthenticatePostInbox delegates the authentication of a POST to an
@ -100,11 +101,11 @@ func (f *federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWr
}) })
l.Trace("received request to authenticate") l.Trace("received request to authenticate")
if !util.IsInboxPath(r.URL) { if !uris.IsInboxPath(r.URL) {
return nil, false, fmt.Errorf("path %s was not an inbox path", r.URL.String()) return nil, false, fmt.Errorf("path %s was not an inbox path", r.URL.String())
} }
username, err := util.ParseInboxPath(r.URL) username, err := uris.ParseInboxPath(r.URL)
if err != nil { if err != nil {
return nil, false, fmt.Errorf("could not parse path %s: %s", r.URL.String(), err) return nil, false, fmt.Errorf("could not parse path %s: %s", r.URL.String(), err)
} }
@ -157,8 +158,8 @@ func (f *federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWr
return nil, false, fmt.Errorf("couldn't get requesting account %s: %s", publicKeyOwnerURI, err) return nil, false, fmt.Errorf("couldn't get requesting account %s: %s", publicKeyOwnerURI, err)
} }
withRequesting := context.WithValue(ctx, util.APRequestingAccount, requestingAccount) withRequesting := context.WithValue(ctx, ap.ContextRequestingAccount, requestingAccount)
withReceiving := context.WithValue(withRequesting, util.APReceivingAccount, receivingAccount) withReceiving := context.WithValue(withRequesting, ap.ContextReceivingAccount, receivingAccount)
return withReceiving, true, nil return withReceiving, true, nil
} }
@ -182,7 +183,7 @@ func (f *federator) Blocked(ctx context.Context, actorIRIs []*url.URL) (bool, er
}) })
l.Debugf("entering BLOCKED function with IRI list: %+v", actorIRIs) l.Debugf("entering BLOCKED function with IRI list: %+v", actorIRIs)
receivingAccountI := ctx.Value(util.APReceivingAccount) receivingAccountI := ctx.Value(ap.ContextReceivingAccount)
receivingAccount, ok := receivingAccountI.(*gtsmodel.Account) receivingAccount, ok := receivingAccountI.(*gtsmodel.Account)
if !ok { if !ok {
l.Errorf("receiving account not set on request context") l.Errorf("receiving account not set on request context")

View File

@ -30,11 +30,11 @@ import (
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/activity/pub" "github.com/superseriousbusiness/activity/pub"
"github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/federation" "github.com/superseriousbusiness/gotosocial/internal/federation"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/typeutils" "github.com/superseriousbusiness/gotosocial/internal/typeutils"
"github.com/superseriousbusiness/gotosocial/internal/util"
"github.com/superseriousbusiness/gotosocial/testrig" "github.com/superseriousbusiness/gotosocial/testrig"
) )
@ -91,7 +91,7 @@ func (suite *ProtocolTestSuite) TestPostInboxRequestBodyHook() {
assert.NotNil(suite.T(), newContext) assert.NotNil(suite.T(), newContext)
// activity should be set on context now // activity should be set on context now
activityI := newContext.Value(util.APActivity) activityI := newContext.Value(ap.ContextActivity)
assert.NotNil(suite.T(), activityI) assert.NotNil(suite.T(), activityI)
returnedActivity, ok := activityI.(pub.Activity) returnedActivity, ok := activityI.(pub.Activity)
assert.True(suite.T(), ok) assert.True(suite.T(), ok)
@ -121,10 +121,10 @@ func (suite *ProtocolTestSuite) TestAuthenticatePostInbox() {
ctx := context.Background() ctx := context.Background()
// by the time AuthenticatePostInbox is called, PostInboxRequestBodyHook should have already been called, // by the time AuthenticatePostInbox is called, PostInboxRequestBodyHook should have already been called,
// which should have set the account and username onto the request. We can replicate that behavior here: // which should have set the account and username onto the request. We can replicate that behavior here:
ctxWithAccount := context.WithValue(ctx, util.APReceivingAccount, inboxAccount) ctxWithAccount := context.WithValue(ctx, ap.ContextReceivingAccount, inboxAccount)
ctxWithActivity := context.WithValue(ctxWithAccount, util.APActivity, activity) ctxWithActivity := context.WithValue(ctxWithAccount, ap.ContextActivity, activity)
ctxWithVerifier := context.WithValue(ctxWithActivity, util.APRequestingPublicKeyVerifier, verifier) ctxWithVerifier := context.WithValue(ctxWithActivity, ap.ContextRequestingPublicKeyVerifier, verifier)
ctxWithSignature := context.WithValue(ctxWithVerifier, util.APRequestingPublicKeySignature, activity.SignatureHeader) ctxWithSignature := context.WithValue(ctxWithVerifier, ap.ContextRequestingPublicKeySignature, activity.SignatureHeader)
// we can pass this recorder as a writer and read it back after // we can pass this recorder as a writer and read it back after
recorder := httptest.NewRecorder() recorder := httptest.NewRecorder()
@ -135,7 +135,7 @@ func (suite *ProtocolTestSuite) TestAuthenticatePostInbox() {
assert.True(suite.T(), authed) assert.True(suite.T(), authed)
// since we know this account already it should be set on the context // since we know this account already it should be set on the context
requestingAccountI := newContext.Value(util.APRequestingAccount) requestingAccountI := newContext.Value(ap.ContextRequestingAccount)
assert.NotNil(suite.T(), requestingAccountI) assert.NotNil(suite.T(), requestingAccountI)
requestingAccount, ok := requestingAccountI.(*gtsmodel.Account) requestingAccount, ok := requestingAccountI.(*gtsmodel.Account)
assert.True(suite.T(), ok) assert.True(suite.T(), ok)

View File

@ -24,7 +24,7 @@ import (
"net/url" "net/url"
"github.com/superseriousbusiness/activity/pub" "github.com/superseriousbusiness/activity/pub"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
// NewTransport returns a new Transport on behalf of a specific actor. // NewTransport returns a new Transport on behalf of a specific actor.
@ -55,13 +55,13 @@ func (f *federator) NewTransport(ctx context.Context, actorBoxIRI *url.URL, gofe
var err error var err error
switch { switch {
case util.IsInboxPath(actorBoxIRI): case uris.IsInboxPath(actorBoxIRI):
username, err = util.ParseInboxPath(actorBoxIRI) username, err = uris.ParseInboxPath(actorBoxIRI)
if err != nil { if err != nil {
return nil, fmt.Errorf("couldn't parse path %s as an inbox: %s", actorBoxIRI.String(), err) return nil, fmt.Errorf("couldn't parse path %s as an inbox: %s", actorBoxIRI.String(), err)
} }
case util.IsOutboxPath(actorBoxIRI): case uris.IsOutboxPath(actorBoxIRI):
username, err = util.ParseOutboxPath(actorBoxIRI) username, err = uris.ParseOutboxPath(actorBoxIRI)
if err != nil { if err != nil {
return nil, fmt.Errorf("couldn't parse path %s as an outbox: %s", actorBoxIRI.String(), err) return nil, fmt.Errorf("couldn't parse path %s as an outbox: %s", actorBoxIRI.String(), err)
} }

View File

@ -28,39 +28,31 @@ import (
"codeberg.org/gruf/go-store/kv" "codeberg.org/gruf/go-store/kv"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/internal/transport" "github.com/superseriousbusiness/gotosocial/internal/transport"
"github.com/superseriousbusiness/gotosocial/internal/uris"
) )
// Size describes the *size* of a piece of media // EmojiMaxBytes is the maximum permitted bytes of an emoji upload (50kb)
const EmojiMaxBytes = 51200
type Size string type Size string
// Type describes the *type* of a piece of media const (
SizeSmall Size = "small" // SizeSmall is the key for small/thumbnail versions of media
SizeOriginal Size = "original" // SizeOriginal is the key for original/fullsize versions of media and emoji
SizeStatic Size = "static" // SizeStatic is the key for static (non-animated) versions of emoji
)
type Type string type Type string
const ( const (
// Small is the key for small/thumbnail versions of media TypeAttachment Type = "attachment" // TypeAttachment is the key for media attachments
Small Size = "small" TypeHeader Type = "header" // TypeHeader is the key for profile header requests
// Original is the key for original/fullsize versions of media and emoji TypeAvatar Type = "avatar" // TypeAvatar is the key for profile avatar requests
Original Size = "original" TypeEmoji Type = "emoji" // TypeEmoji is the key for emoji type requests
// Static is the key for static (non-animated) versions of emoji
Static Size = "static"
// Attachment is the key for media attachments
Attachment Type = "attachment"
// Header is the key for profile header requests
Header Type = "header"
// Avatar is the key for profile avatar requests
Avatar Type = "avatar"
// Emoji is the key for emoji type requests
Emoji Type = "emoji"
// EmojiMaxBytes is the maximum permitted bytes of an emoji upload (50kb)
EmojiMaxBytes = 51200
) )
// Handler provides an interface for parsing, storing, and retrieving media objects like photos, videos, and gifs. // Handler provides an interface for parsing, storing, and retrieving media objects like photos, videos, and gifs.
@ -107,7 +99,7 @@ func New(database db.DB, storage *kv.KVStore) Handler {
func (mh *mediaHandler) ProcessHeaderOrAvatar(ctx context.Context, attachment []byte, accountID string, mediaType Type, remoteURL string) (*gtsmodel.MediaAttachment, error) { func (mh *mediaHandler) ProcessHeaderOrAvatar(ctx context.Context, attachment []byte, accountID string, mediaType Type, remoteURL string) (*gtsmodel.MediaAttachment, error) {
l := logrus.WithField("func", "SetHeaderForAccountID") l := logrus.WithField("func", "SetHeaderForAccountID")
if mediaType != Header && mediaType != Avatar { if mediaType != TypeHeader && mediaType != TypeAvatar {
return nil, errors.New("header or avatar not selected") return nil, errors.New("header or avatar not selected")
} }
@ -178,8 +170,6 @@ func (mh *mediaHandler) ProcessAttachment(ctx context.Context, attachmentBytes [
// *gts.Emoji for it, then returns it to the caller. It's the caller's responsibility to put the returned struct // *gts.Emoji for it, then returns it to the caller. It's the caller's responsibility to put the returned struct
// in the database. // in the database.
func (mh *mediaHandler) ProcessLocalEmoji(ctx context.Context, emojiBytes []byte, shortcode string) (*gtsmodel.Emoji, error) { func (mh *mediaHandler) ProcessLocalEmoji(ctx context.Context, emojiBytes []byte, shortcode string) (*gtsmodel.Emoji, error) {
keys := config.Keys
var clean []byte var clean []byte
var err error var err error
var original *imageAndMeta var original *imageAndMeta
@ -234,31 +224,23 @@ func (mh *mediaHandler) ProcessLocalEmoji(ctx context.Context, emojiBytes []byte
// the file extension (either png or gif) // the file extension (either png or gif)
extension := strings.Split(contentType, "/")[1] extension := strings.Split(contentType, "/")[1]
// create the urls and storage paths // generate a ulid for the new emoji
serveProtocol := viper.GetString(keys.StorageServeProtocol)
serveHost := viper.GetString(keys.StorageServeHost)
serveBasePath := viper.GetString(keys.StorageServeBasePath)
URLbase := fmt.Sprintf("%s://%s%s", serveProtocol, serveHost, serveBasePath)
// generate a id for the new emoji
newEmojiID, err := id.NewRandomULID() newEmojiID, err := id.NewRandomULID()
if err != nil { if err != nil {
return nil, err return nil, err
} }
// webfinger uri for the emoji -- unrelated to actually serving the image // activitypub uri for the emoji -- unrelated to actually serving the image
// will be something like https://example.org/emoji/70a7f3d7-7e35-4098-8ce3-9b5e8203bb9c // will be something like https://example.org/emoji/01FPSVBK3H8N7V8XK6KGSQ86EC
protocol := viper.GetString(keys.Protocol) emojiURI := uris.GenerateURIForEmoji(newEmojiID)
host := viper.GetString(keys.Host)
emojiURI := fmt.Sprintf("%s://%s/%s/%s", protocol, host, Emoji, newEmojiID)
// serve url and storage path for the original emoji -- can be png or gif // serve url and storage path for the original emoji -- can be png or gif
emojiURL := fmt.Sprintf("%s/%s/%s/%s/%s.%s", URLbase, instanceAccount.ID, Emoji, Original, newEmojiID, extension) emojiURL := uris.GenerateURIForAttachment(instanceAccount.ID, string(TypeEmoji), string(SizeOriginal), newEmojiID, extension)
emojiPath := fmt.Sprintf("%s/%s/%s/%s.%s", instanceAccount.ID, Emoji, Original, newEmojiID, extension) emojiPath := fmt.Sprintf("%s/%s/%s/%s.%s", instanceAccount.ID, TypeEmoji, SizeOriginal, newEmojiID, extension)
// serve url and storage path for the static version -- will always be png // serve url and storage path for the static version -- will always be png
emojiStaticURL := fmt.Sprintf("%s/%s/%s/%s/%s.png", URLbase, instanceAccount.ID, Emoji, Static, newEmojiID) emojiStaticURL := uris.GenerateURIForAttachment(instanceAccount.ID, string(TypeEmoji), string(SizeStatic), newEmojiID, "png")
emojiStaticPath := fmt.Sprintf("%s/%s/%s/%s.png", instanceAccount.ID, Emoji, Static, newEmojiID) emojiStaticPath := fmt.Sprintf("%s/%s/%s/%s.png", instanceAccount.ID, TypeEmoji, SizeStatic, newEmojiID)
// Store the original emoji // Store the original emoji
if err := mh.storage.Put(emojiPath, original.image); err != nil { if err := mh.storage.Put(emojiPath, original.image); err != nil {
@ -307,9 +289,9 @@ func (mh *mediaHandler) ProcessRemoteHeaderOrAvatar(ctx context.Context, t trans
var headerOrAvi Type var headerOrAvi Type
if currentAttachment.Header { if currentAttachment.Header {
headerOrAvi = Header headerOrAvi = TypeHeader
} else if currentAttachment.Avatar { } else if currentAttachment.Avatar {
headerOrAvi = Avatar headerOrAvi = TypeAvatar
} }
if currentAttachment.RemoteURL == "" { if currentAttachment.RemoteURL == "" {

View File

@ -24,10 +24,9 @@ import (
"strings" "strings"
"time" "time"
"github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/internal/uris"
) )
func (mh *mediaHandler) processHeaderOrAvi(imageBytes []byte, contentType string, mediaType Type, accountID string, remoteURL string) (*gtsmodel.MediaAttachment, error) { func (mh *mediaHandler) processHeaderOrAvi(imageBytes []byte, contentType string, mediaType Type, accountID string, remoteURL string) (*gtsmodel.MediaAttachment, error) {
@ -35,9 +34,9 @@ func (mh *mediaHandler) processHeaderOrAvi(imageBytes []byte, contentType string
var isAvatar bool var isAvatar bool
switch mediaType { switch mediaType {
case Header: case TypeHeader:
isHeader = true isHeader = true
case Avatar: case TypeAvatar:
isAvatar = true isAvatar = true
default: default:
return nil, errors.New("header or avatar not selected") return nil, errors.New("header or avatar not selected")
@ -81,23 +80,16 @@ func (mh *mediaHandler) processHeaderOrAvi(imageBytes []byte, contentType string
return nil, err return nil, err
} }
keys := config.Keys originalURL := uris.GenerateURIForAttachment(accountID, string(mediaType), string(SizeOriginal), newMediaID, extension)
serveProtocol := viper.GetString(keys.StorageServeProtocol) smallURL := uris.GenerateURIForAttachment(accountID, string(mediaType), string(SizeSmall), newMediaID, extension)
serveHost := viper.GetString(keys.StorageServeHost)
serveBasePath := viper.GetString(keys.StorageServeBasePath)
URLbase := fmt.Sprintf("%s://%s%s", serveProtocol, serveHost, serveBasePath)
originalURL := fmt.Sprintf("%s/%s/%s/original/%s.%s", URLbase, accountID, mediaType, newMediaID, extension)
smallURL := fmt.Sprintf("%s/%s/%s/small/%s.%s", URLbase, accountID, mediaType, newMediaID, extension)
// we store the original... // we store the original...
originalPath := fmt.Sprintf("%s/%s/%s/%s.%s", accountID, mediaType, Original, newMediaID, extension) originalPath := fmt.Sprintf("%s/%s/%s/%s.%s", accountID, mediaType, SizeOriginal, newMediaID, extension)
if err := mh.storage.Put(originalPath, original.image); err != nil { if err := mh.storage.Put(originalPath, original.image); err != nil {
return nil, fmt.Errorf("storage error: %s", err) return nil, fmt.Errorf("storage error: %s", err)
} }
// and a thumbnail... // and a thumbnail...
smallPath := fmt.Sprintf("%s/%s/%s/%s.%s", accountID, mediaType, Small, newMediaID, extension) smallPath := fmt.Sprintf("%s/%s/%s/%s.%s", accountID, mediaType, SizeSmall, newMediaID, extension)
if err := mh.storage.Put(smallPath, small.image); err != nil { if err := mh.storage.Put(smallPath, small.image); err != nil {
return nil, fmt.Errorf("storage error: %s", err) return nil, fmt.Errorf("storage error: %s", err)
} }

View File

@ -24,10 +24,9 @@ import (
"strings" "strings"
"time" "time"
"github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/internal/uris"
) )
func (mh *mediaHandler) processImageAttachment(data []byte, minAttachment *gtsmodel.MediaAttachment) (*gtsmodel.MediaAttachment, error) { func (mh *mediaHandler) processImageAttachment(data []byte, minAttachment *gtsmodel.MediaAttachment) (*gtsmodel.MediaAttachment, error) {
@ -69,23 +68,17 @@ func (mh *mediaHandler) processImageAttachment(data []byte, minAttachment *gtsmo
return nil, err return nil, err
} }
keys := config.Keys originalURL := uris.GenerateURIForAttachment(minAttachment.AccountID, string(TypeAttachment), string(SizeOriginal), newMediaID, extension)
serveProtocol := viper.GetString(keys.StorageServeProtocol) smallURL := uris.GenerateURIForAttachment(minAttachment.AccountID, string(TypeAttachment), string(SizeSmall), newMediaID, "jpeg") // all thumbnails/smalls are encoded as jpeg
serveHost := viper.GetString(keys.StorageServeHost)
serveBasePath := viper.GetString(keys.StorageServeBasePath)
URLbase := fmt.Sprintf("%s://%s%s", serveProtocol, serveHost, serveBasePath)
originalURL := fmt.Sprintf("%s/%s/attachment/original/%s.%s", URLbase, minAttachment.AccountID, newMediaID, extension)
smallURL := fmt.Sprintf("%s/%s/attachment/small/%s.jpeg", URLbase, minAttachment.AccountID, newMediaID) // all thumbnails/smalls are encoded as jpeg
// we store the original... // we store the original...
originalPath := fmt.Sprintf("%s/%s/%s/%s.%s", minAttachment.AccountID, Attachment, Original, newMediaID, extension) originalPath := fmt.Sprintf("%s/%s/%s/%s.%s", minAttachment.AccountID, TypeAttachment, SizeOriginal, newMediaID, extension)
if err := mh.storage.Put(originalPath, original.image); err != nil { if err := mh.storage.Put(originalPath, original.image); err != nil {
return nil, fmt.Errorf("storage error: %s", err) return nil, fmt.Errorf("storage error: %s", err)
} }
// and a thumbnail... // and a thumbnail...
smallPath := fmt.Sprintf("%s/%s/%s/%s.jpeg", minAttachment.AccountID, Attachment, Small, newMediaID) // all thumbnails/smalls are encoded as jpeg smallPath := fmt.Sprintf("%s/%s/%s/%s.jpeg", minAttachment.AccountID, TypeAttachment, SizeSmall, newMediaID) // all thumbnails/smalls are encoded as jpeg
if err := mh.storage.Put(smallPath, small.image); err != nil { if err := mh.storage.Put(smallPath, small.image); err != nil {
return nil, fmt.Errorf("storage error: %s", err) return nil, fmt.Errorf("storage error: %s", err)
} }

View File

@ -295,28 +295,28 @@ type imageAndMeta struct {
// ParseMediaType converts s to a recognized MediaType, or returns an error if unrecognized // ParseMediaType converts s to a recognized MediaType, or returns an error if unrecognized
func ParseMediaType(s string) (Type, error) { func ParseMediaType(s string) (Type, error) {
switch Type(s) { switch s {
case Attachment: case string(TypeAttachment):
return Attachment, nil return TypeAttachment, nil
case Header: case string(TypeHeader):
return Header, nil return TypeHeader, nil
case Avatar: case string(TypeAvatar):
return Avatar, nil return TypeAvatar, nil
case Emoji: case string(TypeEmoji):
return Emoji, nil return TypeEmoji, nil
} }
return "", fmt.Errorf("%s not a recognized MediaType", s) return "", fmt.Errorf("%s not a recognized MediaType", s)
} }
// ParseMediaSize converts s to a recognized MediaSize, or returns an error if unrecognized // ParseMediaSize converts s to a recognized MediaSize, or returns an error if unrecognized
func ParseMediaSize(s string) (Size, error) { func ParseMediaSize(s string) (Size, error) {
switch Size(s) { switch s {
case Small: case string(SizeSmall):
return Small, nil return SizeSmall, nil
case Original: case string(SizeOriginal):
return Original, nil return SizeOriginal, nil
case Static: case string(SizeStatic):
return Static, nil return SizeStatic, nil
} }
return "", fmt.Errorf("%s not a recognized MediaSize", s) return "", fmt.Errorf("%s not a recognized MediaSize", s)
} }

View File

@ -29,7 +29,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/internal/messages" "github.com/superseriousbusiness/gotosocial/internal/messages"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
func (p *processor) BlockCreate(ctx context.Context, requestingAccount *gtsmodel.Account, targetAccountID string) (*apimodel.Relationship, gtserror.WithCode) { func (p *processor) BlockCreate(ctx context.Context, requestingAccount *gtsmodel.Account, targetAccountID string) (*apimodel.Relationship, gtserror.WithCode) {
@ -57,7 +57,7 @@ func (p *processor) BlockCreate(ctx context.Context, requestingAccount *gtsmodel
block.Account = requestingAccount block.Account = requestingAccount
block.TargetAccountID = targetAccountID block.TargetAccountID = targetAccountID
block.TargetAccount = targetAccount block.TargetAccount = targetAccount
block.URI = util.GenerateURIForBlock(requestingAccount.Username, newBlockID) block.URI = uris.GenerateURIForBlock(requestingAccount.Username, newBlockID)
// whack it in the database // whack it in the database
if err := p.db.Put(ctx, block); err != nil { if err := p.db.Put(ctx, block); err != nil {

View File

@ -29,7 +29,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/internal/messages" "github.com/superseriousbusiness/gotosocial/internal/messages"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
func (p *processor) FollowCreate(ctx context.Context, requestingAccount *gtsmodel.Account, form *apimodel.AccountFollowRequest) (*apimodel.Relationship, gtserror.WithCode) { func (p *processor) FollowCreate(ctx context.Context, requestingAccount *gtsmodel.Account, form *apimodel.AccountFollowRequest) (*apimodel.Relationship, gtserror.WithCode) {
@ -76,7 +76,7 @@ func (p *processor) FollowCreate(ctx context.Context, requestingAccount *gtsmode
AccountID: requestingAccount.ID, AccountID: requestingAccount.ID,
TargetAccountID: form.ID, TargetAccountID: form.ID,
ShowReblogs: true, ShowReblogs: true,
URI: util.GenerateURIForFollow(requestingAccount.Username, newFollowID), URI: uris.GenerateURIForFollow(requestingAccount.Username, newFollowID),
Notify: false, Notify: false,
} }
if form.Reblogs != nil { if form.Reblogs != nil {

View File

@ -159,7 +159,7 @@ func (p *processor) UpdateAvatar(ctx context.Context, avatar *multipart.FileHead
} }
// do the setting // do the setting
avatarInfo, err := p.mediaHandler.ProcessHeaderOrAvatar(ctx, buf.Bytes(), accountID, media.Avatar, "") avatarInfo, err := p.mediaHandler.ProcessHeaderOrAvatar(ctx, buf.Bytes(), accountID, media.TypeAvatar, "")
if err != nil { if err != nil {
return nil, fmt.Errorf("error processing avatar: %s", err) return nil, fmt.Errorf("error processing avatar: %s", err)
} }
@ -193,7 +193,7 @@ func (p *processor) UpdateHeader(ctx context.Context, header *multipart.FileHead
} }
// do the setting // do the setting
headerInfo, err := p.mediaHandler.ProcessHeaderOrAvatar(ctx, buf.Bytes(), accountID, media.Header, "") headerInfo, err := p.mediaHandler.ProcessHeaderOrAvatar(ctx, buf.Bytes(), accountID, media.TypeHeader, "")
if err != nil { if err != nil {
return nil, fmt.Errorf("error processing header: %s", err) return nil, fmt.Errorf("error processing header: %s", err)
} }

View File

@ -27,7 +27,7 @@ import (
"github.com/superseriousbusiness/activity/streams" "github.com/superseriousbusiness/activity/streams"
"github.com/superseriousbusiness/activity/streams/vocab" "github.com/superseriousbusiness/activity/streams/vocab"
"github.com/superseriousbusiness/gotosocial/internal/gtserror" "github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
func (p *processor) GetUser(ctx context.Context, requestedUsername string, requestURL *url.URL) (interface{}, gtserror.WithCode) { func (p *processor) GetUser(ctx context.Context, requestedUsername string, requestURL *url.URL) (interface{}, gtserror.WithCode) {
@ -39,13 +39,13 @@ func (p *processor) GetUser(ctx context.Context, requestedUsername string, reque
var requestedPerson vocab.ActivityStreamsPerson var requestedPerson vocab.ActivityStreamsPerson
switch { switch {
case util.IsPublicKeyPath(requestURL): case uris.IsPublicKeyPath(requestURL):
// if it's a public key path, we don't need to authenticate but we'll only serve the bare minimum user profile needed for the public key // if it's a public key path, we don't need to authenticate but we'll only serve the bare minimum user profile needed for the public key
requestedPerson, err = p.tc.AccountToASMinimal(ctx, requestedAccount) requestedPerson, err = p.tc.AccountToASMinimal(ctx, requestedAccount)
if err != nil { if err != nil {
return nil, gtserror.NewErrorInternalError(err) return nil, gtserror.NewErrorInternalError(err)
} }
case util.IsUserPath(requestURL): case uris.IsUserPath(requestURL):
// if it's a user path, we want to fully authenticate the request before we serve any data, and then we can serve a more complete profile // if it's a user path, we want to fully authenticate the request before we serve any data, and then we can serve a more complete profile
requestingAccountURI, authenticated, err := p.federator.AuthenticateFederatedRequest(ctx, requestedUsername) requestingAccountURI, authenticated, err := p.federator.AuthenticateFederatedRequest(ctx, requestedUsername)
if err != nil || !authenticated { if err != nil || !authenticated {

View File

@ -22,11 +22,11 @@ import (
"context" "context"
"net/http" "net/http"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/ap"
) )
func (p *processor) PostInbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (bool, error) { func (p *processor) PostInbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (bool, error) {
// pass the fromFederator channel through to postInbox, since it'll be needed later // pass the fromFederator channel through to postInbox, since it'll be needed later
contextWithChannel := context.WithValue(ctx, util.APFromFederatorChanKey, p.fromFederator) contextWithChannel := context.WithValue(ctx, ap.ContextFromFederatorChan, p.fromFederator)
return p.federator.FederatingActor().PostInbox(contextWithChannel, w, r) return p.federator.FederatingActor().PostInbox(contextWithChannel, w, r)
} }

View File

@ -72,7 +72,7 @@ func (p *processor) GetFile(ctx context.Context, account *gtsmodel.Account, form
content := &apimodel.Content{} content := &apimodel.Content{}
var storagePath string var storagePath string
switch mediaType { switch mediaType {
case media.Emoji: case media.TypeEmoji:
e := &gtsmodel.Emoji{} e := &gtsmodel.Emoji{}
if err := p.db.GetByID(ctx, wantedMediaID, e); err != nil { if err := p.db.GetByID(ctx, wantedMediaID, e); err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("emoji %s could not be taken from the db: %s", wantedMediaID, err)) return nil, gtserror.NewErrorNotFound(fmt.Errorf("emoji %s could not be taken from the db: %s", wantedMediaID, err))
@ -81,16 +81,16 @@ func (p *processor) GetFile(ctx context.Context, account *gtsmodel.Account, form
return nil, gtserror.NewErrorNotFound(fmt.Errorf("emoji %s has been disabled", wantedMediaID)) return nil, gtserror.NewErrorNotFound(fmt.Errorf("emoji %s has been disabled", wantedMediaID))
} }
switch mediaSize { switch mediaSize {
case media.Original: case media.SizeOriginal:
content.ContentType = e.ImageContentType content.ContentType = e.ImageContentType
storagePath = e.ImagePath storagePath = e.ImagePath
case media.Static: case media.SizeStatic:
content.ContentType = e.ImageStaticContentType content.ContentType = e.ImageStaticContentType
storagePath = e.ImageStaticPath storagePath = e.ImageStaticPath
default: default:
return nil, gtserror.NewErrorNotFound(fmt.Errorf("media size %s not recognized for emoji", mediaSize)) return nil, gtserror.NewErrorNotFound(fmt.Errorf("media size %s not recognized for emoji", mediaSize))
} }
case media.Attachment, media.Header, media.Avatar: case media.TypeAttachment, media.TypeHeader, media.TypeAvatar:
a, err := p.db.GetAttachmentByID(ctx, wantedMediaID) a, err := p.db.GetAttachmentByID(ctx, wantedMediaID)
if err != nil { if err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("attachment %s could not be taken from the db: %s", wantedMediaID, err)) return nil, gtserror.NewErrorNotFound(fmt.Errorf("attachment %s could not be taken from the db: %s", wantedMediaID, err))
@ -99,10 +99,10 @@ func (p *processor) GetFile(ctx context.Context, account *gtsmodel.Account, form
return nil, gtserror.NewErrorNotFound(fmt.Errorf("attachment %s is not owned by %s", wantedMediaID, form.AccountID)) return nil, gtserror.NewErrorNotFound(fmt.Errorf("attachment %s is not owned by %s", wantedMediaID, form.AccountID))
} }
switch mediaSize { switch mediaSize {
case media.Original: case media.SizeOriginal:
content.ContentType = a.File.ContentType content.ContentType = a.File.ContentType
storagePath = a.File.Path storagePath = a.File.Path
case media.Small: case media.SizeSmall:
content.ContentType = a.Thumbnail.ContentType content.ContentType = a.Thumbnail.ContentType
storagePath = a.Thumbnail.Path storagePath = a.Thumbnail.Path
default: default:

View File

@ -30,17 +30,17 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/internal/messages" "github.com/superseriousbusiness/gotosocial/internal/messages"
"github.com/superseriousbusiness/gotosocial/internal/text" "github.com/superseriousbusiness/gotosocial/internal/text"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
func (p *processor) Create(ctx context.Context, account *gtsmodel.Account, application *gtsmodel.Application, form *apimodel.AdvancedStatusCreateForm) (*apimodel.Status, gtserror.WithCode) { func (p *processor) Create(ctx context.Context, account *gtsmodel.Account, application *gtsmodel.Application, form *apimodel.AdvancedStatusCreateForm) (*apimodel.Status, gtserror.WithCode) {
uris := util.GenerateURIsForAccount(account.Username) accountURIs := uris.GenerateURIsForAccount(account.Username)
thisStatusID, err := id.NewULID() thisStatusID, err := id.NewULID()
if err != nil { if err != nil {
return nil, gtserror.NewErrorInternalError(err) return nil, gtserror.NewErrorInternalError(err)
} }
thisStatusURI := fmt.Sprintf("%s/%s", uris.StatusesURI, thisStatusID) thisStatusURI := fmt.Sprintf("%s/%s", accountURIs.StatusesURI, thisStatusID)
thisStatusURL := fmt.Sprintf("%s/%s", uris.StatusesURL, thisStatusID) thisStatusURL := fmt.Sprintf("%s/%s", accountURIs.StatusesURL, thisStatusID)
newStatus := &gtsmodel.Status{ newStatus := &gtsmodel.Status{
ID: thisStatusID, ID: thisStatusID,

View File

@ -30,7 +30,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/internal/messages" "github.com/superseriousbusiness/gotosocial/internal/messages"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
func (p *processor) Fave(ctx context.Context, requestingAccount *gtsmodel.Account, targetStatusID string) (*apimodel.Status, gtserror.WithCode) { func (p *processor) Fave(ctx context.Context, requestingAccount *gtsmodel.Account, targetStatusID string) (*apimodel.Status, gtserror.WithCode) {
@ -76,7 +76,7 @@ func (p *processor) Fave(ctx context.Context, requestingAccount *gtsmodel.Accoun
TargetAccount: targetStatus.Account, TargetAccount: targetStatus.Account,
StatusID: targetStatus.ID, StatusID: targetStatus.ID,
Status: targetStatus, Status: targetStatus,
URI: util.GenerateURIForLike(requestingAccount.Username, thisFaveID), URI: uris.GenerateURIForLike(requestingAccount.Username, thisFaveID),
} }
if err := p.db.Put(ctx, gtsFave); err != nil { if err := p.db.Put(ctx, gtsFave); err != nil {

View File

@ -31,7 +31,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/email" "github.com/superseriousbusiness/gotosocial/internal/email"
"github.com/superseriousbusiness/gotosocial/internal/gtserror" "github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
var ( var (
@ -53,7 +53,7 @@ func (p *processor) SendConfirmEmail(ctx context.Context, user *gtsmodel.User, u
// equivalent to the odds of creating a few tens of trillions of UUIDs in a // equivalent to the odds of creating a few tens of trillions of UUIDs in a
// year and having one duplicate. // year and having one duplicate.
confirmationToken := uuid.NewString() confirmationToken := uuid.NewString()
confirmationLink := util.GenerateURIForEmailConfirm(confirmationToken) confirmationLink := uris.GenerateURIForEmailConfirm(confirmationToken)
// pull our instance entry from the database so we can greet the user nicely in the email // pull our instance entry from the database so we can greet the user nicely in the email
instance := &gtsmodel.Instance{} instance := &gtsmodel.Instance{}

View File

@ -7,7 +7,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
func (c *converter) FollowRequestToFollow(ctx context.Context, f *gtsmodel.FollowRequest) *gtsmodel.Follow { func (c *converter) FollowRequestToFollow(ctx context.Context, f *gtsmodel.FollowRequest) *gtsmodel.Follow {
@ -25,13 +25,13 @@ func (c *converter) FollowRequestToFollow(ctx context.Context, f *gtsmodel.Follo
func (c *converter) StatusToBoost(ctx context.Context, s *gtsmodel.Status, boostingAccount *gtsmodel.Account) (*gtsmodel.Status, error) { func (c *converter) StatusToBoost(ctx context.Context, s *gtsmodel.Status, boostingAccount *gtsmodel.Account) (*gtsmodel.Status, error) {
// the wrapper won't use the same ID as the boosted status so we generate some new UUIDs // the wrapper won't use the same ID as the boosted status so we generate some new UUIDs
uris := util.GenerateURIsForAccount(boostingAccount.Username) accountURIs := uris.GenerateURIsForAccount(boostingAccount.Username)
boostWrapperStatusID, err := id.NewULID() boostWrapperStatusID, err := id.NewULID()
if err != nil { if err != nil {
return nil, err return nil, err
} }
boostWrapperStatusURI := fmt.Sprintf("%s/%s", uris.StatusesURI, boostWrapperStatusID) boostWrapperStatusURI := fmt.Sprintf("%s/%s", accountURIs.StatusesURI, boostWrapperStatusID)
boostWrapperStatusURL := fmt.Sprintf("%s/%s", uris.StatusesURL, boostWrapperStatusID) boostWrapperStatusURL := fmt.Sprintf("%s/%s", accountURIs.StatusesURL, boostWrapperStatusID)
local := true local := true
if boostingAccount.Domain != "" { if boostingAccount.Domain != "" {

View File

@ -10,7 +10,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/ap" "github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
func (c *converter) WrapPersonInUpdate(person vocab.ActivityStreamsPerson, originAccount *gtsmodel.Account) (vocab.ActivityStreamsUpdate, error) { func (c *converter) WrapPersonInUpdate(person vocab.ActivityStreamsPerson, originAccount *gtsmodel.Account) (vocab.ActivityStreamsUpdate, error) {
@ -33,7 +33,7 @@ func (c *converter) WrapPersonInUpdate(person vocab.ActivityStreamsPerson, origi
return nil, err return nil, err
} }
idString := util.GenerateURIForUpdate(originAccount.Username, newID) idString := uris.GenerateURIForUpdate(originAccount.Username, newID)
idURI, err := url.Parse(idString) idURI, err := url.Parse(idString)
if err != nil { if err != nil {
return nil, fmt.Errorf("WrapPersonInUpdate: error parsing url %s: %s", idString, err) return nil, fmt.Errorf("WrapPersonInUpdate: error parsing url %s: %s", idString, err)

View File

@ -16,7 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package util package uris
import ( import (
"fmt" "fmt"
@ -28,65 +28,25 @@ import (
) )
const ( const (
// UsersPath is for serving users info UsersPath = "users" // UsersPath is for serving users info
UsersPath = "users" ActorsPath = "actors" // ActorsPath is for serving actors info
// ActorsPath is for serving actors info StatusesPath = "statuses" // StatusesPath is for serving statuses
ActorsPath = "actors" InboxPath = "inbox" // InboxPath represents the activitypub inbox location
// StatusesPath is for serving statuses OutboxPath = "outbox" // OutboxPath represents the activitypub outbox location
StatusesPath = "statuses" FollowersPath = "followers" // FollowersPath represents the activitypub followers location
// InboxPath represents the webfinger inbox location FollowingPath = "following" // FollowingPath represents the activitypub following location
InboxPath = "inbox" LikedPath = "liked" // LikedPath represents the activitypub liked location
// OutboxPath represents the webfinger outbox location CollectionsPath = "collections" // CollectionsPath represents the activitypub collections location
OutboxPath = "outbox" FeaturedPath = "featured" // FeaturedPath represents the activitypub featured location
// FollowersPath represents the webfinger followers location PublicKeyPath = "main-key" // PublicKeyPath is for serving an account's public key
FollowersPath = "followers" FollowPath = "follow" // FollowPath used to generate the URI for an individual follow or follow request
// FollowingPath represents the webfinger following location UpdatePath = "updates" // UpdatePath is used to generate the URI for an account update
FollowingPath = "following" BlocksPath = "blocks" // BlocksPath is used to generate the URI for a block
// LikedPath represents the webfinger liked location ConfirmEmailPath = "confirm_email" // ConfirmEmailPath is used to generate the URI for an email confirmation link
LikedPath = "liked" FileserverPath = "fileserver" // FileserverPath is a path component for serving attachments + media
// CollectionsPath represents the webfinger collections location EmojiPath = "emoji" // EmojiPath represents the activitypub emoji location
CollectionsPath = "collections"
// FeaturedPath represents the webfinger featured location
FeaturedPath = "featured"
// PublicKeyPath is for serving an account's public key
PublicKeyPath = "main-key"
// FollowPath used to generate the URI for an individual follow or follow request
FollowPath = "follow"
// UpdatePath is used to generate the URI for an account update
UpdatePath = "updates"
// BlocksPath is used to generate the URI for a block
BlocksPath = "blocks"
// ConfirmEmailPath is used to generate the URI for an email confirmation link
ConfirmEmailPath = "confirm_email"
) )
// APContextKey is a type used specifically for settings values on contexts within go-fed AP request chains
type APContextKey string
const (
// APActivity can be used to set and retrieve the actual go-fed pub.Activity within a context.
APActivity APContextKey = "activity"
// APReceivingAccount can be used the set and retrieve the account being interacted with / receiving an activity in their inbox.
APReceivingAccount APContextKey = "account"
// APRequestingAccount can be used to set and retrieve the account of an incoming federation request.
// This will often be the actor of the instance that's posting the request.
APRequestingAccount APContextKey = "requestingAccount"
// APRequestingActorIRI can be used to set and retrieve the actor of an incoming federation request.
// This will usually be the owner of whatever activity is being posted.
APRequestingActorIRI APContextKey = "requestingActorIRI"
// APRequestingPublicKeyVerifier can be used to set and retrieve the public key verifier of an incoming federation request.
APRequestingPublicKeyVerifier APContextKey = "requestingPublicKeyVerifier"
// APRequestingPublicKeySignature can be used to set and retrieve the value of the signature header of an incoming federation request.
APRequestingPublicKeySignature APContextKey = "requestingPublicKeySignature"
// APFromFederatorChanKey can be used to pass a pointer to the fromFederator channel into the federator for use in callbacks.
APFromFederatorChanKey APContextKey = "fromFederatorChan"
)
type ginContextKey struct{}
// GinContextKey is used solely for setting and retrieving the gin context from a context.Context
var GinContextKey = &ginContextKey{}
// UserURIs contains a bunch of UserURIs and URLs for a user, host, account, etc. // UserURIs contains a bunch of UserURIs and URLs for a user, host, account, etc.
type UserURIs struct { type UserURIs struct {
// The web URL of the instance host, eg https://example.org // The web URL of the instance host, eg https://example.org
@ -96,21 +56,21 @@ type UserURIs struct {
// The web URL for statuses of this user, eg., https://example.org/@example_user/statuses // The web URL for statuses of this user, eg., https://example.org/@example_user/statuses
StatusesURL string StatusesURL string
// The webfinger URI of this user, eg., https://example.org/users/example_user // The activitypub URI of this user, eg., https://example.org/users/example_user
UserURI string UserURI string
// The webfinger URI for this user's statuses, eg., https://example.org/users/example_user/statuses // The activitypub URI for this user's statuses, eg., https://example.org/users/example_user/statuses
StatusesURI string StatusesURI string
// The webfinger URI for this user's activitypub inbox, eg., https://example.org/users/example_user/inbox // The activitypub URI for this user's activitypub inbox, eg., https://example.org/users/example_user/inbox
InboxURI string InboxURI string
// The webfinger URI for this user's activitypub outbox, eg., https://example.org/users/example_user/outbox // The activitypub URI for this user's activitypub outbox, eg., https://example.org/users/example_user/outbox
OutboxURI string OutboxURI string
// The webfinger URI for this user's followers, eg., https://example.org/users/example_user/followers // The activitypub URI for this user's followers, eg., https://example.org/users/example_user/followers
FollowersURI string FollowersURI string
// The webfinger URI for this user's following, eg., https://example.org/users/example_user/following // The activitypub URI for this user's following, eg., https://example.org/users/example_user/following
FollowingURI string FollowingURI string
// The webfinger URI for this user's liked posts eg., https://example.org/users/example_user/liked // The activitypub URI for this user's liked posts eg., https://example.org/users/example_user/liked
LikedURI string LikedURI string
// The webfinger URI for this user's featured collections, eg., https://example.org/users/example_user/collections/featured // The activitypub URI for this user's featured collections, eg., https://example.org/users/example_user/collections/featured
CollectionURI string CollectionURI string
// The URI for this user's public key, eg., https://example.org/users/example_user/publickey // The URI for this user's public key, eg., https://example.org/users/example_user/publickey
PublicKeyURI string PublicKeyURI string
@ -194,6 +154,23 @@ func GenerateURIsForAccount(username string) *UserURIs {
} }
} }
// GenerateURIForAttachment generates a URI for an attachment/emoji/header etc.
// Will produced something like https://example.org/fileserver/01FPST95B8FC3HG3AGCDKPQNQ2/attachment/original/01FPST9QK4V5XWS3F9Z4F2G1X7.gif
func GenerateURIForAttachment(accountID string, mediaType string, mediaSize string, mediaID string, extension string) string {
protocol := viper.GetString(config.Keys.Protocol)
host := viper.GetString(config.Keys.Host)
return fmt.Sprintf("%s://%s/%s/%s/%s/%s/%s.%s", protocol, host, FileserverPath, accountID, mediaType, mediaSize, mediaID, extension)
}
// GenerateURIForEmoji generates an activitypub uri for a new emoji.
func GenerateURIForEmoji(emojiID string) string {
protocol := viper.GetString(config.Keys.Protocol)
host := viper.GetString(config.Keys.Host)
return fmt.Sprintf("%s://%s/%s/%s", protocol, host, EmojiPath, emojiID)
}
// IsUserPath returns true if the given URL path corresponds to eg /users/example_username // IsUserPath returns true if the given URL path corresponds to eg /users/example_username
func IsUserPath(id *url.URL) bool { func IsUserPath(id *url.URL) bool {
return regexes.UserPath.MatchString(id.Path) return regexes.UserPath.MatchString(id.Path)

View File

@ -31,11 +31,11 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/processing" "github.com/superseriousbusiness/gotosocial/internal/processing"
"github.com/superseriousbusiness/gotosocial/internal/router" "github.com/superseriousbusiness/gotosocial/internal/router"
"github.com/superseriousbusiness/gotosocial/internal/util" "github.com/superseriousbusiness/gotosocial/internal/uris"
) )
const ( const (
confirmEmailPath = "/" + util.ConfirmEmailPath confirmEmailPath = "/" + uris.ConfirmEmailPath
tokenParam = "token" tokenParam = "token"
) )

View File

@ -5,7 +5,7 @@ set -e
echo "STARTING CLI TESTS" echo "STARTING CLI TESTS"
echo "TEST_1 Make sure defaults are set correctly." echo "TEST_1 Make sure defaults are set correctly."
TEST_1_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"localhost","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-base-path":"/gotosocial/storage","storage-serve-base-path":"/fileserver","storage-serve-host":"localhost","storage-serve-protocol":"https","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' TEST_1_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"localhost","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
TEST_1="$(go run ./cmd/gotosocial/... debug config)" TEST_1="$(go run ./cmd/gotosocial/... debug config)"
if [ "${TEST_1}" != "${TEST_1_EXPECTED}" ]; then if [ "${TEST_1}" != "${TEST_1_EXPECTED}" ]; then
echo "TEST_1 not equal TEST_1_EXPECTED" echo "TEST_1 not equal TEST_1_EXPECTED"
@ -15,7 +15,7 @@ else
fi fi
echo "TEST_2 Override db-address from default using cli flag." echo "TEST_2 Override db-address from default using cli flag."
TEST_2_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.db.address","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-base-path":"/gotosocial/storage","storage-serve-base-path":"/fileserver","storage-serve-host":"localhost","storage-serve-protocol":"https","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' TEST_2_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.db.address","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
TEST_2="$(go run ./cmd/gotosocial/... --db-address some.db.address debug config)" TEST_2="$(go run ./cmd/gotosocial/... --db-address some.db.address debug config)"
if [ "${TEST_2}" != "${TEST_2_EXPECTED}" ]; then if [ "${TEST_2}" != "${TEST_2_EXPECTED}" ]; then
echo "TEST_2 not equal TEST_2_EXPECTED" echo "TEST_2 not equal TEST_2_EXPECTED"
@ -25,7 +25,7 @@ else
fi fi
echo "TEST_3 Override db-address from default using env var." echo "TEST_3 Override db-address from default using env var."
TEST_3_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.db.address","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-base-path":"/gotosocial/storage","storage-serve-base-path":"/fileserver","storage-serve-host":"localhost","storage-serve-protocol":"https","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' TEST_3_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.db.address","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
TEST_3="$(GTS_DB_ADDRESS=some.db.address go run ./cmd/gotosocial/... debug config)" TEST_3="$(GTS_DB_ADDRESS=some.db.address go run ./cmd/gotosocial/... debug config)"
if [ "${TEST_3}" != "${TEST_3_EXPECTED}" ]; then if [ "${TEST_3}" != "${TEST_3_EXPECTED}" ]; then
echo "TEST_3 not equal TEST_3_EXPECTED" echo "TEST_3 not equal TEST_3_EXPECTED"
@ -35,7 +35,7 @@ else
fi fi
echo "TEST_4 Override db-address from default using both env var and cli flag. The cli flag should take priority." echo "TEST_4 Override db-address from default using both env var and cli flag. The cli flag should take priority."
TEST_4_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.other.db.address","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-base-path":"/gotosocial/storage","storage-serve-base-path":"/fileserver","storage-serve-host":"localhost","storage-serve-protocol":"https","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' TEST_4_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.other.db.address","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
TEST_4="$(GTS_DB_ADDRESS=some.db.address go run ./cmd/gotosocial/... --db-address some.other.db.address debug config)" TEST_4="$(GTS_DB_ADDRESS=some.db.address go run ./cmd/gotosocial/... --db-address some.other.db.address debug config)"
if [ "${TEST_4}" != "${TEST_4_EXPECTED}" ]; then if [ "${TEST_4}" != "${TEST_4_EXPECTED}" ]; then
echo "TEST_4 not equal TEST_4_EXPECTED" echo "TEST_4 not equal TEST_4_EXPECTED"
@ -45,7 +45,7 @@ else
fi fi
echo "TEST_5 Test loading a config file by passing an env var." echo "TEST_5 Test loading a config file by passing an env var."
TEST_5_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-base-path":"/gotosocial/storage","storage-serve-base-path":"/fileserver","storage-serve-host":"localhost","storage-serve-protocol":"https","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' TEST_5_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
TEST_5="$(GTS_CONFIG_PATH=./test/test.yaml go run ./cmd/gotosocial/... debug config)" TEST_5="$(GTS_CONFIG_PATH=./test/test.yaml go run ./cmd/gotosocial/... debug config)"
if [ "${TEST_5}" != "${TEST_5_EXPECTED}" ]; then if [ "${TEST_5}" != "${TEST_5_EXPECTED}" ]; then
echo "TEST_5 not equal TEST_5_EXPECTED" echo "TEST_5 not equal TEST_5_EXPECTED"
@ -55,7 +55,7 @@ else
fi fi
echo "TEST_6 Test loading a config file by passing cli flag." echo "TEST_6 Test loading a config file by passing cli flag."
TEST_6_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-base-path":"/gotosocial/storage","storage-serve-base-path":"/fileserver","storage-serve-host":"localhost","storage-serve-protocol":"https","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' TEST_6_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
TEST_6="$(go run ./cmd/gotosocial/... --config-path ./test/test.yaml debug config)" TEST_6="$(go run ./cmd/gotosocial/... --config-path ./test/test.yaml debug config)"
if [ "${TEST_6}" != "${TEST_6_EXPECTED}" ]; then if [ "${TEST_6}" != "${TEST_6_EXPECTED}" ]; then
echo "TEST_6 not equal TEST_6_EXPECTED" echo "TEST_6 not equal TEST_6_EXPECTED"
@ -65,7 +65,7 @@ else
fi fi
echo "TEST_7 Test loading a config file and overriding one of the variables with a cli flag." echo "TEST_7 Test loading a config file and overriding one of the variables with a cli flag."
TEST_7_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-base-path":"/gotosocial/storage","storage-serve-base-path":"/fileserver","storage-serve-host":"localhost","storage-serve-protocol":"https","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' TEST_7_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
TEST_7="$(go run ./cmd/gotosocial/... --config-path ./test/test.yaml --account-domain '' debug config)" TEST_7="$(go run ./cmd/gotosocial/... --config-path ./test/test.yaml --account-domain '' debug config)"
if [ "${TEST_7}" != "${TEST_7_EXPECTED}" ]; then if [ "${TEST_7}" != "${TEST_7_EXPECTED}" ]; then
echo "TEST_7 not equal TEST_7_EXPECTED" echo "TEST_7 not equal TEST_7_EXPECTED"
@ -75,7 +75,7 @@ else
fi fi
echo "TEST_8 Test loading a config file and overriding one of the variables with an env var." echo "TEST_8 Test loading a config file and overriding one of the variables with an env var."
TEST_8_EXPECTED='{"account-domain":"peepee","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-base-path":"/gotosocial/storage","storage-serve-base-path":"/fileserver","storage-serve-host":"localhost","storage-serve-protocol":"https","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' TEST_8_EXPECTED='{"account-domain":"peepee","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
TEST_8="$(GTS_ACCOUNT_DOMAIN='peepee' go run ./cmd/gotosocial/... --config-path ./test/test.yaml debug config)" TEST_8="$(GTS_ACCOUNT_DOMAIN='peepee' go run ./cmd/gotosocial/... --config-path ./test/test.yaml debug config)"
if [ "${TEST_8}" != "${TEST_8_EXPECTED}" ]; then if [ "${TEST_8}" != "${TEST_8_EXPECTED}" ]; then
echo "TEST_8 not equal TEST_8_EXPECTED" echo "TEST_8 not equal TEST_8_EXPECTED"
@ -85,7 +85,7 @@ else
fi fi
echo "TEST_9 Test loading a config file and overriding one of the variables with both an env var and a cli flag. The cli flag should have priority." echo "TEST_9 Test loading a config file and overriding one of the variables with both an env var and a cli flag. The cli flag should have priority."
TEST_9_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-base-path":"/gotosocial/storage","storage-serve-base-path":"/fileserver","storage-serve-host":"localhost","storage-serve-protocol":"https","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' TEST_9_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
TEST_9="$(GTS_ACCOUNT_DOMAIN='peepee' go run ./cmd/gotosocial/... --config-path ./test/test.yaml --account-domain '' debug config)" TEST_9="$(GTS_ACCOUNT_DOMAIN='peepee' go run ./cmd/gotosocial/... --config-path ./test/test.yaml --account-domain '' debug config)"
if [ "${TEST_9}" != "${TEST_9_EXPECTED}" ]; then if [ "${TEST_9}" != "${TEST_9_EXPECTED}" ]; then
echo "TEST_9 not equal TEST_9_EXPECTED" echo "TEST_9 not equal TEST_9_EXPECTED"
@ -95,7 +95,7 @@ else
fi fi
echo "TEST_10 Test loading a config file from json." echo "TEST_10 Test loading a config file from json."
TEST_10_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.json","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-base-path":"/gotosocial/storage","storage-serve-base-path":"/fileserver","storage-serve-host":"localhost","storage-serve-protocol":"https","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' TEST_10_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.json","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
TEST_10="$(go run ./cmd/gotosocial/... --config-path ./test/test.json debug config)" TEST_10="$(go run ./cmd/gotosocial/... --config-path ./test/test.json debug config)"
if [ "${TEST_10}" != "${TEST_10_EXPECTED}" ]; then if [ "${TEST_10}" != "${TEST_10_EXPECTED}" ]; then
echo "TEST_10 not equal TEST_10_EXPECTED" echo "TEST_10 not equal TEST_10_EXPECTED"
@ -105,7 +105,7 @@ else
fi fi
echo "TEST_11 Test loading a partial config file. Default values should be used apart from those set in the config file." echo "TEST_11 Test loading a partial config file. Default values should be used apart from those set in the config file."
TEST_11_EXPECTED='{"account-domain":"peepee.poopoo","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test2.yaml","db-address":"localhost","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"trace","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-base-path":"/gotosocial/storage","storage-serve-base-path":"/fileserver","storage-serve-host":"localhost","storage-serve-protocol":"https","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' TEST_11_EXPECTED='{"account-domain":"peepee.poopoo","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test2.yaml","db-address":"localhost","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-level":"trace","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
TEST_11="$(go run ./cmd/gotosocial/... --config-path ./test/test2.yaml debug config)" TEST_11="$(go run ./cmd/gotosocial/... --config-path ./test/test2.yaml debug config)"
if [ "${TEST_11}" != "${TEST_11_EXPECTED}" ]; then if [ "${TEST_11}" != "${TEST_11_EXPECTED}" ]; then
echo "TEST_11 not equal TEST_11_EXPECTED" echo "TEST_11 not equal TEST_11_EXPECTED"

View File

@ -51,10 +51,7 @@
"statuses-poll-max-options": 6, "statuses-poll-max-options": 6,
"statuses-poll-option-max-chars": 50, "statuses-poll-option-max-chars": 50,
"storage-backend": "local", "storage-backend": "local",
"storage-base-path": "/gotosocial/storage", "storage-local-base-path": "/gotosocial/storage",
"storage-serve-base-path": "/fileserver",
"storage-serve-host": "localhost",
"storage-serve-protocol": "https",
"trusted-proxies": [ "trusted-proxies": [
"127.0.0.1/32", "127.0.0.1/32",
"0.0.0.0/0" "0.0.0.0/0"

View File

@ -214,27 +214,7 @@ storage-backend: "local"
# this directly, and create new subdirectories and files with in. # this directly, and create new subdirectories and files with in.
# Examples: ["/home/gotosocial/storage", "/opt/gotosocial/datastorage"] # Examples: ["/home/gotosocial/storage", "/opt/gotosocial/datastorage"]
# Default: "/gotosocial/storage" # Default: "/gotosocial/storage"
storage-base-path: "/gotosocial/storage" storage-local-base-path: "/gotosocial/storage"
# String. Protocol to use for serving stored files.
# It's very unlikely that you'll need to change this ever, but there might be edge cases.
# Examples: ["http", "https"]
storage-serve-protocol: "https"
# String. Host for serving stored files.
# If you're using local storage, this should be THE SAME as the value you've set for Host, above.
# It should only be a different value if you're serving stored files from a host
# other than the one your instance is running on.
# Examples: ["localhost", "example.org"]
# Default: "localhost" -- you should absolutely change this.
storage-serve-host: "localhost"
# String. Base path for serving stored files. This will be added to serveHost and serveProtocol
# to form the prefix url of your stored files. Eg., https://example.org/fileserver/.....
# It's unlikely that you will need to change this.
# Examples: ["/fileserver", "/media"]
# Default: "/fileserver"
storage-serve-base-path: "/fileserver"
########################### ###########################
##### STATUSES CONFIG ##### ##### STATUSES CONFIG #####

View File

@ -88,10 +88,7 @@ var TestDefaults = config.Values{
MediaDescriptionMaxChars: 500, MediaDescriptionMaxChars: 500,
StorageBackend: "local", StorageBackend: "local",
StorageBasePath: "/gotosocial/storage", StorageLocalBasePath: "/gotosocial/storage",
StorageServeProtocol: "http",
StorageServeHost: "localhost:8080",
StorageServeBasePath: "/fileserver",
StatusesMaxChars: 5000, StatusesMaxChars: 5000,
StatusesCWMaxChars: 100, StatusesCWMaxChars: 100,