storj/satellite/peer.go
Jeremy Wharton f61230a670 satellite/console/dbcleanup: create console DB cleanup chore
A chore responsible for purging data from the console DB has been
implemented. Currently, it removes old records for unverified user
accounts. We plan to extend this functionality to include expired
project member invitations in the future.

Resolves #5790
References #5816

Change-Id: I1f3ef62fc96c10a42a383804b3b1d2846d7813f7
2023-05-05 19:11:53 +00:00

284 lines
8.8 KiB
Go

// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package satellite
import (
"context"
"net"
"net/mail"
"net/smtp"
hw "github.com/jtolds/monkit-hw/v2"
"github.com/spacemonkeygo/monkit/v3"
"github.com/zeebo/errs"
"go.uber.org/zap"
"storj.io/common/identity"
"storj.io/private/debug"
"storj.io/private/tagsql"
"storj.io/storj/private/migrate"
"storj.io/storj/private/post"
"storj.io/storj/private/post/oauth2"
"storj.io/storj/private/server"
version_checker "storj.io/storj/private/version/checker"
"storj.io/storj/satellite/accounting"
"storj.io/storj/satellite/accounting/live"
"storj.io/storj/satellite/accounting/projectbwcleanup"
"storj.io/storj/satellite/accounting/rollup"
"storj.io/storj/satellite/accounting/rolluparchive"
"storj.io/storj/satellite/accounting/tally"
"storj.io/storj/satellite/admin"
"storj.io/storj/satellite/analytics"
"storj.io/storj/satellite/attribution"
"storj.io/storj/satellite/audit"
"storj.io/storj/satellite/buckets"
"storj.io/storj/satellite/compensation"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/console/consoleauth"
"storj.io/storj/satellite/console/consoleweb"
"storj.io/storj/satellite/console/dbcleanup"
"storj.io/storj/satellite/console/emailreminders"
"storj.io/storj/satellite/console/restkeys"
"storj.io/storj/satellite/console/userinfo"
"storj.io/storj/satellite/contact"
"storj.io/storj/satellite/gc/bloomfilter"
"storj.io/storj/satellite/gc/sender"
"storj.io/storj/satellite/gracefulexit"
"storj.io/storj/satellite/mailservice"
"storj.io/storj/satellite/mailservice/simulate"
"storj.io/storj/satellite/metabase/rangedloop"
"storj.io/storj/satellite/metabase/zombiedeletion"
"storj.io/storj/satellite/metainfo"
"storj.io/storj/satellite/metainfo/expireddeletion"
"storj.io/storj/satellite/nodeapiversion"
"storj.io/storj/satellite/nodeevents"
"storj.io/storj/satellite/oidc"
"storj.io/storj/satellite/orders"
"storj.io/storj/satellite/overlay"
"storj.io/storj/satellite/overlay/offlinenodes"
"storj.io/storj/satellite/overlay/straynodes"
"storj.io/storj/satellite/payments/accountfreeze"
"storj.io/storj/satellite/payments/billing"
"storj.io/storj/satellite/payments/paymentsconfig"
"storj.io/storj/satellite/payments/storjscan"
"storj.io/storj/satellite/payments/stripe"
"storj.io/storj/satellite/repair/checker"
"storj.io/storj/satellite/repair/queue"
"storj.io/storj/satellite/repair/repairer"
"storj.io/storj/satellite/reputation"
"storj.io/storj/satellite/revocation"
"storj.io/storj/satellite/snopayouts"
)
var mon = monkit.Package()
func init() {
hw.Register(monkit.Default)
}
// DB is the master database for the satellite.
//
// architecture: Master Database
type DB interface {
// MigrateToLatest initializes the database
MigrateToLatest(ctx context.Context) error
// CheckVersion checks the database is the correct version
CheckVersion(ctx context.Context) error
// Close closes the database
Close() error
// PeerIdentities returns a storage for peer identities
PeerIdentities() overlay.PeerIdentities
// OverlayCache returns database for caching overlay information
OverlayCache() overlay.DB
// NodeEvents returns a database for node event information
NodeEvents() nodeevents.DB
// Reputation returns database for audit reputation information
Reputation() reputation.DB
// Attribution returns database for partner keys information
Attribution() attribution.DB
// StoragenodeAccounting returns database for storing information about storagenode use
StoragenodeAccounting() accounting.StoragenodeAccounting
// ProjectAccounting returns database for storing information about project data use
ProjectAccounting() accounting.ProjectAccounting
// RepairQueue returns queue for segments that need repairing
RepairQueue() queue.RepairQueue
// VerifyQueue returns queue for segments chosen for verification
VerifyQueue() audit.VerifyQueue
// ReverifyQueue returns queue for pieces that need audit reverification
ReverifyQueue() audit.ReverifyQueue
// Console returns database for satellite console
Console() console.DB
// OIDC returns the database for OIDC resources.
OIDC() oidc.DB
// Orders returns database for orders
Orders() orders.DB
// Containment returns database for containment
Containment() audit.Containment
// Buckets returns the database to interact with buckets
Buckets() buckets.DB
// GracefulExit returns database for graceful exit
GracefulExit() gracefulexit.DB
// StripeCoinPayments returns stripecoinpayments database.
StripeCoinPayments() stripe.DB
// Billing returns storjscan transactions database.
Billing() billing.TransactionsDB
// Wallets returns storjscan wallets database.
Wallets() storjscan.WalletsDB
// SNOPayouts returns database for payouts.
SNOPayouts() snopayouts.DB
// Compensation tracks storage node compensation
Compensation() compensation.DB
// Revocation tracks revoked macaroons
Revocation() revocation.DB
// NodeAPIVersion tracks nodes observed api usage
NodeAPIVersion() nodeapiversion.DB
// StorjscanPayments stores payments retrieved from storjscan.
StorjscanPayments() storjscan.PaymentsDB
// Testing provides access to testing facilities. These should not be used in production code.
Testing() TestingDB
}
// TestingDB defines access to database testing facilities.
type TestingDB interface {
// RawDB returns the underlying database connection to the primary database.
RawDB() tagsql.DB
// Schema returns the full schema for the database.
Schema() string
// TestMigrateToLatest initializes the database for testplanet.
TestMigrateToLatest(ctx context.Context) error
// ProductionMigration returns the primary migration.
ProductionMigration() *migrate.Migration
// TestMigration returns the migration used for tests.
TestMigration() *migrate.Migration
}
// Config is the global config satellite.
type Config struct {
Identity identity.Config
Server server.Config
Debug debug.Config
Admin admin.Config
Contact contact.Config
Overlay overlay.Config
OfflineNodes offlinenodes.Config
NodeEvents nodeevents.Config
StrayNodes straynodes.Config
Metainfo metainfo.Config
Orders orders.Config
Userinfo userinfo.Config
Reputation reputation.Config
Checker checker.Config
Repairer repairer.Config
Audit audit.Config
GarbageCollection sender.Config
GarbageCollectionBF bloomfilter.Config
RangedLoop rangedloop.Config
ExpiredDeletion expireddeletion.Config
ZombieDeletion zombiedeletion.Config
Tally tally.Config
Rollup rollup.Config
RollupArchive rolluparchive.Config
LiveAccounting live.Config
ProjectBWCleanup projectbwcleanup.Config
Mail mailservice.Config
Payments paymentsconfig.Config
RESTKeys restkeys.Config
Console consoleweb.Config
ConsoleAuth consoleauth.Config
EmailReminders emailreminders.Config
ConsoleDBCleanup dbcleanup.Config
AccountFreeze accountfreeze.Config
Version version_checker.Config
GracefulExit gracefulexit.Config
Compensation compensation.Config
ProjectLimit accounting.ProjectLimitConfig
Analytics analytics.Config
}
func setupMailService(log *zap.Logger, config Config) (*mailservice.Service, error) {
// TODO(yar): test multiple satellites using same OAUTH credentials
mailConfig := config.Mail
// validate from mail address
from, err := mail.ParseAddress(mailConfig.From)
if err != nil {
return nil, errs.New("SMTP from address '%s' couldn't be parsed: %v", mailConfig.From, err)
}
// validate smtp server address
host, _, err := net.SplitHostPort(mailConfig.SMTPServerAddress)
if err != nil && mailConfig.AuthType != "simulate" && mailConfig.AuthType != "nologin" {
return nil, errs.New("SMTP server address '%s' couldn't be parsed: %v", mailConfig.SMTPServerAddress, err)
}
var sender mailservice.Sender
switch mailConfig.AuthType {
case "oauth2":
creds := oauth2.Credentials{
ClientID: mailConfig.ClientID,
ClientSecret: mailConfig.ClientSecret,
TokenURI: mailConfig.TokenURI,
}
token, err := oauth2.RefreshToken(context.TODO(), creds, mailConfig.RefreshToken)
if err != nil {
return nil, err
}
sender = &post.SMTPSender{
From: *from,
Auth: &oauth2.Auth{
UserEmail: from.Address,
Storage: oauth2.NewTokenStore(creds, *token),
},
ServerAddress: mailConfig.SMTPServerAddress,
}
case "plain":
sender = &post.SMTPSender{
From: *from,
Auth: smtp.PlainAuth("", mailConfig.Login, mailConfig.Password, host),
ServerAddress: mailConfig.SMTPServerAddress,
}
case "login":
sender = &post.SMTPSender{
From: *from,
Auth: post.LoginAuth{
Username: mailConfig.Login,
Password: mailConfig.Password,
},
ServerAddress: mailConfig.SMTPServerAddress,
}
case "nomail":
sender = simulate.NoMail{}
default:
sender = simulate.NewDefaultLinkClicker(log.Named("mail:linkclicker"))
}
return mailservice.New(
log.Named("mail:service"),
sender,
mailConfig.TemplatePath,
)
}