Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDP-1116 Support External_ID DRAFT PR (See TODO). reece #256

Draft
wants to merge 49 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
d6adff0
initial without sep24 claim verification
reecexlm Apr 12, 2024
2b7aa01
resolve conflicts
reecexlm Apr 16, 2024
6b24019
missed resolving 2 conflicts
reecexlm Apr 16, 2024
66b017d
updates to serveopts for multitenancy to support external-id
reecexlm Apr 16, 2024
99bb3c9
fix for tenant domain in unit test
reecexlm Apr 18, 2024
ee87c8b
draft of customer-id/hashed mobile# verification
reecexlm Apr 18, 2024
88245da
adding more tests
reecexlm Apr 19, 2024
b05dc79
Fix indentation and tests.
marcelosalloum Apr 19, 2024
09aeba1
Remove extra spaces.
marcelosalloum Apr 19, 2024
b90ae10
fix db cleanup in tests
reecexlm Apr 20, 2024
94f554d
fix conflicts
reecexlm Apr 20, 2024
75a9f94
test fixes
reecexlm Apr 20, 2024
ab60cac
remove rollback
reecexlm Apr 20, 2024
fe65c5e
fix
reecexlm Apr 20, 2024
a36577a
noop
reecexlm Apr 21, 2024
8148138
noop
reecexlm Apr 21, 2024
21eefee
noop
reecexlm Apr 21, 2024
b7f7e96
noop
reecexlm Apr 21, 2024
4fa13da
noop
reecexlm Apr 21, 2024
4c28c3d
noop
reecexlm Apr 21, 2024
0942120
noop
reecexlm Apr 21, 2024
5f00001
noop
reecexlm Apr 22, 2024
dc61fd8
noop
reecexlm Apr 23, 2024
ad5603f
Update internal/services/send_receiver_wallets_invite_service.go
reecexlm Apr 23, 2024
292015f
noop
reecexlm Apr 23, 2024
573de96
noop
marwen-abid Apr 23, 2024
f83d283
Fix lint issues and other errors.
marwen-abid Apr 23, 2024
20ae751
make `kafka-security-protocol` optional
marwen-abid Apr 23, 2024
fcb9827
noop
reecexlm Apr 24, 2024
eda7452
Merge branch 'sdp-1116-externalid' of https://github.com/stellar/stel…
reecexlm Apr 24, 2024
aab9010
noop
reecexlm Apr 24, 2024
37c3db1
noop
reecexlm Apr 25, 2024
f9ae6b0
do not crash if default tenant is missing
reecexlm Apr 26, 2024
7793716
do not error on missing tenant
reecexlm Apr 27, 2024
d8d0896
providing an informative error message
reecexlm Apr 27, 2024
2c47a3e
noop
reecexlm Apr 27, 2024
acc79af
noop
reecexlm Apr 27, 2024
3be5dc2
Add Postman Sample Collection
reecexlm Apr 27, 2024
6efdfec
noop
reecexlm Apr 30, 2024
b88185d
noop
reecexlm May 1, 2024
19ee8de
noop
reecexlm May 1, 2024
558eae4
debugging
reecexlm May 1, 2024
7d6c88e
debugging
reecexlm May 1, 2024
9495335
put middleware tenant check back
reecexlm May 9, 2024
91844b6
turn debug off
reecexlm May 9, 2024
cbae53c
try moving health to top of handleHTTP
reecexlm May 9, 2024
0a0f0ef
only warn on tenant missing
reecexlm May 9, 2024
a9c87f9
Merge branch 'develop' into sdp-1116-externalid
reecexlm May 31, 2024
3e6ef02
Merge branch 'develop' into sdp-1116-externalid
reecexlm Jul 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions cmd/serve.go
marcelosalloum marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,14 @@ func (c *ServeCommand) Command(serverService ServerServiceInterface, monitorServ
FlagDefault: horizonclient.DefaultTestNetClient.HorizonURL,
Required: true,
},
{
Name: "use-external-id",
Usage: "Enable or disable the use of external ID in wallet deep links",
OptType: types.Bool,
ConfigKey: &serveOpts.UseExternalID, // Ensure ServeOptions has a UseExternalID field of type bool
FlagDefault: false, // Default value set to false. Do Not embed external_id in wallet deep links
Required: false,
},
}

messengerOptions := message.MessengerOptions{}
Expand Down
1 change: 1 addition & 0 deletions internal/data/assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ func (a *AssetModel) GetAssetsPerReceiverWallet(ctx context.Context, receiverWal
r.id AS "receiver_wallet.receiver.id",
r.phone_number AS "receiver_wallet.receiver.phone_number",
r.email AS "receiver_wallet.receiver.email",
r.external_id AS "receiver_wallet.receiver.external_id",
a.id AS "asset.id",
a.code AS "asset.code",
a.issuer AS "asset.issuer",
Expand Down
8 changes: 8 additions & 0 deletions internal/data/assets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@ func Test_GetAssetsPerReceiverWallet(t *testing.T) {
ID: receiverX.ID,
Email: receiverX.Email,
PhoneNumber: receiverX.PhoneNumber,
ExternalID: receiverX.ExternalID,
},
ReceiverWalletStats: ReceiverWalletStats{
TotalInvitationSMSResentAttempts: 2,
Expand All @@ -656,6 +657,7 @@ func Test_GetAssetsPerReceiverWallet(t *testing.T) {
ID: receiverX.ID,
Email: receiverX.Email,
PhoneNumber: receiverX.PhoneNumber,
ExternalID: receiverX.ExternalID,
},
InvitationSentAt: &invitationSentAt,
},
Expand All @@ -670,6 +672,7 @@ func Test_GetAssetsPerReceiverWallet(t *testing.T) {
ID: receiverX.ID,
Email: receiverX.Email,
PhoneNumber: receiverX.PhoneNumber,
ExternalID: receiverX.ExternalID,
},
},
WalletID: walletB.ID,
Expand All @@ -683,6 +686,7 @@ func Test_GetAssetsPerReceiverWallet(t *testing.T) {
ID: receiverX.ID,
Email: receiverX.Email,
PhoneNumber: receiverX.PhoneNumber,
ExternalID: receiverX.ExternalID,
},
},
WalletID: walletB.ID,
Expand All @@ -696,6 +700,7 @@ func Test_GetAssetsPerReceiverWallet(t *testing.T) {
ID: receiverY.ID,
Email: receiverY.Email,
PhoneNumber: receiverY.PhoneNumber,
ExternalID: receiverY.ExternalID,
},
},
WalletID: walletA.ID,
Expand All @@ -709,6 +714,7 @@ func Test_GetAssetsPerReceiverWallet(t *testing.T) {
ID: receiverY.ID,
Email: receiverY.Email,
PhoneNumber: receiverY.PhoneNumber,
ExternalID: receiverY.ExternalID,
},
},
WalletID: walletA.ID,
Expand All @@ -722,6 +728,7 @@ func Test_GetAssetsPerReceiverWallet(t *testing.T) {
ID: receiverY.ID,
Email: receiverY.Email,
PhoneNumber: receiverY.PhoneNumber,
ExternalID: receiverY.ExternalID,
},
},
WalletID: walletB.ID,
Expand All @@ -735,6 +742,7 @@ func Test_GetAssetsPerReceiverWallet(t *testing.T) {
ID: receiverY.ID,
Email: receiverY.Email,
PhoneNumber: receiverY.PhoneNumber,
ExternalID: receiverY.ExternalID,
marcelosalloum marked this conversation as resolved.
Show resolved Hide resolved
},
},
WalletID: walletB.ID,
Expand Down
1 change: 1 addition & 0 deletions internal/data/receivers.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type ReceiverRegistrationRequest struct {
VerificationValue string `json:"verification"`
VerificationType VerificationField `json:"verification_type"`
ReCAPTCHAToken string `json:"recaptcha_token"`
ExternalID string `json:"external_id"`
}

type ReceiverStats struct {
Expand Down
1 change: 1 addition & 0 deletions internal/data/receivers_wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ func (rw *ReceiverWalletModel) GetAllPendingRegistration(ctx context.Context) ([
r.id AS "receiver.id",
r.phone_number AS "receiver.phone_number",
r.email AS "receiver.email",
r.external_id AS "receiver.external_id",
w.id AS "wallet.id",
w.name AS "wallet.name"
FROM
Expand Down
2 changes: 2 additions & 0 deletions internal/data/receivers_wallet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,7 @@ func Test_ReceiverWallet_GetAllPendingRegistration(t *testing.T) {
ID: receiver.ID,
PhoneNumber: receiver.PhoneNumber,
Email: receiver.Email,
ExternalID: receiver.ExternalID,
},
Wallet: Wallet{
ID: wallet3.ID,
Expand All @@ -851,6 +852,7 @@ func Test_ReceiverWallet_GetAllPendingRegistration(t *testing.T) {
ID: receiver.ID,
PhoneNumber: receiver.PhoneNumber,
Email: receiver.Email,
ExternalID: receiver.ExternalID,
},
Wallet: Wallet{
ID: wallet4.ID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type SendReceiverWalletsSMSInvitationJobOptions struct {
MaxInvitationSMSResendAttempts int64
Sep10SigningPrivateKey string
CrashTrackerClient crashtracker.CrashTrackerClient
UseExternalID bool
}

var _ Job = (*SendReceiverWalletsSMSInvitationJob)(nil)
Expand Down Expand Up @@ -58,6 +59,7 @@ func NewSendReceiverWalletsSMSInvitationJob(options SendReceiverWalletsSMSInvita
options.Sep10SigningPrivateKey,
options.MaxInvitationSMSResendAttempts,
options.CrashTrackerClient,
options.UseExternalID,
)
if err != nil {
log.Fatalf("error instantiating service: %s", err.Error())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ func Test_SendReceiverWalletsSMSInvitationJob_Execute(t *testing.T) {
stellarSecretKey,
maxInvitationSMSResendAttempts,
crashTrackerClientMock,
true,
)
require.NoError(t, err)

Expand Down Expand Up @@ -200,6 +201,7 @@ func Test_SendReceiverWalletsSMSInvitationJob_Execute(t *testing.T) {
OrganizationName: "MyCustomAid",
AssetCode: asset1.Code,
AssetIssuer: asset1.Issuer,
ExternalID: receiver1.ExternalID,
}
deepLink1, err := walletDeepLink1.GetSignedRegistrationLink(stellarSecretKey)
require.NoError(t, err)
Expand All @@ -211,6 +213,7 @@ func Test_SendReceiverWalletsSMSInvitationJob_Execute(t *testing.T) {
OrganizationName: "MyCustomAid",
AssetCode: asset2.Code,
AssetIssuer: asset2.Issuer,
ExternalID: receiver2.ExternalID,
}
deepLink2, err := walletDeepLink2.GetSignedRegistrationLink(stellarSecretKey)
require.NoError(t, err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ func (v VerifyReceiverRegistrationHandler) processReceiverVerificationPII(
now := time.Now()
truncatedPhoneNumber := utils.TruncateString(receiver.PhoneNumber, 3)

// Use the external_id associated with the receiver if it exists
if receiver.ExternalID != "" {
// Logic to handle the verification associated with the external_id
// This may include comparing the hashed phone number with the one associated with external_id
}

marcelosalloum marked this conversation as resolved.
Show resolved Hide resolved
// STEP 1: find the receiverVerification entry that matches the pair [receiverID, verificationType]
receiverVerifications, err := v.Models.ReceiverVerification.GetByReceiverIDsAndVerificationField(ctx, dbTx, []string{receiver.ID}, receiverRegistrationRequest.VerificationType)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,28 @@ func Test_VerifyReceiverRegistrationHandler_validate(t *testing.T) {
ReCAPTCHAToken: "token",
},
},
{
name: "🎉 successfully parses the body with external_id if the SEP24 token, recaptcha token and request body are all valid",
contextSep24Claims: sep24JWTClaims,
requestBody: `{
"phone_number": "+380445555555",
"otp": "123456",
"verification": "1990-01-01",
"verification_type": "date_of_birth",
"external_id": "user-external-id",
"reCAPTCHA_token": "token"
}`,
isRecaptchaValidFnResponse: []interface{}{true, nil},
wantSep24Claims: sep24JWTClaims,
wantResult: data.ReceiverRegistrationRequest{
PhoneNumber: "+380445555555",
OTP: "123456",
VerificationValue: "1990-01-01",
VerificationType: data.VerificationFieldDateOfBirth,
ExternalID: "user-external-id",
ReCAPTCHAToken: "token",
},
},
}

models, err := data.NewModels(dbConnectionPool)
Expand Down
1 change: 1 addition & 0 deletions internal/serve/serve.go
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will need to propagate the UseExternalID config to the handler responsible for /wallet-registration/verification, injecting it in:

r.With(sep24HeaderTokenAuthenticationMiddleware).Post("/verification", httphandler.VerifyReceiverRegistrationHandler{
AnchorPlatformAPIService: o.AnchorPlatformAPIService,
Models: o.Models,
ReCAPTCHAValidator: reCAPTCHAValidator,
NetworkPassphrase: o.NetworkPassphrase,
EventProducer: o.EventProducer,
}.VerifyReceiverRegistration)

Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ type ServeOptions struct {
DisableMFA bool
DisableReCAPTCHA bool
PasswordValidator *authUtils.PasswordValidator
UseExternalID bool
}

// SetupDependencies uses the serve options to setup the dependencies for the server.
Expand Down
15 changes: 14 additions & 1 deletion internal/services/send_receiver_wallets_invite_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type SendReceiverWalletInviteService struct {
maxInvitationSMSResendAttempts int64
sep10SigningPrivateKey string
crashTrackerClient crashtracker.CrashTrackerClient
UseExternalID bool
}

func (s SendReceiverWalletInviteService) validate() error {
Expand Down Expand Up @@ -106,6 +107,11 @@ func (s SendReceiverWalletInviteService) SendInvite(ctx context.Context) error {
AssetIssuer: rwa.Asset.Issuer,
}

// Only set ExternalID if UseExternalID config is true
if s.UseExternalID {
wdl.ExternalID = rwa.ReceiverWallet.Receiver.ExternalID
}

registrationLink, err := wdl.GetSignedRegistrationLink(s.sep10SigningPrivateKey)
if err != nil {
log.Ctx(ctx).Errorf(
Expand Down Expand Up @@ -245,14 +251,15 @@ func (s SendReceiverWalletInviteService) shouldSendInvitationSMS(ctx context.Con
return true
}

func NewSendReceiverWalletInviteService(models *data.Models, messengerClient message.MessengerClient, anchorPlatformBaseSepURL, sep10SigningPrivateKey string, maxInvitationSMSResendAttempts int64, crashTrackerClient crashtracker.CrashTrackerClient) (*SendReceiverWalletInviteService, error) {
func NewSendReceiverWalletInviteService(models *data.Models, messengerClient message.MessengerClient, anchorPlatformBaseSepURL, sep10SigningPrivateKey string, maxInvitationSMSResendAttempts int64, crashTrackerClient crashtracker.CrashTrackerClient, UseExternalID bool) (*SendReceiverWalletInviteService, error) {
s := &SendReceiverWalletInviteService{
messengerClient: messengerClient,
models: models,
anchorPlatformBaseSepURL: anchorPlatformBaseSepURL,
maxInvitationSMSResendAttempts: maxInvitationSMSResendAttempts,
sep10SigningPrivateKey: sep10SigningPrivateKey,
crashTrackerClient: crashTrackerClient,
UseExternalID: UseExternalID,
}

if err := s.validate(); err != nil {
Expand All @@ -275,6 +282,8 @@ type WalletDeepLink struct {
AssetCode string
// AssetIssuer is the issuer of the Stellar asset that the receiver will be able to receive.
AssetIssuer string
// ExternalID is an optional parameter that can be used to include an external ID in the registration link.
ExternalID string // The external ID you want to include in the registration link
}

func (wdl WalletDeepLink) isNativeAsset() bool {
Expand Down Expand Up @@ -380,6 +389,7 @@ func (wdl WalletDeepLink) validate() error {
// GetUnsignedRegistrationLink creates a deep link for the wallet registration using the format below:
// <deep_link></route>?<domain>&<name>&<asset>.
func (wdl WalletDeepLink) GetUnsignedRegistrationLink() (string, error) {

if err := wdl.validate(); err != nil {
return "", fmt.Errorf("validating WalletDeepLink: %w", err)
}
Expand All @@ -403,6 +413,9 @@ func (wdl WalletDeepLink) GetUnsignedRegistrationLink() (string, error) {
q.Add("domain", tomlFileDomain)
q.Add("name", wdl.OrganizationName)
q.Add("asset", wdl.assetName())
if wdl.ExternalID != "" {
q.Add("external_id", wdl.ExternalID)
}

u.RawQuery = q.Encode()

Expand Down
Loading