From b1a4f38e383279d14d10b6b4575f752ca4b54f73 Mon Sep 17 00:00:00 2001 From: Tobi Smethurst <31960611+tsmethurst@users.noreply.github.com> Date: Mon, 19 Jul 2021 18:42:08 +0200 Subject: [PATCH] allow different host + accountDomain (#103) * allow different host + accountDomain * use accountDomain in tags --- cmd/gotosocial/main.go | 8 +++++++- example/config.yaml | 17 +++++++++++++++-- internal/api/s2s/webfinger/webfingerget.go | 16 ++++++++-------- internal/config/config.go | 12 ++++++++++++ internal/config/default.go | 2 ++ internal/processing/federation.go | 2 +- internal/typeutils/internaltoas.go | 2 +- 7 files changed, 46 insertions(+), 13 deletions(-) diff --git a/cmd/gotosocial/main.go b/cmd/gotosocial/main.go index fde83e623..e8bc793bd 100644 --- a/cmd/gotosocial/main.go +++ b/cmd/gotosocial/main.go @@ -69,10 +69,16 @@ func main() { }, &cli.StringFlag{ Name: flagNames.Host, - Usage: "Hostname to use for the server (eg., example.org, gotosocial.whatever.com)", + Usage: "Hostname to use for the server (eg., example.org, gotosocial.whatever.com). DO NOT change this on a server that's already run!", Value: defaults.Host, EnvVars: []string{envNames.Host}, }, + &cli.StringFlag{ + Name: flagNames.AccountDomain, + Usage: "Domain to use in account names (eg., example.org, whatever.com). If not set, will default to the setting for host. DO NOT change this on a server that's already run!", + Value: defaults.AccountDomain, + EnvVars: []string{envNames.AccountDomain}, + }, &cli.StringFlag{ Name: flagNames.Protocol, Usage: "Protocol to use for the REST api of the server (only use http for debugging and tests!)", diff --git a/example/config.yaml b/example/config.yaml index b26322812..149da46dd 100644 --- a/example/config.yaml +++ b/example/config.yaml @@ -27,12 +27,25 @@ logLevel: "info" # Default: "gotosocial" applicationName: "gotosocial" -# String. Hostname/domain to use for the server. Defaults to localhost for local testing, +# String. Hostname that this server will be reachable at. Defaults to localhost for local testing, # but you should *definitely* change this when running for real, or your server won't work at all. -# Examples: ["example.org","some.server.com"] +# DO NOT change this after your server has already run once, or you will break things! +# Examples: ["gts.example.org","some.server.com"] # Default: "localhost" host: "localhost" +# String. Domain to use when federating profiles. This is useful when you want your server to be at +# eg., "gts.example.org", but you want the domain on accounts to be "example.org" because it looks better +# or is just shorter/easier to remember. +# To make this setting work properly, you need to redirect requests at "example.org/.well-known/webfinger" +# to "gts.example.org/.well-known/webfinger" so that GtS can handle them properly. +# You should also redirect requests at "example.org/.well-known/nodeinfo" in the same way. +# An empty string (ie., not set) means that the same value as 'host' will be used. +# DO NOT change this after your server has already run once, or you will break things! +# Examples: ["example.org","server.com"] +# Default: "" +accountDomain: "" + # String. Protocol to use for the server. Only change to http for local testing! # Options: ["http","https"] # Default: "https" diff --git a/internal/api/s2s/webfinger/webfingerget.go b/internal/api/s2s/webfinger/webfingerget.go index 416a75f3b..1d723e67c 100644 --- a/internal/api/s2s/webfinger/webfingerget.go +++ b/internal/api/s2s/webfinger/webfingerget.go @@ -50,23 +50,23 @@ func (m *Module) WebfingerGETRequest(c *gin.Context) { return } - usernameDomain := strings.Split(withAcct[1], "@") - if len(usernameDomain) != 2 { + usernameAndAccountDomain := strings.Split(withAcct[1], "@") + if len(usernameAndAccountDomain) != 2 { l.Debugf("aborting request because username and domain could not be parsed from %s", withAcct[1]) c.JSON(http.StatusBadRequest, gin.H{"error": "bad request"}) return } - username := strings.ToLower(usernameDomain[0]) - domain := strings.ToLower(usernameDomain[1]) - if username == "" || domain == "" { + username := strings.ToLower(usernameAndAccountDomain[0]) + accountDomain := strings.ToLower(usernameAndAccountDomain[1]) + if username == "" || accountDomain == "" { l.Debug("aborting request because username or domain was empty") c.JSON(http.StatusBadRequest, gin.H{"error": "bad request"}) return } - if domain != m.config.Host { - l.Debugf("aborting request because domain %s does not belong to this instance", domain) - c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("domain %s does not belong to this instance", domain)}) + if accountDomain != m.config.AccountDomain { + l.Debugf("aborting request because accountDomain %s does not belong to this instance", accountDomain) + c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("accountDomain %s does not belong to this instance", accountDomain)}) return } diff --git a/internal/config/config.go b/internal/config/config.go index 323b7de81..958926975 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -48,6 +48,7 @@ type Config struct { LogLevel string `yaml:"logLevel"` ApplicationName string `yaml:"applicationName"` Host string `yaml:"host"` + AccountDomain string `yaml:"accountDomain"` Protocol string `yaml:"protocol"` DBConfig *DBConfig `yaml:"db"` TemplateConfig *TemplateConfig `yaml:"template"` @@ -133,6 +134,13 @@ func (c *Config) ParseCLIFlags(f KeyedFlags, version string) error { return errors.New("host was not set") } + if c.AccountDomain == "" || f.IsSet(fn.AccountDomain) { + c.AccountDomain = f.String(fn.AccountDomain) + } + if c.AccountDomain == "" { + c.AccountDomain = c.Host // default to whatever the host is, if this is empty + } + if c.Protocol == "" || f.IsSet(fn.Protocol) { c.Protocol = f.String(fn.Protocol) } @@ -290,6 +298,7 @@ type Flags struct { ApplicationName string ConfigPath string Host string + AccountDomain string Protocol string DbType string @@ -336,6 +345,7 @@ type Defaults struct { ApplicationName string ConfigPath string Host string + AccountDomain string Protocol string SoftwareVersion string @@ -385,6 +395,7 @@ func GetFlagNames() Flags { ApplicationName: "application-name", ConfigPath: "config-path", Host: "host", + AccountDomain: "account-domain", Protocol: "protocol", DbType: "db-type", @@ -434,6 +445,7 @@ func GetEnvNames() Flags { ApplicationName: "GTS_APPLICATION_NAME", ConfigPath: "GTS_CONFIG_PATH", Host: "GTS_HOST", + AccountDomain: "GTS_ACCOUNT_DOMAIN", Protocol: "GTS_PROTOCOL", DbType: "GTS_DB_TYPE", diff --git a/internal/config/default.go b/internal/config/default.go index 7a030beb5..099eead1c 100644 --- a/internal/config/default.go +++ b/internal/config/default.go @@ -118,6 +118,7 @@ func GetDefaults() Defaults { ApplicationName: "gotosocial", ConfigPath: "", Host: "", + AccountDomain: "", Protocol: "https", DbType: "postgres", @@ -166,6 +167,7 @@ func GetTestDefaults() Defaults { ApplicationName: "gotosocial", ConfigPath: "", Host: "localhost:8080", + AccountDomain: "", Protocol: "http", DbType: "postgres", diff --git a/internal/processing/federation.go b/internal/processing/federation.go index 6299d5e7e..966dab08d 100644 --- a/internal/processing/federation.go +++ b/internal/processing/federation.go @@ -304,7 +304,7 @@ func (p *processor) GetWebfingerAccount(ctx context.Context, requestedUsername s // return the webfinger representation return &apimodel.WellKnownResponse{ - Subject: fmt.Sprintf("acct:%s@%s", requestedAccount.Username, p.config.Host), + Subject: fmt.Sprintf("acct:%s@%s", requestedAccount.Username, p.config.AccountDomain), Aliases: []string{ requestedAccount.URI, requestedAccount.URL, diff --git a/internal/typeutils/internaltoas.go b/internal/typeutils/internaltoas.go index 809cedc45..b24b07e13 100644 --- a/internal/typeutils/internaltoas.go +++ b/internal/typeutils/internaltoas.go @@ -580,7 +580,7 @@ func (c *converter) MentionToAS(m *gtsmodel.Mention) (vocab.ActivityStreamsMenti // name -- this should be the namestring of the mentioned user, something like @whatever@example.org var domain string if m.GTSAccount.Domain == "" { - domain = c.config.Host + domain = c.config.AccountDomain } else { domain = m.GTSAccount.Domain }