Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f74fb1c

Browse files
satellite/{admin,console,payments}: cascade email change
This change cascades admin email changes to analytics and billing system. Related: #7617 Change-Id: Ie2238f781da1e0e1ad44d91dc2c94535d1879743
1 parent 92ee351 commit f74fb1c

File tree

7 files changed

+69
-3
lines changed

7 files changed

+69
-3
lines changed

satellite/admin.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,8 @@ func NewAdmin(log *zap.Logger, full *identity.FullIdentity, db DB, metabaseDB *m
304304
peer.Accounting.Service,
305305
backoffice.NewAuthorizer(log.Named("back-office:auth"), config.Admin.BackOffice),
306306
peer.FreezeAccounts.Service,
307+
peer.Analytics.Service,
308+
peer.Payments.Accounts,
307309
placement,
308310
config.Metainfo.ProjectLimits.MaxBuckets,
309311
config.Metainfo.RateLimiter.Rate,

satellite/admin/back-office/service.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import (
99
"go.uber.org/zap"
1010

1111
"storj.io/storj/satellite/accounting"
12+
"storj.io/storj/satellite/analytics"
1213
"storj.io/storj/satellite/console"
1314
"storj.io/storj/satellite/nodeselection"
15+
"storj.io/storj/satellite/payments"
1416
)
1517

1618
// Defaults contains default values for limits which are not stored in the DB.
@@ -30,6 +32,8 @@ type Service struct {
3032

3133
accountFreeze *console.AccountFreezeService
3234
accounting *accounting.Service
35+
analytics *analytics.Service
36+
payments payments.Accounts
3337

3438
placement nodeselection.PlacementDefinitions
3539
defaults Defaults
@@ -47,6 +51,8 @@ func NewService(
4751
accounting *accounting.Service,
4852
authorizer *Authorizer,
4953
accountFreeze *console.AccountFreezeService,
54+
analytics *analytics.Service,
55+
payments payments.Accounts,
5056
placement nodeselection.PlacementDefinitions,
5157
defaultMaxBuckets int,
5258
defaultRateLimit float64,
@@ -56,10 +62,12 @@ func NewService(
5662
return &Service{
5763
log: log,
5864
consoleDB: consoleDB,
65+
analytics: analytics,
5966
accountingDB: accountingDB,
6067
accounting: accounting,
6168
accountFreeze: accountFreeze,
6269
authorizer: authorizer,
70+
payments: payments,
6371
placement: placement,
6472
defaults: Defaults{
6573
MaxBuckets: defaultMaxBuckets,

satellite/admin/back-office/users.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"time"
1212

1313
"github.com/zeebo/errs"
14+
"go.uber.org/zap"
1415

1516
"storj.io/common/storj"
1617
"storj.io/common/uuid"
@@ -263,6 +264,7 @@ func (s *Service) getUsageLimitsAndFreezes(ctx context.Context, userID uuid.UUID
263264

264265
// UpdateUser updates a user's information.
265266
// Limit updates will cascade to all projects owned by the user.
267+
// Email updates will also update the email in the payment and analytics systems.
266268
func (s *Service) UpdateUser(ctx context.Context, authInfo *AuthInfo, userID uuid.UUID, request UpdateUserRequest) (*UserAccount, api.HTTPError) {
267269
var err error
268270
defer mon.Task()(&ctx)(&err)
@@ -342,9 +344,8 @@ func (s *Service) UpdateUser(ctx context.Context, authInfo *AuthInfo, userID uui
342344
}
343345

344346
err = s.consoleDB.WithTx(ctx, func(ctx context.Context, tx console.DBTx) error {
345-
projectsDB := tx.Projects()
346-
347-
err = tx.Users().Update(ctx, userID, console.UpdateUserRequest{
347+
usersDB := tx.Users()
348+
err = usersDB.Update(ctx, userID, console.UpdateUserRequest{
348349
Email: request.Email,
349350
FullName: request.Name,
350351
Kind: request.Kind,
@@ -361,10 +362,25 @@ func (s *Service) UpdateUser(ctx context.Context, authInfo *AuthInfo, userID uui
361362
return err
362363
}
363364

365+
if request.Email != nil && *request.Email != user.Email {
366+
// update email in analytics and payment system
367+
s.analytics.ChangeContactEmail(user.ID, user.Email, *request.Email)
368+
cusID, err := usersDB.GetCustomerID(ctx, user.ID)
369+
if err != nil {
370+
return err
371+
}
372+
373+
if err = s.payments.ChangeCustomerEmail(ctx, user.ID, cusID, *request.Email); err != nil {
374+
s.log.Error("Failed to update customer email on stripe", zap.Stringer("userId", user.ID), zap.Error(err))
375+
return err
376+
}
377+
}
378+
364379
if request.StorageLimit == nil && request.BandwidthLimit == nil && request.SegmentLimit == nil {
365380
return nil
366381
}
367382

383+
projectsDB := tx.Projects()
368384
projects, err := projectsDB.GetOwn(ctx, userID)
369385
if err != nil {
370386
return err

satellite/console/users.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ type Users interface {
7575
GetUpgradeTime(ctx context.Context, userID uuid.UUID) (*time.Time, error)
7676
// UpsertSettings is a method for updating a user's set of configurations if it exists and inserting it otherwise.
7777
UpsertSettings(ctx context.Context, userID uuid.UUID, settings UpsertUserSettingsRequest) error
78+
// GetCustomerID returns the customer ID for a given user ID.
79+
GetCustomerID(ctx context.Context, id uuid.UUID) (_ string, err error)
7880
// SetStatusPendingDeletion set the user to pending deletion status safely to potentially reduce
7981
// mistakes the data deletion process of valid accounts. The method must automatically verify:
8082
//

satellite/payments/account.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ type Accounts interface {
7373
// ChangeEmail changes a customer's email address.
7474
ChangeEmail(ctx context.Context, userID uuid.UUID, email string) error
7575

76+
// ChangeCustomerEmail changes a customer's email address given the customer ID. This is meant for use
77+
// for methods that run in a transaction to avoid ChangeEmail's non-tx DB lookup. Callers are expected
78+
// to have retrieved customer ID from DB already.
79+
ChangeCustomerEmail(ctx context.Context, userID uuid.UUID, cusID, email string) (err error)
80+
7681
// GetPackageInfo returns the package plan and time of purchase for a user.
7782
GetPackageInfo(ctx context.Context, userID uuid.UUID) (packagePlan *string, purchaseTime *time.Time, err error)
7883

satellite/payments/stripe/accounts.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,28 @@ func (accounts *accounts) ChangeEmail(ctx context.Context, userID uuid.UUID, ema
257257
return nil
258258
}
259259

260+
// ChangeCustomerEmail changes a customer's email address given the customer ID. This is meant for use
261+
// for methods that run in a transaction to avoid ChangeEmail's non-tx DB lookup. Callers are expected
262+
// to have retrieved customer ID from DB already.
263+
func (accounts *accounts) ChangeCustomerEmail(ctx context.Context, userID uuid.UUID, cusID, email string) (err error) {
264+
defer mon.Task()(&ctx, userID, email)(&err)
265+
266+
params := &stripe.CustomerParams{
267+
Params: stripe.Params{Context: ctx},
268+
Email: stripe.String(email),
269+
}
270+
_, err = accounts.service.stripeClient.Customers().Update(cusID, params)
271+
if err != nil {
272+
stripeErr := &stripe.Error{}
273+
if errors.As(err, &stripeErr) {
274+
err = errs.Wrap(errors.New(stripeErr.Msg))
275+
}
276+
return Error.Wrap(err)
277+
}
278+
279+
return nil
280+
}
281+
260282
// SaveBillingAddress saves billing address for a user and returns the updated billing information.
261283
func (accounts *accounts) SaveBillingAddress(ctx context.Context, userID uuid.UUID, address payments.BillingAddress) (_ *payments.BillingInformation, err error) {
262284
defer mon.Task()(&ctx)(&err)

satellite/satellitedb/consoledb/users.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,17 @@ func (users *users) UpsertSettings(ctx context.Context, userID uuid.UUID, settin
768768
return err
769769
}
770770

771+
// GetCustomerID returns the customer ID for a given user ID.
772+
func (users *users) GetCustomerID(ctx context.Context, id uuid.UUID) (_ string, err error) {
773+
defer mon.Task()(&ctx)(&err)
774+
idRow, err := users.db.Get_StripeCustomer_CustomerId_By_UserId(ctx, dbx.StripeCustomer_UserId(id[:]))
775+
if err != nil {
776+
return "", err
777+
}
778+
779+
return idRow.CustomerId, nil
780+
}
781+
771782
// SetStatusPendingDeletion set the user to "pending deletion" status safely. It is implemented as
772783
// documented in the corresponding Users interface method that implements.
773784
func (users *users) SetStatusPendingDeletion(

0 commit comments

Comments
 (0)