mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-30 17:02:25 -05:00 
			
		
		
		
	nodeinfo compliance (#61)
This commit is contained in:
		
					parent
					
						
							
								16e486ad96
							
						
					
				
			
			
				commit
				
					
						c1e107266f
					
				
			
		
					 14 changed files with 285 additions and 46 deletions
				
			
		|  | @ -1,39 +0,0 @@ | ||||||
| package model |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
|    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/>. |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| // WebfingerAccountResponse represents the response to a webfinger request for an 'acct' resource. |  | ||||||
| // For example, it would be returned from https://example.org/.well-known/webfinger?resource=acct:some_username@example.org |  | ||||||
| // |  | ||||||
| // See https://webfinger.net/ |  | ||||||
| type WebfingerAccountResponse struct { |  | ||||||
| 	Subject string          `json:"subject"` |  | ||||||
| 	Aliases []string        `json:"aliases"` |  | ||||||
| 	Links   []WebfingerLink `json:"links"` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // WebfingerLink represents one 'link' in a slice of webfinger links returned from a lookup request. |  | ||||||
| // |  | ||||||
| // See https://webfinger.net/ |  | ||||||
| type WebfingerLink struct { |  | ||||||
| 	Rel      string `json:"rel"` |  | ||||||
| 	Type     string `json:"type,omitempty"` |  | ||||||
| 	Href     string `json:"href,omitempty"` |  | ||||||
| 	Template string `json:"template,omitempty"` |  | ||||||
| } |  | ||||||
							
								
								
									
										78
									
								
								internal/api/model/well-known.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								internal/api/model/well-known.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,78 @@ | ||||||
|  | /* | ||||||
|  |    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 model | ||||||
|  | 
 | ||||||
|  | // WellKnownResponse represents the response to either a webfinger request for an 'acct' resource, or a request to nodeinfo. | ||||||
|  | // For example, it would be returned from https://example.org/.well-known/webfinger?resource=acct:some_username@example.org | ||||||
|  | // | ||||||
|  | // See https://webfinger.net/ | ||||||
|  | type WellKnownResponse struct { | ||||||
|  | 	Subject string   `json:"subject,omitempty"` | ||||||
|  | 	Aliases []string `json:"aliases,omitempty"` | ||||||
|  | 	Links   []Link   `json:"links,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Link represents one 'link' in a slice of links returned from a lookup request. | ||||||
|  | // | ||||||
|  | // See https://webfinger.net/ | ||||||
|  | type Link struct { | ||||||
|  | 	Rel      string `json:"rel"` | ||||||
|  | 	Type     string `json:"type,omitempty"` | ||||||
|  | 	Href     string `json:"href,omitempty"` | ||||||
|  | 	Template string `json:"template,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Nodeinfo represents a version 2.1 or version 2.0 nodeinfo schema. | ||||||
|  | // See: https://nodeinfo.diaspora.software/schema.html | ||||||
|  | type Nodeinfo struct { | ||||||
|  | 	// The schema version | ||||||
|  | 	Version string `json:"version"` | ||||||
|  | 	// Metadata about server software in use. | ||||||
|  | 	Software NodeInfoSoftware `json:"software"` | ||||||
|  | 	// The protocols supported on this server. | ||||||
|  | 	Protocols []string `json:"protocols"` | ||||||
|  | 	// The third party sites this server can connect to via their application API. | ||||||
|  | 	Services NodeInfoServices `json:"services"` | ||||||
|  | 	// Whether this server allows open self-registration. | ||||||
|  | 	OpenRegistrations bool `json:"openRegistrations"` | ||||||
|  | 	// Usage statistics for this server. | ||||||
|  | 	Usage NodeInfoUsage `json:"usage"` | ||||||
|  | 	// Free form key value pairs for software specific values. Clients should not rely on any specific key present. | ||||||
|  | 	Metadata map[string]interface{} `json:"metadata"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NodeInfoSoftware represents the name and version number of the software of this node. | ||||||
|  | type NodeInfoSoftware struct { | ||||||
|  | 	Name    string `json:"name"` | ||||||
|  | 	Version string `json:"version"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NodeInfoServices represents inbound and outbound services that this node offers connections to. | ||||||
|  | type NodeInfoServices struct { | ||||||
|  | 	Inbound  []string `json:"inbound"` | ||||||
|  | 	Outbound []string `json:"outbound"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NodeInfoUsage represents usage information about this server, such as number of users. | ||||||
|  | type NodeInfoUsage struct { | ||||||
|  | 	Users NodeInfoUsers `json:"users"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NodeInfoUsers is a stub for usage information, currently empty. | ||||||
|  | type NodeInfoUsers struct{} | ||||||
							
								
								
									
										59
									
								
								internal/api/s2s/nodeinfo/nodeinfo.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								internal/api/s2s/nodeinfo/nodeinfo.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | ||||||
|  | /* | ||||||
|  |    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 nodeinfo | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"net/http" | ||||||
|  | 
 | ||||||
|  | 	"github.com/sirupsen/logrus" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/api" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/config" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/processing" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/router" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	// NodeInfoWellKnownPath is the base path for serving responses to nodeinfo lookup requests. | ||||||
|  | 	NodeInfoWellKnownPath = ".well-known/nodeinfo" | ||||||
|  | 	// NodeInfoBasePath is the path for serving nodeinfo responses. | ||||||
|  | 	NodeInfoBasePath      = "/nodeinfo/2.0" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Module implements the FederationModule interface | ||||||
|  | type Module struct { | ||||||
|  | 	config    *config.Config | ||||||
|  | 	processor processing.Processor | ||||||
|  | 	log       *logrus.Logger | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // New returns a new nodeinfo module | ||||||
|  | func New(config *config.Config, processor processing.Processor, log *logrus.Logger) api.FederationModule { | ||||||
|  | 	return &Module{ | ||||||
|  | 		config:    config, | ||||||
|  | 		processor: processor, | ||||||
|  | 		log:       log, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Route satisfies the FederationModule interface | ||||||
|  | func (m *Module) Route(s router.Router) error { | ||||||
|  | 	s.AttachHandler(http.MethodGet, NodeInfoWellKnownPath, m.NodeInfoWellKnownGETHandler) | ||||||
|  | 	s.AttachHandler(http.MethodGet, NodeInfoBasePath, m.NodeInfoGETHandler) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										44
									
								
								internal/api/s2s/nodeinfo/nodeinfoget.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								internal/api/s2s/nodeinfo/nodeinfoget.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | ||||||
|  | /* | ||||||
|  |    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 nodeinfo | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"net/http" | ||||||
|  | 
 | ||||||
|  | 	"github.com/gin-gonic/gin" | ||||||
|  | 	"github.com/sirupsen/logrus" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // NodeInfoGETHandler returns a compliant nodeinfo response to node info queries. | ||||||
|  | // See: https://nodeinfo.diaspora.software/ | ||||||
|  | func (m *Module) NodeInfoGETHandler(c *gin.Context) { | ||||||
|  | 	l := m.log.WithFields(logrus.Fields{ | ||||||
|  | 		"func":       "NodeInfoGETHandler", | ||||||
|  | 		"user-agent": c.Request.UserAgent(), | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	ni, err := m.processor.GetNodeInfo(c.Request) | ||||||
|  | 	if err != nil { | ||||||
|  | 		l.Debugf("error with get node info request: %s", err) | ||||||
|  | 		c.JSON(err.Code(), err.Safe()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	c.JSON(http.StatusOK, ni) | ||||||
|  | } | ||||||
							
								
								
									
										44
									
								
								internal/api/s2s/nodeinfo/wellknownget.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								internal/api/s2s/nodeinfo/wellknownget.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | ||||||
|  | /* | ||||||
|  |    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 nodeinfo | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"net/http" | ||||||
|  | 
 | ||||||
|  | 	"github.com/gin-gonic/gin" | ||||||
|  | 	"github.com/sirupsen/logrus" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // NodeInfoWellKnownGETHandler returns a well known response to a query to /.well-known/nodeinfo, | ||||||
|  | // directing (but not redirecting...) callers to the NodeInfoGETHandler. | ||||||
|  | func (m *Module) NodeInfoWellKnownGETHandler(c *gin.Context) { | ||||||
|  | 	l := m.log.WithFields(logrus.Fields{ | ||||||
|  | 		"func":       "NodeInfoWellKnownGETHandler", | ||||||
|  | 		"user-agent": c.Request.UserAgent(), | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	niRel, err := m.processor.GetNodeInfoRel(c.Request) | ||||||
|  | 	if err != nil { | ||||||
|  | 		l.Debugf("error with get node info rel request: %s", err) | ||||||
|  | 		c.JSON(err.Code(), err.Safe()) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	c.JSON(http.StatusOK, niRel) | ||||||
|  | } | ||||||
|  | @ -4,5 +4,5 @@ import "github.com/gin-gonic/gin" | ||||||
| 
 | 
 | ||||||
| // ExtraHeaders adds any additional required headers to the response | // ExtraHeaders adds any additional required headers to the response | ||||||
| func (m *Module) ExtraHeaders(c *gin.Context) { | func (m *Module) ExtraHeaders(c *gin.Context) { | ||||||
| 	c.Header("Server", "Mastodon") | 	c.Header("Server", "gotosocial") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -26,6 +26,7 @@ import ( | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/api/client/status" | 	"github.com/superseriousbusiness/gotosocial/internal/api/client/status" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/api/client/streaming" | 	"github.com/superseriousbusiness/gotosocial/internal/api/client/streaming" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/api/client/timeline" | 	"github.com/superseriousbusiness/gotosocial/internal/api/client/timeline" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/api/s2s/nodeinfo" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/api/s2s/user" | 	"github.com/superseriousbusiness/gotosocial/internal/api/s2s/user" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/api/s2s/webfinger" | 	"github.com/superseriousbusiness/gotosocial/internal/api/s2s/webfinger" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/api/security" | 	"github.com/superseriousbusiness/gotosocial/internal/api/security" | ||||||
|  | @ -124,6 +125,7 @@ var Start cliactions.GTSAction = func(ctx context.Context, c *config.Config, log | ||||||
| 	appsModule := app.New(c, processor, log) | 	appsModule := app.New(c, processor, log) | ||||||
| 	followRequestsModule := followrequest.New(c, processor, log) | 	followRequestsModule := followrequest.New(c, processor, log) | ||||||
| 	webfingerModule := webfinger.New(c, processor, log) | 	webfingerModule := webfinger.New(c, processor, log) | ||||||
|  | 	nodeInfoModule := nodeinfo.New(c, processor, log) | ||||||
| 	webBaseModule := web.New(c, processor, log) | 	webBaseModule := web.New(c, processor, log) | ||||||
| 	usersModule := user.New(c, processor, log) | 	usersModule := user.New(c, processor, log) | ||||||
| 	timelineModule := timeline.New(c, processor, log) | 	timelineModule := timeline.New(c, processor, log) | ||||||
|  | @ -155,6 +157,7 @@ var Start cliactions.GTSAction = func(ctx context.Context, c *config.Config, log | ||||||
| 		adminModule, | 		adminModule, | ||||||
| 		statusModule, | 		statusModule, | ||||||
| 		webfingerModule, | 		webfingerModule, | ||||||
|  | 		nodeInfoModule, | ||||||
| 		usersModule, | 		usersModule, | ||||||
| 		timelineModule, | 		timelineModule, | ||||||
| 		notificationModule, | 		notificationModule, | ||||||
|  |  | ||||||
|  | @ -28,6 +28,7 @@ import ( | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/api/client/status" | 	"github.com/superseriousbusiness/gotosocial/internal/api/client/status" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/api/client/streaming" | 	"github.com/superseriousbusiness/gotosocial/internal/api/client/streaming" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/api/client/timeline" | 	"github.com/superseriousbusiness/gotosocial/internal/api/client/timeline" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/api/s2s/nodeinfo" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/api/s2s/user" | 	"github.com/superseriousbusiness/gotosocial/internal/api/s2s/user" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/api/s2s/webfinger" | 	"github.com/superseriousbusiness/gotosocial/internal/api/s2s/webfinger" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/api/security" | 	"github.com/superseriousbusiness/gotosocial/internal/api/security" | ||||||
|  | @ -70,6 +71,7 @@ var Start cliactions.GTSAction = func(ctx context.Context, _ *config.Config, log | ||||||
| 	appsModule := app.New(c, processor, log) | 	appsModule := app.New(c, processor, log) | ||||||
| 	followRequestsModule := followrequest.New(c, processor, log) | 	followRequestsModule := followrequest.New(c, processor, log) | ||||||
| 	webfingerModule := webfinger.New(c, processor, log) | 	webfingerModule := webfinger.New(c, processor, log) | ||||||
|  | 	nodeInfoModule := nodeinfo.New(c, processor, log) | ||||||
| 	webBaseModule := web.New(c, processor, log) | 	webBaseModule := web.New(c, processor, log) | ||||||
| 	usersModule := user.New(c, processor, log) | 	usersModule := user.New(c, processor, log) | ||||||
| 	timelineModule := timeline.New(c, processor, log) | 	timelineModule := timeline.New(c, processor, log) | ||||||
|  | @ -101,6 +103,7 @@ var Start cliactions.GTSAction = func(ctx context.Context, _ *config.Config, log | ||||||
| 		adminModule, | 		adminModule, | ||||||
| 		statusModule, | 		statusModule, | ||||||
| 		webfingerModule, | 		webfingerModule, | ||||||
|  | 		nodeInfoModule, | ||||||
| 		usersModule, | 		usersModule, | ||||||
| 		timelineModule, | 		timelineModule, | ||||||
| 		notificationModule, | 		notificationModule, | ||||||
|  |  | ||||||
|  | @ -59,9 +59,9 @@ type Config struct { | ||||||
| 
 | 
 | ||||||
| 	/* | 	/* | ||||||
| 		Not parsed from .yaml configuration file. | 		Not parsed from .yaml configuration file. | ||||||
| 		For short running commands (admin CLI tools etc). |  | ||||||
| 	*/ | 	*/ | ||||||
| 	AccountCLIFlags map[string]string | 	AccountCLIFlags map[string]string | ||||||
|  | 	SoftwareVersion string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // FromFile returns a new config from a file, or an error if something goes amiss. | // FromFile returns a new config from a file, or an error if something goes amiss. | ||||||
|  | @ -252,6 +252,8 @@ func (c *Config) ParseCLIFlags(f KeyedFlags) error { | ||||||
| 		c.LetsEncryptConfig.EmailAddress = f.String(fn.LetsEncryptEmailAddress) | 		c.LetsEncryptConfig.EmailAddress = f.String(fn.LetsEncryptEmailAddress) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	c.SoftwareVersion = GetDefaults().SoftwareVersion | ||||||
|  | 
 | ||||||
| 	// command-specific flags | 	// command-specific flags | ||||||
| 
 | 
 | ||||||
| 	// admin account CLI flags | 	// admin account CLI flags | ||||||
|  | @ -323,6 +325,7 @@ type Defaults struct { | ||||||
| 	ConfigPath      string | 	ConfigPath      string | ||||||
| 	Host            string | 	Host            string | ||||||
| 	Protocol        string | 	Protocol        string | ||||||
|  | 	SoftwareVersion string | ||||||
| 
 | 
 | ||||||
| 	DbType     string | 	DbType     string | ||||||
| 	DbAddress  string | 	DbAddress  string | ||||||
|  |  | ||||||
|  | @ -1,5 +1,7 @@ | ||||||
| package config | package config | ||||||
| 
 | 
 | ||||||
|  | const softwareVersion = "0.1.0-SNAPSHOT" | ||||||
|  | 
 | ||||||
| // TestDefault returns a default config for testing | // TestDefault returns a default config for testing | ||||||
| func TestDefault() *Config { | func TestDefault() *Config { | ||||||
| 	defaults := GetTestDefaults() | 	defaults := GetTestDefaults() | ||||||
|  | @ -8,6 +10,7 @@ func TestDefault() *Config { | ||||||
| 		ApplicationName: defaults.ApplicationName, | 		ApplicationName: defaults.ApplicationName, | ||||||
| 		Host:            defaults.Host, | 		Host:            defaults.Host, | ||||||
| 		Protocol:        defaults.Protocol, | 		Protocol:        defaults.Protocol, | ||||||
|  | 		SoftwareVersion: defaults.SoftwareVersion, | ||||||
| 		DBConfig: &DBConfig{ | 		DBConfig: &DBConfig{ | ||||||
| 			Type:            defaults.DbType, | 			Type:            defaults.DbType, | ||||||
| 			Address:         defaults.DbAddress, | 			Address:         defaults.DbAddress, | ||||||
|  | @ -62,6 +65,7 @@ func Default() *Config { | ||||||
| 		ApplicationName: defaults.ApplicationName, | 		ApplicationName: defaults.ApplicationName, | ||||||
| 		Host:            defaults.Host, | 		Host:            defaults.Host, | ||||||
| 		Protocol:        defaults.Protocol, | 		Protocol:        defaults.Protocol, | ||||||
|  | 		SoftwareVersion: defaults.SoftwareVersion, | ||||||
| 		DBConfig: &DBConfig{ | 		DBConfig: &DBConfig{ | ||||||
| 			Type:            defaults.DbType, | 			Type:            defaults.DbType, | ||||||
| 			Address:         defaults.DbAddress, | 			Address:         defaults.DbAddress, | ||||||
|  | @ -117,6 +121,7 @@ func GetDefaults() Defaults { | ||||||
| 		ConfigPath:      "", | 		ConfigPath:      "", | ||||||
| 		Host:            "", | 		Host:            "", | ||||||
| 		Protocol:        "https", | 		Protocol:        "https", | ||||||
|  | 		SoftwareVersion: softwareVersion, | ||||||
| 
 | 
 | ||||||
| 		DbType:     "postgres", | 		DbType:     "postgres", | ||||||
| 		DbAddress:  "localhost", | 		DbAddress:  "localhost", | ||||||
|  | @ -163,6 +168,7 @@ func GetTestDefaults() Defaults { | ||||||
| 		ConfigPath:      "", | 		ConfigPath:      "", | ||||||
| 		Host:            "localhost:8080", | 		Host:            "localhost:8080", | ||||||
| 		Protocol:        "http", | 		Protocol:        "http", | ||||||
|  | 		SoftwareVersion: softwareVersion, | ||||||
| 
 | 
 | ||||||
| 		DbType:     "postgres", | 		DbType:     "postgres", | ||||||
| 		DbAddress:  "localhost", | 		DbAddress:  "localhost", | ||||||
|  |  | ||||||
|  | @ -41,7 +41,7 @@ func (f *federator) FingerRemoteAccount(requestingUsername string, targetUsernam | ||||||
| 		return nil, fmt.Errorf("FingerRemoteAccount: error doing request on behalf of username %s while dereferencing @%s@%s: %s", requestingUsername, targetUsername, targetDomain, err) | 		return nil, fmt.Errorf("FingerRemoteAccount: error doing request on behalf of username %s while dereferencing @%s@%s: %s", requestingUsername, targetUsername, targetDomain, err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	resp := &apimodel.WebfingerAccountResponse{} | 	resp := &apimodel.WellKnownResponse{} | ||||||
| 	if err := json.Unmarshal(b, resp); err != nil { | 	if err := json.Unmarshal(b, resp); err != nil { | ||||||
| 		return nil, fmt.Errorf("FingerRemoteAccount: could not unmarshal server response as WebfingerAccountResponse on behalf of username %s while dereferencing @%s@%s: %s", requestingUsername, targetUsername, targetDomain, err) | 		return nil, fmt.Errorf("FingerRemoteAccount: could not unmarshal server response as WebfingerAccountResponse on behalf of username %s while dereferencing @%s@%s: %s", requestingUsername, targetUsername, targetDomain, err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -265,7 +265,7 @@ func (p *processor) GetFediStatus(requestedUsername string, requestedStatusID st | ||||||
| 	return data, nil | 	return data, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *processor) GetWebfingerAccount(requestedUsername string, request *http.Request) (*apimodel.WebfingerAccountResponse, gtserror.WithCode) { | func (p *processor) GetWebfingerAccount(requestedUsername string, request *http.Request) (*apimodel.WellKnownResponse, gtserror.WithCode) { | ||||||
| 	// get the account the request is referring to | 	// get the account the request is referring to | ||||||
| 	requestedAccount := >smodel.Account{} | 	requestedAccount := >smodel.Account{} | ||||||
| 	if err := p.db.GetLocalAccountByUsername(requestedUsername, requestedAccount); err != nil { | 	if err := p.db.GetLocalAccountByUsername(requestedUsername, requestedAccount); err != nil { | ||||||
|  | @ -273,13 +273,13 @@ func (p *processor) GetWebfingerAccount(requestedUsername string, request *http. | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// return the webfinger representation | 	// return the webfinger representation | ||||||
| 	return &apimodel.WebfingerAccountResponse{ | 	return &apimodel.WellKnownResponse{ | ||||||
| 		Subject: fmt.Sprintf("acct:%s@%s", requestedAccount.Username, p.config.Host), | 		Subject: fmt.Sprintf("acct:%s@%s", requestedAccount.Username, p.config.Host), | ||||||
| 		Aliases: []string{ | 		Aliases: []string{ | ||||||
| 			requestedAccount.URI, | 			requestedAccount.URI, | ||||||
| 			requestedAccount.URL, | 			requestedAccount.URL, | ||||||
| 		}, | 		}, | ||||||
| 		Links: []apimodel.WebfingerLink{ | 		Links: []apimodel.Link{ | ||||||
| 			{ | 			{ | ||||||
| 				Rel:  "http://webfinger.net/rel/profile-page", | 				Rel:  "http://webfinger.net/rel/profile-page", | ||||||
| 				Type: "text/html", | 				Type: "text/html", | ||||||
|  | @ -294,6 +294,37 @@ func (p *processor) GetWebfingerAccount(requestedUsername string, request *http. | ||||||
| 	}, nil | 	}, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (p *processor) GetNodeInfoRel(request *http.Request) (*apimodel.WellKnownResponse, gtserror.WithCode) { | ||||||
|  | 	return &apimodel.WellKnownResponse{ | ||||||
|  | 		Links: []apimodel.Link{ | ||||||
|  | 			{ | ||||||
|  | 				Rel:  "http://nodeinfo.diaspora.software/ns/schema/2.0", | ||||||
|  | 				Href: fmt.Sprintf("%s://%s/nodeinfo/2.0", p.config.Protocol, p.config.Host), | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	}, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p *processor) GetNodeInfo(request *http.Request) (*apimodel.Nodeinfo, gtserror.WithCode) { | ||||||
|  | 	return &apimodel.Nodeinfo{ | ||||||
|  | 		Version: "2.0", | ||||||
|  | 		Software: apimodel.NodeInfoSoftware{ | ||||||
|  | 			Name:    "gotosocial", | ||||||
|  | 			Version: p.config.SoftwareVersion, | ||||||
|  | 		}, | ||||||
|  | 		Protocols: []string{"activitypub"}, | ||||||
|  | 		Services: apimodel.NodeInfoServices{ | ||||||
|  | 			Inbound:  []string{}, | ||||||
|  | 			Outbound: []string{}, | ||||||
|  | 		}, | ||||||
|  | 		OpenRegistrations: p.config.AccountsConfig.OpenRegistration, | ||||||
|  | 		Usage: apimodel.NodeInfoUsage{ | ||||||
|  | 			Users: apimodel.NodeInfoUsers{}, | ||||||
|  | 		}, | ||||||
|  | 		Metadata: make(map[string]interface{}), | ||||||
|  | 	}, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (p *processor) InboxPost(ctx context.Context, w http.ResponseWriter, r *http.Request) (bool, error) { | func (p *processor) InboxPost(ctx context.Context, w http.ResponseWriter, r *http.Request) (bool, error) { | ||||||
| 	contextWithChannel := context.WithValue(ctx, util.APFromFederatorChanKey, p.fromFederator) | 	contextWithChannel := context.WithValue(ctx, util.APFromFederatorChanKey, p.fromFederator) | ||||||
| 	posted, err := p.federator.FederatingActor().PostInbox(contextWithChannel, w, r) | 	posted, err := p.federator.FederatingActor().PostInbox(contextWithChannel, w, r) | ||||||
|  |  | ||||||
|  | @ -169,7 +169,13 @@ type Processor interface { | ||||||
| 	GetFediStatus(requestedUsername string, requestedStatusID string, request *http.Request) (interface{}, gtserror.WithCode) | 	GetFediStatus(requestedUsername string, requestedStatusID string, request *http.Request) (interface{}, gtserror.WithCode) | ||||||
| 
 | 
 | ||||||
| 	// GetWebfingerAccount handles the GET for a webfinger resource. Most commonly, it will be used for returning account lookups. | 	// GetWebfingerAccount handles the GET for a webfinger resource. Most commonly, it will be used for returning account lookups. | ||||||
| 	GetWebfingerAccount(requestedUsername string, request *http.Request) (*apimodel.WebfingerAccountResponse, gtserror.WithCode) | 	GetWebfingerAccount(requestedUsername string, request *http.Request) (*apimodel.WellKnownResponse, gtserror.WithCode) | ||||||
|  | 
 | ||||||
|  | 	// GetNodeInfoRel returns a well known response giving the path to node info. | ||||||
|  | 	GetNodeInfoRel(request *http.Request) (*apimodel.WellKnownResponse, gtserror.WithCode) | ||||||
|  | 
 | ||||||
|  | 	// GetNodeInfo returns a node info struct in response to a node info request. | ||||||
|  | 	GetNodeInfo(request *http.Request) (*apimodel.Nodeinfo, gtserror.WithCode) | ||||||
| 
 | 
 | ||||||
| 	// InboxPost handles POST requests to a user's inbox for new activitypub messages. | 	// InboxPost handles POST requests to a user's inbox for new activitypub messages. | ||||||
| 	// | 	// | ||||||
|  |  | ||||||
|  | @ -543,6 +543,7 @@ func (c *converter) InstanceToMasto(i *gtsmodel.Instance) (*model.Instance, erro | ||||||
| 		mi.URLS = &model.InstanceURLs{ | 		mi.URLS = &model.InstanceURLs{ | ||||||
| 			StreamingAPI: fmt.Sprintf("wss://%s", c.config.Host), | 			StreamingAPI: fmt.Sprintf("wss://%s", c.config.Host), | ||||||
| 		} | 		} | ||||||
|  | 		mi.Version = c.config.SoftwareVersion | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// get the instance account if it exists and just skip if it doesn't | 	// get the instance account if it exists and just skip if it doesn't | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue