go-ssb-room/roomsrv/server.go

209 lines
4.6 KiB
Go
Raw Normal View History

// SPDX-FileCopyrightText: 2021 The NGI Pointer Secure-Scuttlebutt Team of 2020/2021
//
2021-01-25 12:23:03 +00:00
// SPDX-License-Identifier: MIT
2021-03-16 08:10:44 +00:00
// Package roomsrv implements the muxrpc server for all the room related code.
// It ties the muxrpc/handlers packages and network listeners together.
2021-01-25 12:23:03 +00:00
package roomsrv
import (
"context"
"encoding/base64"
"fmt"
"net"
"os"
"os/user"
"path/filepath"
"sync"
"github.com/ssbc/go-muxrpc/v2/typemux"
"github.com/ssbc/go-netwrap"
kitlog "go.mindeco.de/log"
"go.mindeco.de/log/level"
2021-01-25 12:23:03 +00:00
refs "github.com/ssbc/go-ssb-refs"
"github.com/ssbc/go-ssb-room/v2/internal/maybemod/keys"
"github.com/ssbc/go-ssb-room/v2/internal/maybemod/multicloser"
"github.com/ssbc/go-ssb-room/v2/internal/network"
"github.com/ssbc/go-ssb-room/v2/internal/repo"
"github.com/ssbc/go-ssb-room/v2/internal/signinwithssb"
"github.com/ssbc/go-ssb-room/v2/roomdb"
"github.com/ssbc/go-ssb-room/v2/roomstate"
2021-01-25 12:23:03 +00:00
)
type Server struct {
logger kitlog.Logger
rootCtx context.Context
Shutdown context.CancelFunc
closers multicloser.Closer
closed bool
closedMu *sync.Mutex
2021-01-25 12:23:03 +00:00
closeErr error
Network network.Network
appKey []byte
listenAddr net.Addr
2021-01-25 15:35:22 +00:00
wsAddr string
2021-01-25 12:23:03 +00:00
dialer netwrap.Dialer
netInfo network.ServerEndpointDetails
2021-01-25 15:35:22 +00:00
loadUnixSock bool
2021-01-28 14:06:51 +00:00
repo repo.Interface
2021-01-25 12:23:03 +00:00
repoPath string
2021-01-25 15:35:22 +00:00
keyPair *keys.KeyPair
2021-01-25 12:23:03 +00:00
networkConnTracker network.ConnTracker
preSecureWrappers []netwrap.ConnWrapper
postSecureWrappers []netwrap.ConnWrapper
public typemux.HandlerMux
master typemux.HandlerMux
2021-01-25 12:23:03 +00:00
StateManager *roomstate.Manager
2021-04-07 08:53:57 +00:00
Members roomdb.MembersService
DeniedKeys roomdb.DeniedKeysService
Aliases roomdb.AliasesService
2021-03-24 10:39:08 +00:00
authWithSSB roomdb.AuthWithSSBService
authWithSSBBridge *signinwithssb.SignalBridge
2021-04-06 09:29:00 +00:00
Config roomdb.RoomConfig
2021-01-25 15:35:22 +00:00
}
func (s Server) Whoami() refs.FeedRef {
return s.keyPair.Feed
2021-01-25 12:23:03 +00:00
}
func New(
2021-03-19 10:51:06 +00:00
membersdb roomdb.MembersService,
2021-04-07 08:53:57 +00:00
deniedkeysdb roomdb.DeniedKeysService,
2021-03-19 10:51:06 +00:00
aliasdb roomdb.AliasesService,
2021-03-24 10:39:08 +00:00
awsdb roomdb.AuthWithSSBService,
bridge *signinwithssb.SignalBridge,
config roomdb.RoomConfig,
netInfo network.ServerEndpointDetails,
opts ...Option,
) (*Server, error) {
2021-01-25 12:23:03 +00:00
var s Server
s.closedMu = new(sync.Mutex)
2021-01-25 12:23:03 +00:00
2021-03-19 10:51:06 +00:00
s.Members = membersdb
2021-04-07 08:53:57 +00:00
s.DeniedKeys = deniedkeysdb
s.Aliases = aliasdb
s.Config = config
2021-03-24 10:39:08 +00:00
s.authWithSSB = awsdb
s.authWithSSBBridge = bridge
2021-03-24 10:39:08 +00:00
s.netInfo = netInfo
2021-01-25 12:23:03 +00:00
for i, opt := range opts {
err := opt(&s)
if err != nil {
return nil, fmt.Errorf("error applying option #%d: %w", i, err)
}
}
if s.repoPath == "" {
u, err := user.Current()
if err != nil {
return nil, fmt.Errorf("error getting info on current user: %w", err)
}
s.repoPath = filepath.Join(u.HomeDir, ".ssb-go")
}
if s.appKey == nil {
ak, err := base64.StdEncoding.DecodeString("1KHLiKZvAvjbY1ziZEHMXawbCEIM6qwjCDm3VYRan/s=")
if err != nil {
return nil, fmt.Errorf("failed to decode default appkey: %w", err)
}
s.appKey = ak
}
if s.dialer == nil {
s.dialer = netwrap.Dial
}
var err error
s.listenAddr, err = net.ResolveTCPAddr("tcp", s.netInfo.ListenAddressMUXRPC)
if err != nil {
return nil, err
2021-01-25 12:23:03 +00:00
}
if s.logger == nil {
logger := kitlog.NewLogfmtLogger(kitlog.NewSyncWriter(os.Stdout))
logger = kitlog.With(logger, "ts", kitlog.DefaultTimestampUTC, "caller", kitlog.DefaultCaller)
s.logger = logger
}
s.public = typemux.New(kitlog.With(s.logger, "mux", "public"))
s.master = typemux.New(kitlog.With(s.logger, "mux", "master"))
2021-01-25 12:23:03 +00:00
if s.rootCtx == nil {
s.rootCtx, s.Shutdown = context.WithCancel(context.Background())
}
2021-01-28 14:06:51 +00:00
s.repo = repo.New(s.repoPath)
2021-01-25 12:23:03 +00:00
2021-01-25 15:35:22 +00:00
if s.keyPair == nil {
2021-01-25 12:23:03 +00:00
var err error
2021-01-28 14:06:51 +00:00
s.keyPair, err = repo.DefaultKeyPair(s.repo)
2021-01-25 12:23:03 +00:00
if err != nil {
return nil, fmt.Errorf("roomsrv: failed to get keypair: %w", err)
2021-01-25 12:23:03 +00:00
}
}
s.netInfo.RoomID = s.keyPair.Feed
2021-04-22 18:00:39 +00:00
s.StateManager = roomstate.NewManager(s.logger)
s.initHandlers()
2021-01-25 15:35:22 +00:00
if err := s.initNetwork(); err != nil {
2021-01-25 12:23:03 +00:00
return nil, err
}
2021-01-25 15:35:22 +00:00
if s.loadUnixSock {
if err := s.initUnixSock(); err != nil {
return nil, err
}
}
2021-01-25 12:23:03 +00:00
return &s, nil
}
// Close closes the bot by stopping network connections and closing the internal databases
func (s *Server) Close() error {
s.closedMu.Lock()
defer s.closedMu.Unlock()
if s.closed {
return s.closeErr
}
closeEvt := kitlog.With(s.logger, "event", "tunserv closing")
s.closed = true
if s.Network != nil {
if err := s.Network.Close(); err != nil {
s.closeErr = fmt.Errorf("sbot: failed to close own network node: %w", err)
return s.closeErr
}
s.Network.GetConnTracker().CloseAll()
level.Debug(closeEvt).Log("msg", "connections closed")
}
if err := s.closers.Close(); err != nil {
s.closeErr = err
return s.closeErr
}
level.Info(closeEvt).Log("msg", "closers closed")
return nil
}