satellite/console/consoleweb: add support for partner
parameter for
signup page With this change partner id can be associated with user during creating account by adding `?partner=partner_name` parameter to signup page url e.g. https://tardigrade.io/signup?partner=mongodb https://storjlabs.atlassian.net/browse/USR-999 Change-Id: I12a5ebec92a6f5135909447172ef24da57fb1c68
This commit is contained in:
parent
edfd3d7661
commit
4561d9bdb0
@ -600,6 +600,7 @@ func NewAPI(log *zap.Logger, full *identity.FullIdentity, db DB,
|
||||
peer.Console.Service,
|
||||
peer.Mail.Service,
|
||||
peer.Referrals.Service,
|
||||
peer.Marketing.PartnersService,
|
||||
peer.Console.Listener,
|
||||
config.Payments.StripeCoinPayments.StripePublicKey,
|
||||
)
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
"storj.io/storj/satellite/console/consoleweb/consoleql"
|
||||
"storj.io/storj/satellite/console/consoleweb/consolewebauth"
|
||||
"storj.io/storj/satellite/mailservice"
|
||||
"storj.io/storj/satellite/rewards"
|
||||
)
|
||||
|
||||
// ErrAuthAPI - console auth api error type.
|
||||
@ -32,10 +33,11 @@ type Auth struct {
|
||||
service *console.Service
|
||||
mailService *mailservice.Service
|
||||
cookieAuth *consolewebauth.CookieAuth
|
||||
partners *rewards.PartnersService
|
||||
}
|
||||
|
||||
// NewAuth is a constructor for api auth controller.
|
||||
func NewAuth(log *zap.Logger, service *console.Service, mailService *mailservice.Service, cookieAuth *consolewebauth.CookieAuth, externalAddress string, letUsKnowURL string, termsAndConditionsURL string, contactInfoURL string) *Auth {
|
||||
func NewAuth(log *zap.Logger, service *console.Service, mailService *mailservice.Service, cookieAuth *consolewebauth.CookieAuth, partners *rewards.PartnersService, externalAddress string, letUsKnowURL string, termsAndConditionsURL string, contactInfoURL string) *Auth {
|
||||
return &Auth{
|
||||
log: log,
|
||||
ExternalAddress: externalAddress,
|
||||
@ -45,6 +47,7 @@ func NewAuth(log *zap.Logger, service *console.Service, mailService *mailservice
|
||||
service: service,
|
||||
mailService: mailService,
|
||||
cookieAuth: cookieAuth,
|
||||
partners: partners,
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,6 +105,7 @@ func (a *Auth) Register(w http.ResponseWriter, r *http.Request) {
|
||||
FullName string `json:"fullName"`
|
||||
ShortName string `json:"shortName"`
|
||||
Email string `json:"email"`
|
||||
Partner string `json:"partner"`
|
||||
PartnerID string `json:"partnerId"`
|
||||
Password string `json:"password"`
|
||||
SecretInput string `json:"secret"`
|
||||
@ -120,6 +124,15 @@ func (a *Auth) Register(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if registerData.Partner != "" {
|
||||
info, err := a.partners.ByName(ctx, registerData.Partner)
|
||||
if err != nil {
|
||||
a.log.Warn("Invalid partner name", zap.String("Partner name", registerData.Partner), zap.String("User email", registerData.Email), zap.Error(err))
|
||||
} else {
|
||||
registerData.PartnerID = info.ID
|
||||
}
|
||||
}
|
||||
|
||||
user, err := a.service.CreateUser(ctx,
|
||||
console.CreateUser{
|
||||
FullName: registerData.FullName,
|
||||
|
92
satellite/console/consoleweb/consoleapi/auth_test.go
Normal file
92
satellite/console/consoleweb/consoleapi/auth_test.go
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright (C) 2020 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package consoleapi_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"storj.io/common/testcontext"
|
||||
"storj.io/common/uuid"
|
||||
"storj.io/storj/private/testplanet"
|
||||
"storj.io/storj/satellite"
|
||||
)
|
||||
|
||||
func TestAuth_Register(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 0,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
config.Console.OpenRegistrationEnabled = true
|
||||
config.Console.RateLimit.Burst = 10
|
||||
},
|
||||
},
|
||||
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||
|
||||
for i, test := range []struct {
|
||||
Partner string
|
||||
ValidPartner bool
|
||||
}{
|
||||
{Partner: "minio", ValidPartner: true},
|
||||
{Partner: "Minio", ValidPartner: true},
|
||||
{Partner: "Raiden Network", ValidPartner: true},
|
||||
{Partner: "Raiden nEtwork", ValidPartner: true},
|
||||
{Partner: "invalid-name", ValidPartner: false},
|
||||
} {
|
||||
registerData := struct {
|
||||
FullName string `json:"fullName"`
|
||||
ShortName string `json:"shortName"`
|
||||
Email string `json:"email"`
|
||||
Partner string `json:"partner"`
|
||||
PartnerID string `json:"partnerId"`
|
||||
Password string `json:"password"`
|
||||
SecretInput string `json:"secret"`
|
||||
ReferrerUserID string `json:"referrerUserId"`
|
||||
}{
|
||||
FullName: "testuser" + strconv.Itoa(i),
|
||||
ShortName: "test",
|
||||
Email: "user@test" + strconv.Itoa(i),
|
||||
Partner: test.Partner,
|
||||
Password: "abc123",
|
||||
}
|
||||
|
||||
jsonBody, err := json.Marshal(registerData)
|
||||
require.NoError(t, err)
|
||||
|
||||
result, err := http.Post("http://"+planet.Satellites[0].API.Console.Listener.Addr().String()+"/api/v0/auth/register", "application/json", bytes.NewBuffer(jsonBody))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, result.StatusCode)
|
||||
|
||||
defer func() {
|
||||
err = result.Body.Close()
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
body, err := ioutil.ReadAll(result.Body)
|
||||
require.NoError(t, err)
|
||||
|
||||
var userID uuid.UUID
|
||||
err = json.Unmarshal(body, &userID)
|
||||
require.NoError(t, err)
|
||||
|
||||
user, err := planet.Satellites[0].API.Console.Service.GetUser(ctx, userID)
|
||||
require.NoError(t, err)
|
||||
|
||||
if test.ValidPartner {
|
||||
info, err := planet.Satellites[0].API.Marketing.PartnersService.ByName(ctx, test.Partner)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, info.UUID, user.PartnerID)
|
||||
} else {
|
||||
require.Equal(t, uuid.UUID{}, user.PartnerID)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
@ -39,6 +39,7 @@ import (
|
||||
"storj.io/storj/satellite/console/consoleweb/consolewebauth"
|
||||
"storj.io/storj/satellite/mailservice"
|
||||
"storj.io/storj/satellite/referrals"
|
||||
"storj.io/storj/satellite/rewards"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -93,6 +94,7 @@ type Server struct {
|
||||
service *console.Service
|
||||
mailService *mailservice.Service
|
||||
referralsService *referrals.Service
|
||||
partners *rewards.PartnersService
|
||||
|
||||
listener net.Listener
|
||||
server http.Server
|
||||
@ -114,7 +116,7 @@ type Server struct {
|
||||
}
|
||||
|
||||
// NewServer creates new instance of console server.
|
||||
func NewServer(logger *zap.Logger, config Config, service *console.Service, mailService *mailservice.Service, referralsService *referrals.Service, listener net.Listener, stripePublicKey string) *Server {
|
||||
func NewServer(logger *zap.Logger, config Config, service *console.Service, mailService *mailservice.Service, referralsService *referrals.Service, partners *rewards.PartnersService, listener net.Listener, stripePublicKey string) *Server {
|
||||
server := Server{
|
||||
log: logger,
|
||||
config: config,
|
||||
@ -122,6 +124,7 @@ func NewServer(logger *zap.Logger, config Config, service *console.Service, mail
|
||||
service: service,
|
||||
mailService: mailService,
|
||||
referralsService: referralsService,
|
||||
partners: partners,
|
||||
stripePublicKey: stripePublicKey,
|
||||
rateLimiter: web.NewIPRateLimiter(config.RateLimit),
|
||||
}
|
||||
@ -164,7 +167,7 @@ func NewServer(logger *zap.Logger, config Config, service *console.Service, mail
|
||||
referralsRouter.Handle("/tokens", server.withAuth(http.HandlerFunc(referralsController.GetTokens))).Methods(http.MethodGet)
|
||||
referralsRouter.HandleFunc("/register", referralsController.Register).Methods(http.MethodPost)
|
||||
|
||||
authController := consoleapi.NewAuth(logger, service, mailService, server.cookieAuth, server.config.ExternalAddress, config.LetUsKnowURL, config.TermsAndConditionsURL, config.ContactInfoURL)
|
||||
authController := consoleapi.NewAuth(logger, service, mailService, server.cookieAuth, partners, server.config.ExternalAddress, config.LetUsKnowURL, config.TermsAndConditionsURL, config.ContactInfoURL)
|
||||
authRouter := router.PathPrefix("/api/v0/auth").Subrouter()
|
||||
authRouter.Handle("/account", server.withAuth(http.HandlerFunc(authController.GetAccount))).Methods(http.MethodGet)
|
||||
authRouter.Handle("/account", server.withAuth(http.HandlerFunc(authController.UpdateAccount))).Methods(http.MethodPatch)
|
||||
|
@ -114,7 +114,7 @@ func (service *PartnersService) ByUserAgent(ctx context.Context, userAgentString
|
||||
return PartnerInfo{}, ErrPartners.Wrap(err)
|
||||
}
|
||||
|
||||
return service.db.ByName(ctx, info.Product.Name)
|
||||
return service.db.ByUserAgent(ctx, info.Product.Name)
|
||||
}
|
||||
|
||||
// All returns all partners.
|
||||
|
@ -6,6 +6,7 @@ package rewards
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/zeebo/errs"
|
||||
)
|
||||
@ -37,10 +38,11 @@ func NewPartnersStaticDB(list *PartnerList) (*PartnersStaticDB, error) {
|
||||
|
||||
var errg errs.Group
|
||||
for _, p := range list.Partners {
|
||||
if _, exists := db.byName[p.Name]; exists {
|
||||
name := strings.ToLower(p.Name)
|
||||
if _, exists := db.byName[name]; exists {
|
||||
errg.Add(ErrPartners.New("name %q already exists", p.Name))
|
||||
} else {
|
||||
db.byName[p.Name] = p
|
||||
db.byName[name] = p
|
||||
}
|
||||
|
||||
if _, exists := db.byID[p.ID]; exists {
|
||||
@ -65,9 +67,9 @@ func (db *PartnersStaticDB) All(ctx context.Context) ([]PartnerInfo, error) {
|
||||
return append([]PartnerInfo{}, db.list.Partners...), nil
|
||||
}
|
||||
|
||||
// ByName returns partner definitions for a given name.
|
||||
// ByName returns partner definitions for a given name. Name is case insensitive.
|
||||
func (db *PartnersStaticDB) ByName(ctx context.Context, name string) (PartnerInfo, error) {
|
||||
partner, ok := db.byName[name]
|
||||
partner, ok := db.byName[strings.ToLower(name)]
|
||||
if !ok {
|
||||
return PartnerInfo{}, ErrPartnerNotExist.New("%q", name)
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ export class AuthHttpApi {
|
||||
* @returns id of created user
|
||||
* @throws Error
|
||||
*/
|
||||
public async register(user: {fullName: string; shortName: string; email: string; partnerId: string; password: string}, secret: string, referrerUserId: string): Promise<string> {
|
||||
public async register(user: {fullName: string; shortName: string; email: string; partner: string, partnerId: string; password: string}, secret: string, referrerUserId: string): Promise<string> {
|
||||
const path = `${this.ROOT_PATH}/register`;
|
||||
const body = {
|
||||
secret: secret,
|
||||
@ -205,6 +205,7 @@ export class AuthHttpApi {
|
||||
fullName: user.fullName,
|
||||
shortName: user.shortName,
|
||||
email: user.email,
|
||||
partner: user.partner ? user.partner : '',
|
||||
partnerId: user.partnerId ? user.partnerId : '',
|
||||
};
|
||||
|
||||
|
@ -29,14 +29,16 @@ export class User {
|
||||
public fullName: string;
|
||||
public shortName: string;
|
||||
public email: string;
|
||||
public partner: string;
|
||||
public partnerId: string;
|
||||
public password: string;
|
||||
|
||||
public constructor(id: string = '', fullName: string = '', shortName: string = '', email: string = '', partnerId: string = '', password: string = '') {
|
||||
public constructor(id: string = '', fullName: string = '', shortName: string = '', email: string = '', partner: string = '', partnerId: string = '', password: string = '') {
|
||||
this.id = id;
|
||||
this.fullName = fullName;
|
||||
this.shortName = shortName;
|
||||
this.email = email;
|
||||
this.partner = partner;
|
||||
this.partnerId = partnerId;
|
||||
this.password = password;
|
||||
}
|
||||
|
@ -106,6 +106,10 @@ export default class RegisterArea extends Vue {
|
||||
this.referralToken = this.$route.query.referralToken.toString();
|
||||
}
|
||||
|
||||
if (this.$route.query.partner) {
|
||||
this.user.partner = this.$route.query.partner.toString();
|
||||
}
|
||||
|
||||
const { ids = '' } = this.$route.params;
|
||||
let decoded = '';
|
||||
try {
|
||||
|
Loading…
Reference in New Issue
Block a user