Skip to content

Commit

Permalink
rpc: add a new test for EmailAlreadyInUse
Browse files Browse the repository at this point in the history
  • Loading branch information
patrislav committed Jul 31, 2024
1 parent 85276f6 commit 821ed2b
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 71 deletions.
6 changes: 3 additions & 3 deletions rpc/admin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ func TestRPC_GetTenant(t *testing.T) {

svc := initRPC(t)

tenant, _ := newTenant(t, svc.Enclave, issuer)
tenant2, _ := newTenantWithAuthConfig(t, svc.Enclave, proto.AuthConfig{Email: proto.AuthEmailConfig{Enabled: true}})
tenant, _ := newTenant(t, svc.Enclave, withOIDC(issuer))
tenant2, _ := newTenant(t, svc.Enclave, withEmail())
require.NoError(t, svc.Tenants.Add(context.Background(), tenant))
require.NoError(t, svc.Tenants.Add(context.Background(), tenant2))

Expand Down Expand Up @@ -63,7 +63,7 @@ func TestRPC_CreateTenant(t *testing.T) {

svc := initRPC(t)

tenant, _ := newTenant(t, svc.Enclave, issuer)
tenant, _ := newTenant(t, svc.Enclave, withOIDC(issuer))
require.NoError(t, svc.Tenants.Add(context.Background(), tenant))

srv := httptest.NewServer(svc.Handler())
Expand Down
135 changes: 112 additions & 23 deletions rpc/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,7 @@ func TestEmailAuth(t *testing.T) {
})

var p assertionParams
p.tenant, _ = newTenantWithAuthConfig(t, svc.Enclave, proto.AuthConfig{
Email: proto.AuthEmailConfig{
Enabled: true,
},
})
p.tenant, _ = newTenant(t, svc.Enclave, withEmail())
require.NoError(t, svc.Tenants.Add(ctx, p.tenant))

if testCase.emailBuilderFn != nil {
Expand Down Expand Up @@ -219,11 +215,7 @@ func TestGuestAuth(t *testing.T) {
ctx := context.Background()

svc := initRPC(t)
tenant, _ := newTenantWithAuthConfig(t, svc.Enclave, proto.AuthConfig{
Guest: proto.AuthGuestConfig{
Enabled: true,
},
})
tenant, _ := newTenant(t, svc.Enclave, withGuest())
require.NoError(t, svc.Tenants.Add(ctx, tenant))

srv := httptest.NewServer(svc.Handler())
Expand Down Expand Up @@ -282,7 +274,7 @@ func TestOIDCAuth(t *testing.T) {
defer closeJWKS()

svc := initRPC(t)
tenant, _ := newTenant(t, svc.Enclave, issuer)
tenant, _ := newTenant(t, svc.Enclave, withOIDC(issuer))
require.NoError(t, svc.Tenants.Add(ctx, tenant))

sessWallet, err := ethwallet.NewWalletFromRandomEntropy()
Expand Down Expand Up @@ -347,12 +339,7 @@ func TestStytchAuth(t *testing.T) {
}
},
}})
tenant, _ := newTenantWithAuthConfig(t, svc.Enclave, proto.AuthConfig{
Stytch: proto.AuthStytchConfig{
Enabled: true,
ProjectID: "project-123",
},
})
tenant, _ := newTenant(t, svc.Enclave, withStytch("project-123"))
require.NoError(t, svc.Tenants.Add(ctx, tenant))

sessWallet, err := ethwallet.NewWalletFromRandomEntropy()
Expand Down Expand Up @@ -415,12 +402,7 @@ func TestPlayFabAuth(t *testing.T) {
}
},
}})
tenant, _ := newTenantWithAuthConfig(t, svc.Enclave, proto.AuthConfig{
Playfab: proto.AuthPlayfabConfig{
Enabled: true,
TitleID: "TITLE",
},
})
tenant, _ := newTenant(t, svc.Enclave, withPlayFab("TITLE"))
require.NoError(t, svc.Tenants.Add(ctx, tenant))

sessWallet, err := ethwallet.NewWalletFromRandomEntropy()
Expand Down Expand Up @@ -465,3 +447,110 @@ func TestPlayFabAuth(t *testing.T) {
assert.Equal(t, proto.IntentResponseCode_sessionOpened, registerRes.Code)
})
}

func TestEmailAlreadyInUse(t *testing.T) {
ctx := context.Background()

builderServer := httptest.NewServer(builder.NewBuilderServer(builder.NewMock()))
defer builderServer.Close()
walletService := newWalletServiceMock(nil)
waasServer := httptest.NewServer(proto_wallet.NewWaaSServer(walletService))
defer waasServer.Close()

email := "[email protected]"
exp := time.Now().Add(120 * time.Second)
tokBuilderFn := func(b *jwt.Builder, url string) {
b.Expiration(exp)
b.Claim("email", email)
}

issuer, tok, closeJWKS := issueAccessTokenAndRunJwksServer(t, tokBuilderFn)
defer closeJWKS()

svc := initRPC(t, func(cfg *config.Config) {
cfg.Builder.BaseURL = builderServer.URL
cfg.Endpoints.WaasAPIServer = waasServer.URL
})

tenant, _ := newTenant(t, svc.Enclave, withEmail(), withOIDC(issuer))
require.NoError(t, svc.Tenants.Add(ctx, tenant))

srv := httptest.NewServer(svc.Handler())
defer srv.Close()

c := proto.NewWaasAuthenticatorClient(srv.URL, http.DefaultClient)
header := make(http.Header)
header.Set("X-Sequence-Project", strconv.Itoa(int(tenant.ProjectID)))
ctx, err := proto.WithHTTPRequestHeaders(context.Background(), header)
require.NoError(t, err)

// Sign up with email
{
sessWallet, err := ethwallet.NewWalletFromRandomEntropy()
require.NoError(t, err)
signingSession := intents.NewSessionP256K1(sessWallet)

initiateAuth := generateSignedIntent(t, intents.IntentName_initiateAuth, intents.IntentDataInitiateAuth{
SessionID: signingSession.SessionID(),
IdentityType: intents.IdentityType_Email,
Verifier: email + ";" + signingSession.SessionID(),
}, signingSession)
initRes, err := c.SendIntent(ctx, initiateAuth)
require.NoError(t, err)
assert.Equal(t, proto.IntentResponseCode_authInitiated, initRes.Code)

_, message, found := getSentEmailMessage(t, email)
require.True(t, found)
code := strings.TrimPrefix(message, "Your login code: ")
challenge := initRes.Data.(map[string]any)["challenge"].(string)
answer := hexutil.Encode(crypto.Keccak256([]byte(challenge + code)))

openSessionData := intents.IntentDataOpenSession{
SessionID: signingSession.SessionID(),
IdentityType: intents.IdentityType_Email,
Verifier: email + ";" + signingSession.SessionID(),
Answer: answer,
}
openSession := generateSignedIntent(t, intents.IntentName_openSession, openSessionData, signingSession)

session, openSessionRes, err := c.RegisterSession(ctx, openSession, "friendly name")
require.NoError(t, err)
require.NotNil(t, openSessionRes)
require.NotNil(t, session)
}

// Try to sign up with OIDC using the same email address
{
sessWallet, err := ethwallet.NewWalletFromRandomEntropy()
require.NoError(t, err)
signingSession := intents.NewSessionP256K1(sessWallet)

hashedToken := hexutil.Encode(crypto.Keccak256([]byte(tok)))
verifier := hashedToken + ";" + strconv.Itoa(int(exp.Unix()))
initiateAuth := generateSignedIntent(t, intents.IntentName_initiateAuth, intents.IntentDataInitiateAuth{
SessionID: signingSession.SessionID(),
IdentityType: intents.IdentityType_OIDC,
Verifier: verifier,
}, signingSession)
initRes, err := c.SendIntent(ctx, initiateAuth)
require.NoError(t, err)
assert.Equal(t, proto.IntentResponseCode_authInitiated, initRes.Code)

b, err := json.Marshal(initRes.Data)
require.NoError(t, err)
var initResData intents.IntentResponseAuthInitiated
require.NoError(t, json.Unmarshal(b, &initResData))

registerSession := generateSignedIntent(t, intents.IntentName_openSession, intents.IntentDataOpenSession{
SessionID: signingSession.SessionID(),
IdentityType: intents.IdentityType_OIDC,
Verifier: verifier,
Answer: tok,
}, signingSession)
_, _, err = c.RegisterSession(ctx, registerSession, "Friendly name")

var wErr proto.WebRPCError
require.ErrorAs(t, err, &wErr)
assert.Equal(t, "Email|[email protected]", wErr.Cause)
}
}
80 changes: 41 additions & 39 deletions rpc/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ func initLocalstack() (string, func()) {

var currentProjectID atomic.Uint64

func newTenant(t *testing.T, enc *enclave.Enclave, issuer string) (*data.Tenant, *proto.TenantData) {
func newTenant(t *testing.T, enc *enclave.Enclave, opts ...func(*proto.TenantData)) (*data.Tenant, *proto.TenantData) {
att, err := enc.GetAttestation(context.Background(), nil)
require.NoError(t, err)

Expand All @@ -298,19 +298,19 @@ func newTenant(t *testing.T, enc *enclave.Enclave, issuer string) (*data.Tenant,
},
UpgradeCode: "CHANGEME",
WaasAccessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXJ0bmVyX2lkIjozfQ.g2fWwLrKPhTUpLFc7ZM9pMm4kEHGu8haCMzMOOGiqSM",
OIDCProviders: []*proto.OpenIdProvider{
{Issuer: issuer, Audience: []string{"audience"}},
{Issuer: "https://" + strings.TrimPrefix(issuer, "http://"), Audience: []string{"audience"}},
},
AllowedOrigins: validation.Origins{"http://localhost"},
KMSKeys: []string{"arn:aws:kms:us-east-1:000000000000:key/27ebbde0-49d2-4cb6-ad78-4f2c24fe7b79"},
AllowedOrigins: validation.Origins{"http://localhost"},
KMSKeys: []string{"arn:aws:kms:us-east-1:000000000000:key/27ebbde0-49d2-4cb6-ad78-4f2c24fe7b79"},
}

for _, opt := range opts {
opt(payload)
}

encryptedKey, algorithm, ciphertext, err := crypto.EncryptData(context.Background(), att, "27ebbde0-49d2-4cb6-ad78-4f2c24fe7b79", payload)
require.NoError(t, err)

return &data.Tenant{
ProjectID: projectID,
ProjectID: payload.ProjectID,
Version: 1,
EncryptedKey: encryptedKey,
Algorithm: algorithm,
Expand All @@ -319,43 +319,45 @@ func newTenant(t *testing.T, enc *enclave.Enclave, issuer string) (*data.Tenant,
}, payload
}

func newTenantWithAuthConfig(t *testing.T, enc *enclave.Enclave, authCfg proto.AuthConfig) (*data.Tenant, *proto.TenantData) {
att, err := enc.GetAttestation(context.Background(), nil)
require.NoError(t, err)
func withProjectID(projectID uint64) func(*proto.TenantData) {
return func(data *proto.TenantData) {
data.ProjectID = projectID
}
}

wallet, err := ethwallet.NewWalletFromRandomEntropy()
require.NoError(t, err)
func withOIDC(issuer string) func(*proto.TenantData) {
return func(data *proto.TenantData) {
data.OIDCProviders = []*proto.OpenIdProvider{
{Issuer: issuer, Audience: []string{"audience"}},
{Issuer: "https://" + strings.TrimPrefix(issuer, "http://"), Audience: []string{"audience"}},
}
}
}

projectID := currentProjectID.Add(1)
func withGuest() func(*proto.TenantData) {
return func(data *proto.TenantData) {
data.AuthConfig.Guest.Enabled = true
}
}

userSalt, _ := hexutil.Decode("0xa176de7902ef0781d2c6120cc5fd5add3048e1543f597ef4feae38391d234839")
payload := &proto.TenantData{
ProjectID: projectID,
PrivateKey: wallet.PrivateKeyHex()[2:],
ParentAddress: common.HexToAddress("0xcF104bc904E4dC1cCe0027aB9F9C905Ad3aE6c21"),
UserSalt: userSalt,
SequenceContext: &proto.MiniSequenceContext{
Factory: "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A",
MainModule: "0xfBf8f1A5E00034762D928f46d438B947f5d4065d",
},
UpgradeCode: "CHANGEME",
WaasAccessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXJ0bmVyX2lkIjozfQ.g2fWwLrKPhTUpLFc7ZM9pMm4kEHGu8haCMzMOOGiqSM",
AllowedOrigins: validation.Origins{"http://localhost"},
AuthConfig: authCfg,
KMSKeys: []string{"arn:aws:kms:us-east-1:000000000000:key/27ebbde0-49d2-4cb6-ad78-4f2c24fe7b79"},
func withEmail() func(*proto.TenantData) {
return func(data *proto.TenantData) {
data.AuthConfig.Email.Enabled = true
}
}

encryptedKey, algorithm, ciphertext, err := crypto.EncryptData(context.Background(), att, "27ebbde0-49d2-4cb6-ad78-4f2c24fe7b79", payload)
require.NoError(t, err)
func withPlayFab(titleID string) func(*proto.TenantData) {
return func(data *proto.TenantData) {
data.AuthConfig.Playfab.Enabled = true
data.AuthConfig.Playfab.TitleID = titleID
}
}

return &data.Tenant{
ProjectID: projectID,
Version: 1,
EncryptedKey: encryptedKey,
Algorithm: algorithm,
Ciphertext: ciphertext,
CreatedAt: time.Now(),
}, payload
func withStytch(stytchProjectID string) func(*proto.TenantData) {
return func(data *proto.TenantData) {
data.AuthConfig.Stytch.Enabled = true
data.AuthConfig.Stytch.ProjectID = stytchProjectID
}
}

func newAccount(t *testing.T, tnt *data.Tenant, enc *enclave.Enclave, identity proto.Identity, wallet *ethwallet.Wallet) *data.Account {
Expand Down
2 changes: 1 addition & 1 deletion rpc/identity_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func TestRPC_SendIntent_GetIdToken(t *testing.T) {

svc := initRPC(t)

tenant, tntData := newTenant(t, svc.Enclave, issuer)
tenant, tntData := newTenant(t, svc.Enclave, withOIDC(issuer))
acc := newAccount(t, tenant, svc.Enclave, newOIDCIdentity(issuer), sessWallet)
sess := newSession(t, tenant, svc.Enclave, issuer, signingSession)

Expand Down
2 changes: 1 addition & 1 deletion rpc/send_transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func TestRPC_SendIntent_SendTransaction(t *testing.T) {

svc := initRPC(t)

tenant, tntData := newTenant(t, svc.Enclave, issuer)
tenant, tntData := newTenant(t, svc.Enclave, withOIDC(issuer))
acc := newAccount(t, tenant, svc.Enclave, newOIDCIdentity(issuer), sessWallet)
sess := newSession(t, tenant, svc.Enclave, issuer, signingSession)

Expand Down
6 changes: 3 additions & 3 deletions rpc/sessions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func TestLegacyAuth(t *testing.T) {
walletService := newWalletServiceMock(nil)
svc.Wallets = walletService

tenant, _ := newTenant(t, svc.Enclave, issuer)
tenant, _ := newTenant(t, svc.Enclave, withOIDC(issuer))
account := newAccount(t, tenant, svc.Enclave, newOIDCIdentity("http://another-issuer"), nil)

require.NoError(t, svc.Tenants.Add(ctx, tenant))
Expand Down Expand Up @@ -307,7 +307,7 @@ func TestRPC_SendIntent_DropSession(t *testing.T) {

svc := initRPC(t)

tenant, _ := newTenant(t, svc.Enclave, issuer)
tenant, _ := newTenant(t, svc.Enclave, withOIDC(issuer))
acc := newAccount(t, tenant, svc.Enclave, newOIDCIdentity(issuer), sessWallet)
session := newSession(t, tenant, svc.Enclave, issuer, signingSession)

Expand Down Expand Up @@ -374,7 +374,7 @@ func TestRPC_SendIntent_ListSessions(t *testing.T) {

svc := initRPC(t)

tenant, tntData := newTenant(t, svc.Enclave, issuer)
tenant, tntData := newTenant(t, svc.Enclave, withOIDC(issuer))
acc := newAccount(t, tenant, svc.Enclave, newOIDCIdentity(issuer), sessWallet)
sess1 := newSession(t, tenant, svc.Enclave, issuer, signingSession)
sess2 := newSessionFromData(t, tenant, svc.Enclave, &proto.SessionData{
Expand Down
2 changes: 1 addition & 1 deletion rpc/sign_message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestRPC_SendIntent_SignMessage(t *testing.T) {

svc := initRPC(t)

tenant, tntData := newTenant(t, svc.Enclave, issuer)
tenant, tntData := newTenant(t, svc.Enclave, withOIDC(issuer))
acc := newAccount(t, tenant, svc.Enclave, newOIDCIdentity(issuer), sessWallet)
sess := newSession(t, tenant, svc.Enclave, issuer, signingSession)

Expand Down

0 comments on commit 821ed2b

Please sign in to comment.