gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

webfingerget_test.go (7774B)


      1 // GoToSocial
      2 // Copyright (C) GoToSocial Authors admin@gotosocial.org
      3 // SPDX-License-Identifier: AGPL-3.0-or-later
      4 //
      5 // This program is free software: you can redistribute it and/or modify
      6 // it under the terms of the GNU Affero General Public License as published by
      7 // the Free Software Foundation, either version 3 of the License, or
      8 // (at your option) any later version.
      9 //
     10 // This program is distributed in the hope that it will be useful,
     11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 // GNU Affero General Public License for more details.
     14 //
     15 // You should have received a copy of the GNU Affero General Public License
     16 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18 package webfinger_test
     19 
     20 import (
     21 	"bytes"
     22 	"context"
     23 	"crypto/rand"
     24 	"crypto/rsa"
     25 	"encoding/json"
     26 	"fmt"
     27 	"io"
     28 	"net/http"
     29 	"net/http/httptest"
     30 	"testing"
     31 
     32 	"github.com/stretchr/testify/suite"
     33 	"github.com/superseriousbusiness/gotosocial/internal/ap"
     34 	apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
     35 	"github.com/superseriousbusiness/gotosocial/internal/api/wellknown/webfinger"
     36 	"github.com/superseriousbusiness/gotosocial/internal/config"
     37 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
     38 	"github.com/superseriousbusiness/gotosocial/internal/processing"
     39 	"github.com/superseriousbusiness/gotosocial/testrig"
     40 )
     41 
     42 type WebfingerGetTestSuite struct {
     43 	WebfingerStandardTestSuite
     44 }
     45 
     46 func (suite *WebfingerGetTestSuite) finger(requestPath string) string {
     47 	// Set up the request.
     48 	recorder := httptest.NewRecorder()
     49 	ctx, _ := testrig.CreateGinTestContext(recorder, nil)
     50 	ctx.Request = httptest.NewRequest(http.MethodGet, requestPath, nil)
     51 	ctx.Request.Header.Set("accept", "application/jrd+json")
     52 
     53 	// Trigger the handler.
     54 	suite.webfingerModule.WebfingerGETRequest(ctx)
     55 
     56 	// Read the result + return it
     57 	// as nicely indented JSON.
     58 	result := recorder.Result()
     59 	defer result.Body.Close()
     60 
     61 	// Result should always use the
     62 	// webfinger content-type.
     63 	if ct := result.Header.Get("content-type"); ct != string(apiutil.AppJRDJSON) {
     64 		suite.FailNow("", "expected content type %s, got %s", apiutil.AppJRDJSON, ct)
     65 	}
     66 
     67 	b, err := io.ReadAll(result.Body)
     68 	if err != nil {
     69 		suite.FailNow(err.Error())
     70 	}
     71 
     72 	var dst bytes.Buffer
     73 	if err := json.Indent(&dst, b, "", "  "); err != nil {
     74 		suite.FailNow(err.Error())
     75 	}
     76 
     77 	return dst.String()
     78 }
     79 
     80 func (suite *WebfingerGetTestSuite) funkifyAccountDomain(host string, accountDomain string) *gtsmodel.Account {
     81 	// Reset suite structs + config
     82 	// to new host + account domain.
     83 	config.SetHost(host)
     84 	config.SetAccountDomain(accountDomain)
     85 	suite.processor = processing.NewProcessor(suite.tc, suite.federator, testrig.NewTestOauthServer(suite.db), testrig.NewTestMediaManager(&suite.state), &suite.state, suite.emailSender)
     86 	suite.webfingerModule = webfinger.New(suite.processor)
     87 
     88 	// Generate a new account for the
     89 	// tester, which uses the new host.
     90 	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
     91 	if err != nil {
     92 		panic(err)
     93 	}
     94 	publicKey := &privateKey.PublicKey
     95 
     96 	targetAccount := &gtsmodel.Account{
     97 		ID:                    "01FG1K8EA7SYHEC7V6XKVNC4ZA",
     98 		Username:              "new_account_domain_user",
     99 		Privacy:               gtsmodel.VisibilityDefault,
    100 		URI:                   "http://" + host + "/users/new_account_domain_user",
    101 		URL:                   "http://" + host + "/@new_account_domain_user",
    102 		InboxURI:              "http://" + host + "/users/new_account_domain_user/inbox",
    103 		OutboxURI:             "http://" + host + "/users/new_account_domain_user/outbox",
    104 		FollowingURI:          "http://" + host + "/users/new_account_domain_user/following",
    105 		FollowersURI:          "http://" + host + "/users/new_account_domain_user/followers",
    106 		FeaturedCollectionURI: "http://" + host + "/users/new_account_domain_user/collections/featured",
    107 		ActorType:             ap.ActorPerson,
    108 		PrivateKey:            privateKey,
    109 		PublicKey:             publicKey,
    110 		PublicKeyURI:          "http://" + host + "/users/new_account_domain_user/main-key",
    111 	}
    112 
    113 	if err := suite.db.PutAccount(context.Background(), targetAccount); err != nil {
    114 		suite.FailNow(err.Error())
    115 	}
    116 
    117 	return targetAccount
    118 }
    119 
    120 func (suite *WebfingerGetTestSuite) TestFingerUser() {
    121 	targetAccount := suite.testAccounts["local_account_1"]
    122 	requestPath := fmt.Sprintf("/%s?resource=acct:%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, config.GetHost())
    123 
    124 	resp := suite.finger(requestPath)
    125 	suite.Equal(`{
    126   "subject": "acct:the_mighty_zork@localhost:8080",
    127   "aliases": [
    128     "http://localhost:8080/users/the_mighty_zork",
    129     "http://localhost:8080/@the_mighty_zork"
    130   ],
    131   "links": [
    132     {
    133       "rel": "http://webfinger.net/rel/profile-page",
    134       "type": "text/html",
    135       "href": "http://localhost:8080/@the_mighty_zork"
    136     },
    137     {
    138       "rel": "self",
    139       "type": "application/activity+json",
    140       "href": "http://localhost:8080/users/the_mighty_zork"
    141     }
    142   ]
    143 }`, resp)
    144 }
    145 
    146 func (suite *WebfingerGetTestSuite) TestFingerUserWithDifferentAccountDomainByHost() {
    147 	targetAccount := suite.funkifyAccountDomain("gts.example.org", "example.org")
    148 	requestPath := fmt.Sprintf("/%s?resource=acct:%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, config.GetHost())
    149 
    150 	resp := suite.finger(requestPath)
    151 	suite.Equal(`{
    152   "subject": "acct:new_account_domain_user@example.org",
    153   "aliases": [
    154     "http://gts.example.org/users/new_account_domain_user",
    155     "http://gts.example.org/@new_account_domain_user"
    156   ],
    157   "links": [
    158     {
    159       "rel": "http://webfinger.net/rel/profile-page",
    160       "type": "text/html",
    161       "href": "http://gts.example.org/@new_account_domain_user"
    162     },
    163     {
    164       "rel": "self",
    165       "type": "application/activity+json",
    166       "href": "http://gts.example.org/users/new_account_domain_user"
    167     }
    168   ]
    169 }`, resp)
    170 }
    171 
    172 func (suite *WebfingerGetTestSuite) TestFingerUserWithDifferentAccountDomainByAccountDomain() {
    173 	targetAccount := suite.funkifyAccountDomain("gts.example.org", "example.org")
    174 	requestPath := fmt.Sprintf("/%s?resource=acct:%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, config.GetAccountDomain())
    175 
    176 	resp := suite.finger(requestPath)
    177 	suite.Equal(`{
    178   "subject": "acct:new_account_domain_user@example.org",
    179   "aliases": [
    180     "http://gts.example.org/users/new_account_domain_user",
    181     "http://gts.example.org/@new_account_domain_user"
    182   ],
    183   "links": [
    184     {
    185       "rel": "http://webfinger.net/rel/profile-page",
    186       "type": "text/html",
    187       "href": "http://gts.example.org/@new_account_domain_user"
    188     },
    189     {
    190       "rel": "self",
    191       "type": "application/activity+json",
    192       "href": "http://gts.example.org/users/new_account_domain_user"
    193     }
    194   ]
    195 }`, resp)
    196 }
    197 
    198 func (suite *WebfingerGetTestSuite) TestFingerUserWithoutAcct() {
    199 	// Leave out the 'acct:' part in the request path;
    200 	// the handler should be generous + still work OK.
    201 	targetAccount := suite.testAccounts["local_account_1"]
    202 	requestPath := fmt.Sprintf("/%s?resource=%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, config.GetHost())
    203 
    204 	resp := suite.finger(requestPath)
    205 	suite.Equal(`{
    206   "subject": "acct:the_mighty_zork@localhost:8080",
    207   "aliases": [
    208     "http://localhost:8080/users/the_mighty_zork",
    209     "http://localhost:8080/@the_mighty_zork"
    210   ],
    211   "links": [
    212     {
    213       "rel": "http://webfinger.net/rel/profile-page",
    214       "type": "text/html",
    215       "href": "http://localhost:8080/@the_mighty_zork"
    216     },
    217     {
    218       "rel": "self",
    219       "type": "application/activity+json",
    220       "href": "http://localhost:8080/users/the_mighty_zork"
    221     }
    222   ]
    223 }`, resp)
    224 }
    225 
    226 func TestWebfingerGetTestSuite(t *testing.T) {
    227 	suite.Run(t, new(WebfingerGetTestSuite))
    228 }