diff --git a/internal/api/client/instance/instancepatch_test.go b/internal/api/client/instance/instancepatch_test.go index 0ba0f9881..47126e8b5 100644 --- a/internal/api/client/instance/instancepatch_test.go +++ b/internal/api/client/instance/instancepatch_test.go @@ -28,6 +28,7 @@ import ( "github.com/stretchr/testify/suite" "github.com/superseriousbusiness/gotosocial/internal/api/client/instance" + "github.com/superseriousbusiness/gotosocial/internal/middleware" "github.com/superseriousbusiness/gotosocial/internal/oauth" "github.com/superseriousbusiness/gotosocial/testrig" ) @@ -51,6 +52,7 @@ func (suite *InstancePatchTestSuite) instancePatch(fieldName string, fileName st ctx := suite.newContext(recorder, http.MethodPatch, instance.InstanceInformationPathV1, requestBody.Bytes(), w.FormDataContentType(), true) suite.instanceModule.InstanceUpdatePATCHHandler(ctx) + middleware.Logger(false)(ctx) result := recorder.Result() defer result.Body.Close() diff --git a/internal/db/bundb/account.go b/internal/db/bundb/account.go index 2029fc732..3d85df381 100644 --- a/internal/db/bundb/account.go +++ b/internal/db/bundb/account.go @@ -140,7 +140,7 @@ func (a *accountDB) GetAccountByUsernameDomain(ctx context.Context, username str var err error // Normalize the domain as punycode - domain, err = util.Punify_(domain) + domain, err = util.Punify(domain) if err != nil { return nil, err } diff --git a/internal/db/bundb/domain.go b/internal/db/bundb/domain.go index 76c730015..925387bd9 100644 --- a/internal/db/bundb/domain.go +++ b/internal/db/bundb/domain.go @@ -39,7 +39,7 @@ type domainDB struct { func (d *domainDB) CreateDomainAllow(ctx context.Context, allow *gtsmodel.DomainAllow) (err error) { // Normalize the domain as punycode, note the extra // validation step for domain name write operations. - allow.Domain, err = util.PunifyValidate(allow.Domain) + allow.Domain, err = util.PunifySafely(allow.Domain) if err != nil { return gtserror.Newf("error punifying domain %s: %w", allow.Domain, err) } @@ -59,7 +59,7 @@ func (d *domainDB) CreateDomainAllow(ctx context.Context, allow *gtsmodel.Domain func (d *domainDB) GetDomainAllow(ctx context.Context, domain string) (*gtsmodel.DomainAllow, error) { // Normalize domain as punycode for lookup. - domain, err := util.Punify_(domain) + domain, err := util.Punify(domain) if err != nil { return nil, gtserror.Newf("error punifying domain %s: %w", domain, err) } @@ -114,7 +114,7 @@ func (d *domainDB) GetDomainAllowByID(ctx context.Context, id string) (*gtsmodel func (d *domainDB) UpdateDomainAllow(ctx context.Context, allow *gtsmodel.DomainAllow, columns ...string) (err error) { // Normalize the domain as punycode, note the extra // validation step for domain name write operations. - allow.Domain, err = util.PunifyValidate(allow.Domain) + allow.Domain, err = util.PunifySafely(allow.Domain) if err != nil { return gtserror.Newf("error punifying domain %s: %w", allow.Domain, err) } @@ -143,7 +143,7 @@ func (d *domainDB) UpdateDomainAllow(ctx context.Context, allow *gtsmodel.Domain func (d *domainDB) DeleteDomainAllow(ctx context.Context, domain string) error { // Normalize domain as punycode for lookup. - domain, err := util.Punify_(domain) + domain, err := util.Punify(domain) if err != nil { return gtserror.Newf("error punifying domain %s: %w", domain, err) } @@ -167,7 +167,7 @@ func (d *domainDB) CreateDomainBlock(ctx context.Context, block *gtsmodel.Domain // Normalize the domain as punycode, note the extra // validation step for domain name write operations. - block.Domain, err = util.PunifyValidate(block.Domain) + block.Domain, err = util.PunifySafely(block.Domain) if err != nil { return gtserror.Newf("error punifying domain %s: %w", block.Domain, err) } @@ -187,7 +187,7 @@ func (d *domainDB) CreateDomainBlock(ctx context.Context, block *gtsmodel.Domain func (d *domainDB) GetDomainBlock(ctx context.Context, domain string) (*gtsmodel.DomainBlock, error) { // Normalize domain as punycode for lookup. - domain, err := util.Punify_(domain) + domain, err := util.Punify(domain) if err != nil { return nil, gtserror.Newf("error punifying domain %s: %w", domain, err) } @@ -244,7 +244,7 @@ func (d *domainDB) UpdateDomainBlock(ctx context.Context, block *gtsmodel.Domain // Normalize the domain as punycode, note the extra // validation step for domain name write operations. - block.Domain, err = util.PunifyValidate(block.Domain) + block.Domain, err = util.PunifySafely(block.Domain) if err != nil { return gtserror.Newf("error punifying domain %s: %w", block.Domain, err) } @@ -273,7 +273,7 @@ func (d *domainDB) UpdateDomainBlock(ctx context.Context, block *gtsmodel.Domain func (d *domainDB) DeleteDomainBlock(ctx context.Context, domain string) error { // Normalize domain as punycode for lookup. - domain, err := util.Punify_(domain) + domain, err := util.Punify(domain) if err != nil { return gtserror.Newf("error punifying domain %s: %w", domain, err) } @@ -294,7 +294,7 @@ func (d *domainDB) DeleteDomainBlock(ctx context.Context, domain string) error { func (d *domainDB) IsDomainBlocked(ctx context.Context, domain string) (bool, error) { // Normalize domain as punycode for lookup. - domain, err := util.Punify_(domain) + domain, err := util.Punify(domain) if err != nil { return false, gtserror.Newf("error punifying domain %s: %w", domain, err) } diff --git a/internal/db/bundb/domainpermissiondraft.go b/internal/db/bundb/domainpermissiondraft.go index ca29f69a6..281db1224 100644 --- a/internal/db/bundb/domainpermissiondraft.go +++ b/internal/db/bundb/domainpermissiondraft.go @@ -169,7 +169,7 @@ func (d *domainDB) GetDomainPermissionDrafts( var err error // Normalize domain as punycode for lookup. - domain, err = util.Punify_(domain) + domain, err = util.Punify(domain) if err != nil { return nil, gtserror.Newf("error punifying domain %s: %w", domain, err) } @@ -240,7 +240,7 @@ func (d *domainDB) PutDomainPermissionDraft( // Normalize the domain as punycode, note the extra // validation step for domain name write operations. - draft.Domain, err = util.PunifyValidate(draft.Domain) + draft.Domain, err = util.PunifySafely(draft.Domain) if err != nil { return gtserror.Newf("error punifying domain %s: %w", draft.Domain, err) } diff --git a/internal/db/bundb/domainpermissionexclude.go b/internal/db/bundb/domainpermissionexclude.go index ca3fcfb51..1527a584b 100644 --- a/internal/db/bundb/domainpermissionexclude.go +++ b/internal/db/bundb/domainpermissionexclude.go @@ -41,7 +41,7 @@ func (d *domainDB) PutDomainPermissionExclude( // Normalize the domain as punycode, note the extra // validation step for domain name write operations. - exclude.Domain, err = util.PunifyValidate(exclude.Domain) + exclude.Domain, err = util.PunifySafely(exclude.Domain) if err != nil { return gtserror.Newf("error punifying domain %s: %w", exclude.Domain, err) } @@ -61,7 +61,7 @@ func (d *domainDB) PutDomainPermissionExclude( func (d *domainDB) IsDomainPermissionExcluded(ctx context.Context, domain string) (bool, error) { // Normalize domain as punycode for lookup. - domain, err := util.Punify_(domain) + domain, err := util.Punify(domain) if err != nil { return false, gtserror.Newf("error punifying domain %s: %w", domain, err) } @@ -180,7 +180,7 @@ func (d *domainDB) GetDomainPermissionExcludes( var err error // Normalize domain as punycode for lookup. - domain, err = util.Punify_(domain) + domain, err = util.Punify(domain) if err != nil { return nil, gtserror.Newf("error punifying domain %s: %w", domain, err) } diff --git a/internal/db/bundb/instance.go b/internal/db/bundb/instance.go index a1c26946a..7852ae52e 100644 --- a/internal/db/bundb/instance.go +++ b/internal/db/bundb/instance.go @@ -161,7 +161,7 @@ func (i *instanceDB) GetInstance(ctx context.Context, domain string) (*gtsmodel. var err error // Normalize the domain as punycode - domain, err = util.Punify_(domain) + domain, err = util.Punify(domain) if err != nil { return nil, gtserror.Newf("error punifying domain %s: %w", domain, err) } @@ -268,7 +268,7 @@ func (i *instanceDB) PutInstance(ctx context.Context, instance *gtsmodel.Instanc // Normalize the domain as punycode, note the extra // validation step for domain name write operations. - instance.Domain, err = util.PunifyValidate(instance.Domain) + instance.Domain, err = util.PunifySafely(instance.Domain) if err != nil { return gtserror.Newf("error punifying domain %s: %w", instance.Domain, err) } @@ -285,7 +285,7 @@ func (i *instanceDB) UpdateInstance(ctx context.Context, instance *gtsmodel.Inst // Normalize the domain as punycode, note the extra // validation step for domain name write operations. - instance.Domain, err = util.PunifyValidate(instance.Domain) + instance.Domain, err = util.PunifySafely(instance.Domain) if err != nil { return gtserror.Newf("error punifying domain %s: %w", instance.Domain, err) } @@ -356,7 +356,7 @@ func (i *instanceDB) GetInstanceAccounts(ctx context.Context, domain string, max var err error // Normalize the domain as punycode - domain, err = util.Punify_(domain) + domain, err = util.Punify(domain) if err != nil { return nil, gtserror.Newf("error punifying domain %s: %w", domain, err) } diff --git a/internal/subscriptions/domainperms.go b/internal/subscriptions/domainperms.go index 397c186d8..dc4224899 100644 --- a/internal/subscriptions/domainperms.go +++ b/internal/subscriptions/domainperms.go @@ -627,7 +627,7 @@ func permsFromCSV( // Normalize + validate domain. domainRaw := record[*domainI] - domain, err := util.PunifyValidate(domainRaw) + domain, err := util.PunifySafely(domainRaw) if err != nil { l.Warnf("skipping invalid domain %s: %+v", domainRaw, err) continue @@ -700,7 +700,7 @@ func permsFromJSON( // Normalize + validate domain. domainRaw := apiPerm.Domain.Domain - domain, err := util.PunifyValidate(domainRaw) + domain, err := util.PunifySafely(domainRaw) if err != nil { l.Warnf("skipping invalid domain %s: %+v", domainRaw, err) continue @@ -756,7 +756,7 @@ func permsFromPlain( for _, domainRaw := range domains { // Normalize + validate domain as ASCII. - domain, err := util.PunifyValidate(domainRaw) + domain, err := util.PunifySafely(domainRaw) if err != nil { l.Warnf("skipping invalid domain %s: %+v", domainRaw, err) continue diff --git a/internal/transport/finger.go b/internal/transport/finger.go index 14e0350ec..f82719245 100644 --- a/internal/transport/finger.go +++ b/internal/transport/finger.go @@ -76,7 +76,7 @@ func prepWebfingerReq(ctx context.Context, loc, domain, username string) (*http. func (t *transport) Finger(ctx context.Context, targetUsername string, targetDomain string) ([]byte, error) { // Remotes seem to prefer having their punycode // domain used in webfinger requests, so let's oblige. - punyDomain, err := util.Punify_(targetDomain) + punyDomain, err := util.Punify(targetDomain) if err != nil { return nil, gtserror.Newf("error punifying %s: %w", targetDomain, err) } diff --git a/internal/util/domain.go b/internal/util/domain.go index 9bc2f1133..c64cc65d7 100644 --- a/internal/util/domain.go +++ b/internal/util/domain.go @@ -31,15 +31,32 @@ var ( verifyProfile = *idna.Lookup ) -// PunifyValidate validates the provided domain name, +// PunifySafely validates the provided domain name, // and converts unicode chars to ASCII, i.e. punified form. -func PunifyValidate(domain string) (string, error) { - domain, err := verifyProfile.ToASCII(domain) - return strings.ToLower(domain), err +func PunifySafely(domain string) (string, error) { + if i := strings.LastIndexByte(domain, ':'); i >= 0 { + + // If there is a port included in domain, we + // strip it as colon is invalid in a hostname. + domain, port := domain[:i], domain[i:] + domain, err := verifyProfile.ToASCII(domain) + if err != nil { + return "", err + } + + // Then rebuild with port after. + domain = strings.ToLower(domain) + return domain + port, nil + } else { //nolint:revive + + // Otherwise we just punify domain as-is. + domain, err := verifyProfile.ToASCII(domain) + return strings.ToLower(domain), err + } } -// Punify is a faster form of ValidatePunify() without validation. -func Punify_(domain string) (string, error) { +// Punify is a faster form of PunifySafely() without validation. +func Punify(domain string) (string, error) { domain, err := punifyProfile.ToASCII(domain) return strings.ToLower(domain), err } @@ -62,7 +79,7 @@ func URIMatches(expect *url.URL, uris ...*url.URL) (ok bool, err error) { *punyURI = *expect // Set punified expected URL host. - punyURI.Host, err = Punify_(expect.Host) + punyURI.Host, err = Punify(expect.Host) if err != nil { return false, err } @@ -76,7 +93,7 @@ func URIMatches(expect *url.URL, uris ...*url.URL) (ok bool, err error) { // strings to check against. for _, uri := range uris { *punyURI = *uri - punyURI.Host, err = Punify_(uri.Host) + punyURI.Host, err = Punify(uri.Host) if err != nil { return false, err } @@ -91,12 +108,11 @@ func URIMatches(expect *url.URL, uris ...*url.URL) (ok bool, err error) { return false, nil } -// PunifyURIToStr returns a new copy of URI with the -// 'host' part converted to punycode with DomainToASCII. -// This can potentially be expensive doing extra domain -// verification for storage, for simple checks prefer URIMatches(). +// PunifyURI returns a new copy of URI with the 'host' +// part converted to punycode with PunifySafely(). +// For simple comparisons prefer the faster URIMatches(). func PunifyURI(in *url.URL) (*url.URL, error) { - punyHost, err := PunifyValidate(in.Host) + punyHost, err := PunifySafely(in.Host) if err != nil { return nil, err } @@ -107,11 +123,10 @@ func PunifyURI(in *url.URL) (*url.URL, error) { } // PunifyURIToStr returns given URI serialized with the -// 'host' part converted to punycode with DomainToASCII. -// This can potentially be expensive doing extra domain -// verification for storage, for simple checks prefer URIMatches(). +// 'host' part converted to punycode with PunifySafely(). +// For simple comparisons prefer the faster URIMatches(). func PunifyURIToStr(in *url.URL) (string, error) { - punyHost, err := PunifyValidate(in.Host) + punyHost, err := PunifySafely(in.Host) if err != nil { return "", err } diff --git a/internal/util/puny_test.go b/internal/util/domain_test.go similarity index 100% rename from internal/util/puny_test.go rename to internal/util/domain_test.go