gtsocial-umbx

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

wellknown.go (4808B)


      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 fedi
     19 
     20 import (
     21 	"context"
     22 	"fmt"
     23 
     24 	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
     25 	"github.com/superseriousbusiness/gotosocial/internal/config"
     26 	"github.com/superseriousbusiness/gotosocial/internal/gtserror"
     27 )
     28 
     29 const (
     30 	hostMetaXMLNS                   = "http://docs.oasis-open.org/ns/xri/xrd-1.0"
     31 	hostMetaRel                     = "lrdd"
     32 	hostMetaType                    = "application/xrd+xml"
     33 	hostMetaTemplate                = ".well-known/webfinger?resource={uri}"
     34 	nodeInfoVersion                 = "2.0"
     35 	nodeInfoSoftwareName            = "gotosocial"
     36 	nodeInfoRel                     = "http://nodeinfo.diaspora.software/ns/schema/" + nodeInfoVersion
     37 	webfingerProfilePage            = "http://webfinger.net/rel/profile-page"
     38 	webFingerProfilePageContentType = "text/html"
     39 	webfingerSelf                   = "self"
     40 	webFingerSelfContentType        = "application/activity+json"
     41 	webfingerAccount                = "acct"
     42 )
     43 
     44 var (
     45 	nodeInfoProtocols = []string{"activitypub"}
     46 	nodeInfoInbound   = []string{}
     47 	nodeInfoOutbound  = []string{}
     48 	nodeInfoMetadata  = make(map[string]interface{})
     49 )
     50 
     51 // NodeInfoRelGet returns a well known response giving the path to node info.
     52 func (p *Processor) NodeInfoRelGet(ctx context.Context) (*apimodel.WellKnownResponse, gtserror.WithCode) {
     53 	protocol := config.GetProtocol()
     54 	host := config.GetHost()
     55 
     56 	return &apimodel.WellKnownResponse{
     57 		Links: []apimodel.Link{
     58 			{
     59 				Rel:  nodeInfoRel,
     60 				Href: fmt.Sprintf("%s://%s/nodeinfo/%s", protocol, host, nodeInfoVersion),
     61 			},
     62 		},
     63 	}, nil
     64 }
     65 
     66 // NodeInfoGet returns a node info struct in response to a node info request.
     67 func (p *Processor) NodeInfoGet(ctx context.Context) (*apimodel.Nodeinfo, gtserror.WithCode) {
     68 	host := config.GetHost()
     69 
     70 	userCount, err := p.state.DB.CountInstanceUsers(ctx, host)
     71 	if err != nil {
     72 		return nil, gtserror.NewErrorInternalError(err)
     73 	}
     74 
     75 	postCount, err := p.state.DB.CountInstanceStatuses(ctx, host)
     76 	if err != nil {
     77 		return nil, gtserror.NewErrorInternalError(err)
     78 	}
     79 
     80 	return &apimodel.Nodeinfo{
     81 		Version: nodeInfoVersion,
     82 		Software: apimodel.NodeInfoSoftware{
     83 			Name:    nodeInfoSoftwareName,
     84 			Version: config.GetSoftwareVersion(),
     85 		},
     86 		Protocols: nodeInfoProtocols,
     87 		Services: apimodel.NodeInfoServices{
     88 			Inbound:  nodeInfoInbound,
     89 			Outbound: nodeInfoOutbound,
     90 		},
     91 		OpenRegistrations: config.GetAccountsRegistrationOpen(),
     92 		Usage: apimodel.NodeInfoUsage{
     93 			Users: apimodel.NodeInfoUsers{
     94 				Total: userCount,
     95 			},
     96 			LocalPosts: postCount,
     97 		},
     98 		Metadata: nodeInfoMetadata,
     99 	}, nil
    100 }
    101 
    102 // HostMetaGet returns a host-meta struct in response to a host-meta request.
    103 func (p *Processor) HostMetaGet() *apimodel.HostMeta {
    104 	protocol := config.GetProtocol()
    105 	host := config.GetHost()
    106 	return &apimodel.HostMeta{
    107 		XMLNS: hostMetaXMLNS,
    108 		Link: []apimodel.Link{
    109 			{
    110 				Rel:      hostMetaRel,
    111 				Type:     hostMetaType,
    112 				Template: fmt.Sprintf("%s://%s/%s", protocol, host, hostMetaTemplate),
    113 			},
    114 		},
    115 	}
    116 }
    117 
    118 // WebfingerGet handles the GET for a webfinger resource. Most commonly, it will be used for returning account lookups.
    119 func (p *Processor) WebfingerGet(ctx context.Context, requestedUsername string) (*apimodel.WellKnownResponse, gtserror.WithCode) {
    120 	// Get the local account the request is referring to.
    121 	requestedAccount, err := p.state.DB.GetAccountByUsernameDomain(ctx, requestedUsername, "")
    122 	if err != nil {
    123 		return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err))
    124 	}
    125 
    126 	return &apimodel.WellKnownResponse{
    127 		Subject: webfingerAccount + ":" + requestedAccount.Username + "@" + config.GetAccountDomain(),
    128 		Aliases: []string{
    129 			requestedAccount.URI,
    130 			requestedAccount.URL,
    131 		},
    132 		Links: []apimodel.Link{
    133 			{
    134 				Rel:  webfingerProfilePage,
    135 				Type: webFingerProfilePageContentType,
    136 				Href: requestedAccount.URL,
    137 			},
    138 			{
    139 				Rel:  webfingerSelf,
    140 				Type: webFingerSelfContentType,
    141 				Href: requestedAccount.URI,
    142 			},
    143 		},
    144 	}, nil
    145 }