nodeinfo compliance (#61)

This commit is contained in:
Tobi Smethurst
2021-06-24 14:26:08 +02:00
committed by GitHub
parent 16e486ad96
commit c1e107266f
14 changed files with 285 additions and 46 deletions

View File

@ -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"`
}

View 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{}

View 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
}

View 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)
}

View 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)
}

View File

@ -4,5 +4,5 @@ import "github.com/gin-gonic/gin"
// ExtraHeaders adds any additional required headers to the response
func (m *Module) ExtraHeaders(c *gin.Context) {
c.Header("Server", "Mastodon")
c.Header("Server", "gotosocial")
}