diff --git a/exp/services/recoverysigner/cmd/serve.go b/exp/services/recoverysigner/cmd/serve.go index 61887e7ba4..f7b1f35ed5 100644 --- a/exp/services/recoverysigner/cmd/serve.go +++ b/exp/services/recoverysigner/cmd/serve.go @@ -45,9 +45,9 @@ func (c *ServeCommand) Command() *cobra.Command { }, { Name: "signing-key", - Usage: "Stellar signing key used for signing transactions (will be deprecated with per-account keys in the future)", + Usage: "Stellar signing key(s) used for signing transactions comma separated (first key is preferred signer) (will be deprecated with per-account keys in the future)", OptType: types.String, - ConfigKey: &opts.SigningKey, + ConfigKey: &opts.SigningKeys, Required: true, }, { diff --git a/exp/services/recoverysigner/internal/serve/account_delete.go b/exp/services/recoverysigner/internal/serve/account_delete.go index 418cd57beb..c59d7ac5ae 100644 --- a/exp/services/recoverysigner/internal/serve/account_delete.go +++ b/exp/services/recoverysigner/internal/serve/account_delete.go @@ -12,9 +12,9 @@ import ( ) type accountDeleteHandler struct { - Logger *supportlog.Entry - SigningAddress *keypair.FromAddress - AccountStore account.Store + Logger *supportlog.Entry + SigningAddresses []*keypair.FromAddress + AccountStore account.Store } type accountDeleteRequest struct { @@ -53,12 +53,16 @@ func (h accountDeleteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) return } + signers := []accountResponseSigner{} + for _, signingAddress := range h.SigningAddresses { + signers = append(signers, accountResponseSigner{ + Key: signingAddress.Address(), + }) + } resp := accountResponse{ Address: acc.Address, - Signer: h.SigningAddress.Address(), - Signers: []accountResponseSigner{ - {Key: h.SigningAddress.Address()}, - }, + Signer: h.SigningAddresses[0].Address(), + Signers: signers, } // Authorized if authenticated as the account. diff --git a/exp/services/recoverysigner/internal/serve/account_delete_test.go b/exp/services/recoverysigner/internal/serve/account_delete_test.go index ceba47e708..0bf99f7575 100644 --- a/exp/services/recoverysigner/internal/serve/account_delete_test.go +++ b/exp/services/recoverysigner/internal/serve/account_delete_test.go @@ -33,9 +33,12 @@ func TestAccountDelete_authenticatedNotAuthorized(t *testing.T) { }, }) h := accountDeleteHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -76,9 +79,12 @@ func TestAccountDelete_notAuthenticated(t *testing.T) { }, }) h := accountDeleteHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -119,9 +125,12 @@ func TestAccountDelete_notFound(t *testing.T) { }, }) h := accountDeleteHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -168,9 +177,12 @@ func TestAccountDelete_authenticatedByIdentityAddress(t *testing.T) { }, }) h := accountDeleteHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -206,6 +218,10 @@ func TestAccountDelete_authenticatedByIdentityAddress(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` @@ -237,9 +253,12 @@ func TestAccountDelete_authenticatedByAccountAddress(t *testing.T) { }, }) h := accountDeleteHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -274,6 +293,10 @@ func TestAccountDelete_authenticatedByAccountAddress(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` @@ -305,9 +328,12 @@ func TestAccountDelete_authenticatedByPhoneNumber(t *testing.T) { }, }) h := accountDeleteHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -343,6 +369,10 @@ func TestAccountDelete_authenticatedByPhoneNumber(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` @@ -374,9 +404,12 @@ func TestAccountDelete_authenticatedByEmail(t *testing.T) { }, }) h := accountDeleteHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -412,6 +445,10 @@ func TestAccountDelete_authenticatedByEmail(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` diff --git a/exp/services/recoverysigner/internal/serve/account_get.go b/exp/services/recoverysigner/internal/serve/account_get.go index 2c5f356b6e..a716d7c968 100644 --- a/exp/services/recoverysigner/internal/serve/account_get.go +++ b/exp/services/recoverysigner/internal/serve/account_get.go @@ -12,9 +12,9 @@ import ( ) type accountGetHandler struct { - Logger *supportlog.Entry - SigningAddress *keypair.FromAddress - AccountStore account.Store + Logger *supportlog.Entry + SigningAddresses []*keypair.FromAddress + AccountStore account.Store } type accountGetRequest struct { @@ -53,12 +53,16 @@ func (h accountGetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + signers := []accountResponseSigner{} + for _, signingAddress := range h.SigningAddresses { + signers = append(signers, accountResponseSigner{ + Key: signingAddress.Address(), + }) + } resp := accountResponse{ Address: acc.Address, - Signer: h.SigningAddress.Address(), - Signers: []accountResponseSigner{ - {Key: h.SigningAddress.Address()}, - }, + Signer: h.SigningAddresses[0].Address(), + Signers: signers, } // Authorized if authenticated as the account. diff --git a/exp/services/recoverysigner/internal/serve/account_get_test.go b/exp/services/recoverysigner/internal/serve/account_get_test.go index f904d57240..10db804c5f 100644 --- a/exp/services/recoverysigner/internal/serve/account_get_test.go +++ b/exp/services/recoverysigner/internal/serve/account_get_test.go @@ -33,9 +33,12 @@ func TestAccountGet_authenticatedNotAuthorized(t *testing.T) { }, }) h := accountGetHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -76,9 +79,12 @@ func TestAccountGet_notAuthenticated(t *testing.T) { }, }) h := accountGetHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -119,9 +125,12 @@ func TestAccountGet_notFound(t *testing.T) { }, }) h := accountGetHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -168,9 +177,12 @@ func TestAccountGet_authenticatedByIdentityAddress(t *testing.T) { }, }) h := accountGetHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -206,6 +218,10 @@ func TestAccountGet_authenticatedByIdentityAddress(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` @@ -233,9 +249,12 @@ func TestAccountGet_authenticatedByAccountAddress(t *testing.T) { }, }) h := accountGetHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -270,6 +289,10 @@ func TestAccountGet_authenticatedByAccountAddress(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` @@ -297,9 +320,12 @@ func TestAccountGet_authenticatedByPhoneNumber(t *testing.T) { }, }) h := accountGetHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -335,6 +361,10 @@ func TestAccountGet_authenticatedByPhoneNumber(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` @@ -362,9 +392,12 @@ func TestAccountGet_authenticatedByEmail(t *testing.T) { }, }) h := accountGetHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -400,6 +433,10 @@ func TestAccountGet_authenticatedByEmail(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` diff --git a/exp/services/recoverysigner/internal/serve/account_list.go b/exp/services/recoverysigner/internal/serve/account_list.go index 88c278683c..9aedcd0381 100644 --- a/exp/services/recoverysigner/internal/serve/account_list.go +++ b/exp/services/recoverysigner/internal/serve/account_list.go @@ -11,9 +11,9 @@ import ( ) type accountListHandler struct { - Logger *supportlog.Entry - SigningAddress *keypair.FromAddress - AccountStore account.Store + Logger *supportlog.Entry + SigningAddresses []*keypair.FromAddress + AccountStore account.Store } type accountListResponse struct { @@ -48,12 +48,16 @@ func (h accountListHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { serverError.Render(w) return } else { + signers := []accountResponseSigner{} + for _, signingAddress := range h.SigningAddresses { + signers = append(signers, accountResponseSigner{ + Key: signingAddress.Address(), + }) + } accResp := accountResponse{ Address: acc.Address, - Signer: h.SigningAddress.Address(), - Signers: []accountResponseSigner{ - {Key: h.SigningAddress.Address()}, - }, + Signer: h.SigningAddresses[0].Address(), + Signers: signers, } for _, i := range acc.Identities { accRespIdentity := accountResponseIdentity{ @@ -75,12 +79,16 @@ func (h accountListHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } for _, acc := range accs { + signers := []accountResponseSigner{} + for _, signingAddress := range h.SigningAddresses { + signers = append(signers, accountResponseSigner{ + Key: signingAddress.Address(), + }) + } accResp := accountResponse{ Address: acc.Address, - Signer: h.SigningAddress.Address(), - Signers: []accountResponseSigner{ - {Key: h.SigningAddress.Address()}, - }, + Signer: h.SigningAddresses[0].Address(), + Signers: signers, } for _, i := range acc.Identities { accRespIdentity := accountResponseIdentity{ @@ -110,12 +118,16 @@ func (h accountListHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } for _, acc := range accs { + signers := []accountResponseSigner{} + for _, signingAddress := range h.SigningAddresses { + signers = append(signers, accountResponseSigner{ + Key: signingAddress.Address(), + }) + } accResp := accountResponse{ Address: acc.Address, - Signer: h.SigningAddress.Address(), - Signers: []accountResponseSigner{ - {Key: h.SigningAddress.Address()}, - }, + Signer: h.SigningAddresses[0].Address(), + Signers: signers, } for _, i := range acc.Identities { accRespIdentity := accountResponseIdentity{ @@ -145,12 +157,16 @@ func (h accountListHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } for _, acc := range accs { + signers := []accountResponseSigner{} + for _, signingAddress := range h.SigningAddresses { + signers = append(signers, accountResponseSigner{ + Key: signingAddress.Address(), + }) + } accResp := accountResponse{ Address: acc.Address, - Signer: h.SigningAddress.Address(), - Signers: []accountResponseSigner{ - {Key: h.SigningAddress.Address()}, - }, + Signer: h.SigningAddresses[0].Address(), + Signers: signers, } for _, i := range acc.Identities { accRespIdentity := accountResponseIdentity{ diff --git a/exp/services/recoverysigner/internal/serve/account_list_test.go b/exp/services/recoverysigner/internal/serve/account_list_test.go index 6204cf61d8..54e03e15da 100644 --- a/exp/services/recoverysigner/internal/serve/account_list_test.go +++ b/exp/services/recoverysigner/internal/serve/account_list_test.go @@ -46,9 +46,12 @@ func TestAccountList_authenticatedButNonePermitted(t *testing.T) { }, }) h := accountListHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -108,9 +111,12 @@ func TestAccountList_authenticatedByPhoneNumber(t *testing.T) { }, }) h := accountListHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -140,6 +146,10 @@ func TestAccountList_authenticatedByPhoneNumber(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }, @@ -153,6 +163,10 @@ func TestAccountList_authenticatedByPhoneNumber(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] } @@ -197,9 +211,12 @@ func TestAccountList_authenticatedByEmail(t *testing.T) { }, }) h := accountListHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -229,6 +246,10 @@ func TestAccountList_authenticatedByEmail(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }, @@ -242,6 +263,10 @@ func TestAccountList_authenticatedByEmail(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] } @@ -286,9 +311,12 @@ func TestAccountList_notAuthenticated(t *testing.T) { }, }) h := accountListHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() diff --git a/exp/services/recoverysigner/internal/serve/account_post.go b/exp/services/recoverysigner/internal/serve/account_post.go index d6cf9a5da1..05d467f618 100644 --- a/exp/services/recoverysigner/internal/serve/account_post.go +++ b/exp/services/recoverysigner/internal/serve/account_post.go @@ -13,9 +13,9 @@ import ( ) type accountPostHandler struct { - Logger *supportlog.Entry - SigningAddress *keypair.FromAddress - AccountStore account.Store + Logger *supportlog.Entry + SigningAddresses []*keypair.FromAddress + AccountStore account.Store } type accountPostRequest struct { @@ -139,12 +139,16 @@ func (h accountPostHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { l.Info("Account registered.") + signers := []accountResponseSigner{} + for _, signingAddress := range h.SigningAddresses { + signers = append(signers, accountResponseSigner{ + Key: signingAddress.Address(), + }) + } resp := accountResponse{ Address: acc.Address, - Signer: h.SigningAddress.Address(), - Signers: []accountResponseSigner{ - {Key: h.SigningAddress.Address()}, - }, + Signer: h.SigningAddresses[0].Address(), + Signers: signers, } for _, i := range acc.Identities { respIdentity := accountResponseIdentity{ diff --git a/exp/services/recoverysigner/internal/serve/account_post_test.go b/exp/services/recoverysigner/internal/serve/account_post_test.go index 85eba61643..9914e0634a 100644 --- a/exp/services/recoverysigner/internal/serve/account_post_test.go +++ b/exp/services/recoverysigner/internal/serve/account_post_test.go @@ -22,9 +22,12 @@ import ( func TestAccountPost_newWithRoleOwnerContentTypeJSON(t *testing.T) { s := &account.DBStore{DB: dbtest.Open(t).Open()} h := accountPostHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -66,6 +69,10 @@ func TestAccountPost_newWithRoleOwnerContentTypeJSON(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` @@ -92,9 +99,12 @@ func TestAccountPost_newWithRoleOwnerContentTypeJSON(t *testing.T) { func TestAccountPost_newWithRoleOwnerContentTypeForm(t *testing.T) { s := &account.DBStore{DB: dbtest.Open(t).Open()} h := accountPostHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -135,6 +145,10 @@ func TestAccountPost_newWithRoleOwnerContentTypeForm(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` @@ -161,9 +175,12 @@ func TestAccountPost_newWithRoleOwnerContentTypeForm(t *testing.T) { func TestAccountPost_newWithRolesSenderReceiverContentTypeJSON(t *testing.T) { s := &account.DBStore{DB: dbtest.Open(t).Open()} h := accountPostHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -214,6 +231,10 @@ func TestAccountPost_newWithRolesSenderReceiverContentTypeJSON(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` @@ -248,9 +269,12 @@ func TestAccountPost_newWithRolesSenderReceiverContentTypeJSON(t *testing.T) { func TestAccountPost_newWithRolesSenderReceiverContentTypeForm(t *testing.T) { s := &account.DBStore{DB: dbtest.Open(t).Open()} h := accountPostHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -299,6 +323,10 @@ func TestAccountPost_newWithRolesSenderReceiverContentTypeForm(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` @@ -336,9 +364,12 @@ func TestAccountPost_accountAddressInvalid(t *testing.T) { Address: "GDIXCQJ2W2N6TAS6AYW4LW2EBV7XNRUCLNHQB37FARDEWBQXRWP47Q6N", }) h := accountPostHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -374,9 +405,12 @@ func TestAccountPost_accountAlreadyExists(t *testing.T) { Address: "GDIXCQJ2W2N6TAS6AYW4LW2EBV7XNRUCLNHQB37FARDEWBQXRWP47Q6N", }) h := accountPostHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -422,9 +456,12 @@ func TestAccountPost_accountAlreadyExists(t *testing.T) { func TestAccountPost_identitiesNotProvided(t *testing.T) { s := &account.DBStore{DB: dbtest.Open(t).Open()} h := accountPostHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -457,9 +494,12 @@ func TestAccountPost_identitiesNotProvided(t *testing.T) { func TestAccountPost_roleNotProvided(t *testing.T) { s := &account.DBStore{DB: dbtest.Open(t).Open()} h := accountPostHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -502,9 +542,12 @@ func TestAccountPost_roleNotProvided(t *testing.T) { func TestAccountPost_authMethodsNotProvided(t *testing.T) { s := &account.DBStore{DB: dbtest.Open(t).Open()} h := accountPostHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -546,9 +589,12 @@ func TestAccountPost_authMethodTypeUnrecognized(t *testing.T) { Address: "GDIXCQJ2W2N6TAS6AYW4LW2EBV7XNRUCLNHQB37FARDEWBQXRWP47Q6N", }) h := accountPostHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -597,9 +643,12 @@ func TestAccountPost_authMethodTypeUnrecognized(t *testing.T) { func TestAccountPost_notAuthenticatedForAccount(t *testing.T) { s := &account.DBStore{DB: dbtest.Open(t).Open()} h := accountPostHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() diff --git a/exp/services/recoverysigner/internal/serve/account_put.go b/exp/services/recoverysigner/internal/serve/account_put.go index cf8e3654a1..ad8ce8b83e 100644 --- a/exp/services/recoverysigner/internal/serve/account_put.go +++ b/exp/services/recoverysigner/internal/serve/account_put.go @@ -13,9 +13,9 @@ import ( ) type accountPutHandler struct { - Logger *supportlog.Entry - SigningAddress *keypair.FromAddress - AccountStore account.Store + Logger *supportlog.Entry + SigningAddresses []*keypair.FromAddress + AccountStore account.Store } type accountPutRequest struct { @@ -165,12 +165,16 @@ func (h accountPutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { l.Info("Account updated.") + signers := []accountResponseSigner{} + for _, signingAddress := range h.SigningAddresses { + signers = append(signers, accountResponseSigner{ + Key: signingAddress.Address(), + }) + } resp := accountResponse{ Address: accWithNewIdentiies.Address, - Signer: h.SigningAddress.Address(), - Signers: []accountResponseSigner{ - {Key: h.SigningAddress.Address()}, - }, + Signer: h.SigningAddresses[0].Address(), + Signers: signers, } for _, i := range accWithNewIdentiies.Identities { resp.Identities = append(resp.Identities, accountResponseIdentity{ diff --git a/exp/services/recoverysigner/internal/serve/account_put_test.go b/exp/services/recoverysigner/internal/serve/account_put_test.go index 4409837e4f..33ad0420dd 100644 --- a/exp/services/recoverysigner/internal/serve/account_put_test.go +++ b/exp/services/recoverysigner/internal/serve/account_put_test.go @@ -38,9 +38,12 @@ func TestAccountPut_authenticatedNotAuthorized(t *testing.T) { }, }) h := accountPutHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -99,9 +102,12 @@ func TestAccountPut_notAuthenticated(t *testing.T) { }, }) h := accountPutHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -160,9 +166,12 @@ func TestAccountPut_authenticatedByAccountAddress(t *testing.T) { }, }) h := accountPutHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -206,6 +215,10 @@ func TestAccountPut_authenticatedByAccountAddress(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` @@ -250,9 +263,12 @@ func TestAccountPut_authenticatedByIdentityAddress(t *testing.T) { }, }) h := accountPutHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -296,6 +312,10 @@ func TestAccountPut_authenticatedByIdentityAddress(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` @@ -340,9 +360,12 @@ func TestAccountPut_authenticatedByPhoneNumber(t *testing.T) { }, }) h := accountPutHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -386,6 +409,10 @@ func TestAccountPut_authenticatedByPhoneNumber(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` @@ -430,9 +457,12 @@ func TestAccountPut_authenticatedByEmail(t *testing.T) { }, }) h := accountPutHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningAddress: keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningAddresses: []*keypair.FromAddress{ + keypair.MustParseAddress("GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE"), + keypair.MustParseAddress("GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS"), + }, } ctx := context.Background() @@ -476,6 +506,10 @@ func TestAccountPut_authenticatedByEmail(t *testing.T) { { "key": "GCAPXRXSU7P6D353YGXMP6ROJIC744HO5OZCIWTXZQK2X757YU5KCHUE", "added_at": "0001-01-01T00:00:00Z" + }, + { + "key": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "added_at": "0001-01-01T00:00:00Z" } ] }` diff --git a/exp/services/recoverysigner/internal/serve/account_sign.go b/exp/services/recoverysigner/internal/serve/account_sign.go index fdf45a925d..a6c388b566 100644 --- a/exp/services/recoverysigner/internal/serve/account_sign.go +++ b/exp/services/recoverysigner/internal/serve/account_sign.go @@ -14,7 +14,7 @@ import ( type accountSignHandler struct { Logger *supportlog.Entry - SigningKey *keypair.Full + SigningKeys []*keypair.Full NetworkPassphrase string AccountStore account.Store } @@ -57,10 +57,22 @@ func (h accountSignHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { l.Info("Request to sign transaction.") - if req.SigningAddress != nil && req.SigningAddress.Address() != h.SigningKey.Address() { - l.Info("Signing key not found.") - notFound.Render(w) - return + var signingKey *keypair.Full + if req.SigningAddress != nil { + for _, sk := range h.SigningKeys { + if req.SigningAddress.Address() == sk.Address() { + signingKey = sk + break + } + } + if signingKey == nil { + l.Info("Signing key not found.") + notFound.Render(w) + return + } + } + if signingKey == nil { + signingKey = h.SigningKeys[0] } // Find the account that the request is for. @@ -149,7 +161,7 @@ func (h accountSignHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { serverError.Render(w) return } - sig, err := h.SigningKey.SignBase64(hash[:]) + sig, err := signingKey.SignBase64(hash[:]) if err != nil { l.Error("Error signing transaction:", err) serverError.Render(w) @@ -159,7 +171,7 @@ func (h accountSignHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { l.Info("Transaction signed.") resp := accountSignResponse{ - Signer: h.SigningKey.Address(), + Signer: signingKey.Address(), Signature: sig, NetworkPassphrase: h.NetworkPassphrase, } diff --git a/exp/services/recoverysigner/internal/serve/account_sign_signing_address_test.go b/exp/services/recoverysigner/internal/serve/account_sign_signing_address_test.go index e9e22fc662..9a32d9fda9 100644 --- a/exp/services/recoverysigner/internal/serve/account_sign_signing_address_test.go +++ b/exp/services/recoverysigner/internal/serve/account_sign_signing_address_test.go @@ -27,9 +27,12 @@ import ( func TestAccountSign_signingAddressAuthenticatedButNotFound(t *testing.T) { s := &account.DBStore{DB: dbtest.Open(t).Open()} h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -70,9 +73,12 @@ func TestAccountSign_signingAddressAccountAuthenticatedButNotPermitted(t *testin Address: "GBLOP46WEVXWO5N75TDX7GXLYFQE3XLDT5NQ2VYIBEWWEMSZWR3AUISZ", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -105,9 +111,12 @@ func TestAccountSign_signingAddressAccountAuthenticatedButNotPermitted(t *testin func TestAccountSign_signingAddressAccountAuthenticatedButInvalidAddress(t *testing.T) { s := &account.DBStore{DB: dbtest.Open(t).Open()} h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -135,9 +144,12 @@ func TestAccountSign_signingAddressAccountAuthenticatedButInvalidAddress(t *test func TestAccountSign_signingAddressAccountAuthenticatedButEmptyAddress(t *testing.T) { s := &account.DBStore{DB: dbtest.Open(t).Open()} h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -201,9 +213,12 @@ func TestAccountSign_signingAddressPhoneNumberAuthenticatedButNotPermitted(t *te }, }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -272,9 +287,12 @@ func TestAccountSign_signingAddressEmailAuthenticatedButNotPermitted(t *testing. }, }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -311,9 +329,12 @@ func TestAccountSign_signingAddressAccountAuthenticatedButSigningAddressInvalid( Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -364,6 +385,70 @@ func TestAccountSign_signingAddressAccountAuthenticatedButSigningAddressInvalid( assert.JSONEq(t, wantBody, string(body)) } +func TestAccountSign_signingAddressAccountAuthenticatedOtherSignerSelected(t *testing.T) { + s := &account.DBStore{DB: dbtest.Open(t).Open()} + s.Add(account.Account{ + Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", + }) + h := accountSignHandler{ + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, + NetworkPassphrase: network.TestNetworkPassphrase, + } + + tx, err := txnbuild.NewTransaction( + txnbuild.TransactionParams{ + SourceAccount: &txnbuild.SimpleAccount{AccountID: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4"}, + IncrementSequenceNum: true, + Operations: []txnbuild.Operation{ + &txnbuild.SetOptions{ + Signer: &txnbuild.Signer{ + Address: "GD7CGJSJ5OBOU5KOP2UQDH3MPY75UTEY27HVV5XPSL2X6DJ2VGTOSXEU", + Weight: 20, + }, + }, + }, + BaseFee: txnbuild.MinBaseFee, + Timebounds: txnbuild.NewTimebounds(0, 1), + }, + ) + require.NoError(t, err) + txEnc, err := tx.Base64() + require.NoError(t, err) + t.Log("Tx:", txEnc) + + ctx := context.Background() + ctx = auth.NewContext(ctx, auth.Auth{Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4"}) + req := `{ + "transaction": "` + txEnc + `" +}` + r := httptest.NewRequest("POST", "/GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4/sign/GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", strings.NewReader(req)) + r = r.WithContext(ctx) + + w := httptest.NewRecorder() + m := chi.NewMux() + m.Post("/{address}/sign/{signing-address}", h.ServeHTTP) + m.ServeHTTP(w, r) + resp := w.Result() + + require.Equal(t, http.StatusOK, resp.StatusCode) + assert.Equal(t, "application/json; charset=utf-8", resp.Header.Get("Content-Type")) + + body, err := ioutil.ReadAll(resp.Body) + require.NoError(t, err) + + wantBody := `{ + "signer": "GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS", + "signature": "8Tew6rTol9me8H9u7ezJXg6SEqzOr7cwSf1y9+Vri275XEDH9xWtZ2klTX2uUSPy56otUoIySPqsV3dUFs2kDA==", + "network_passphrase": "Test SDF Network ; September 2015" +}` + assert.JSONEq(t, wantBody, string(body)) +} + // Test that when the source account of the transaction matches the account the // request is for, that the transaction is signed and a signature is returned. // The operation source account does not need to be set. @@ -373,9 +458,12 @@ func TestAccountSign_signingAddressAccountAuthenticatedTxSourceAccountValid(t *t Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -437,9 +525,12 @@ func TestAccountSign_signingAddressAccountAuthenticatedTxAndOpSourceAccountValid Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -501,9 +592,12 @@ func TestAccountSign_signingAddressAccountAuthenticatedTxSourceAccountInvalid(t Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -561,9 +655,12 @@ func TestAccountSign_signingAddressAccountAuthenticatedOpSourceAccountInvalid(t Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -622,9 +719,12 @@ func TestAccountSign_signingAddressAccountAuthenticatedTxAndOpSourceAccountInval Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -689,9 +789,12 @@ func TestAccountSign_signingAddressPhoneNumberOwnerAuthenticated(t *testing.T) { }, }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -759,9 +862,12 @@ func TestAccountSign_signingAddressPhoneNumberOtherAuthenticated(t *testing.T) { }, }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -829,9 +935,12 @@ func TestAccountSign_signingAddressEmailOwnerAuthenticated(t *testing.T) { }, }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -899,9 +1008,12 @@ func TestAccountSign_signingAddressEmailOtherAuthenticated(t *testing.T) { }, }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -961,9 +1073,12 @@ func TestAccountSign_signingAddressCannotParseTransaction(t *testing.T) { Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -1000,9 +1115,12 @@ func TestAccountSign_signingAddressRejectsFeeBumpTx(t *testing.T) { Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -1090,9 +1208,12 @@ func TestAccountSign_signingAddressValidContentTypeForm(t *testing.T) { Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } diff --git a/exp/services/recoverysigner/internal/serve/account_sign_test.go b/exp/services/recoverysigner/internal/serve/account_sign_test.go index 2de021e99a..4b92dbd295 100644 --- a/exp/services/recoverysigner/internal/serve/account_sign_test.go +++ b/exp/services/recoverysigner/internal/serve/account_sign_test.go @@ -2,7 +2,6 @@ package serve import ( "context" - "github.com/stellar/go/xdr" "io/ioutil" "net/http" "net/http/httptest" @@ -10,6 +9,8 @@ import ( "strings" "testing" + "github.com/stellar/go/xdr" + "github.com/go-chi/chi" "github.com/stellar/go/exp/services/recoverysigner/internal/account" "github.com/stellar/go/exp/services/recoverysigner/internal/db/dbtest" @@ -26,9 +27,12 @@ import ( func TestAccountSign_authenticatedButNotFound(t *testing.T) { s := &account.DBStore{DB: dbtest.Open(t).Open()} h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -69,9 +73,12 @@ func TestAccountSign_accountAuthenticatedButNotPermitted(t *testing.T) { Address: "GBLOP46WEVXWO5N75TDX7GXLYFQE3XLDT5NQ2VYIBEWWEMSZWR3AUISZ", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -104,9 +111,12 @@ func TestAccountSign_accountAuthenticatedButNotPermitted(t *testing.T) { func TestAccountSign_accountAuthenticatedButInvalidAddress(t *testing.T) { s := &account.DBStore{DB: dbtest.Open(t).Open()} h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -134,9 +144,12 @@ func TestAccountSign_accountAuthenticatedButInvalidAddress(t *testing.T) { func TestAccountSign_accountAuthenticatedButEmptyAddress(t *testing.T) { s := &account.DBStore{DB: dbtest.Open(t).Open()} h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -200,9 +213,12 @@ func TestAccountSign_phoneNumberAuthenticatedButNotPermitted(t *testing.T) { }, }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -271,9 +287,12 @@ func TestAccountSign_emailAuthenticatedButNotPermitted(t *testing.T) { }, }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -312,9 +331,12 @@ func TestAccountSign_accountAuthenticatedTxSourceAccountValid(t *testing.T) { Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -376,9 +398,12 @@ func TestAccountSign_accountAuthenticatedTxAndOpSourceAccountValid(t *testing.T) Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -440,9 +465,12 @@ func TestAccountSign_accountAuthenticatedTxSourceAccountInvalid(t *testing.T) { Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -500,9 +528,12 @@ func TestAccountSign_accountAuthenticatedOpSourceAccountInvalid(t *testing.T) { Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -561,9 +592,12 @@ func TestAccountSign_accountAuthenticatedTxAndOpSourceAccountInvalid(t *testing. Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -628,9 +662,12 @@ func TestAccountSign_phoneNumberOwnerAuthenticated(t *testing.T) { }, }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -698,9 +735,12 @@ func TestAccountSign_phoneNumberOtherAuthenticated(t *testing.T) { }, }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -768,9 +808,12 @@ func TestAccountSign_emailOwnerAuthenticated(t *testing.T) { }, }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -838,9 +881,12 @@ func TestAccountSign_emailOtherAuthenticated(t *testing.T) { }, }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -900,9 +946,12 @@ func TestAccountSign_cannotParseTransaction(t *testing.T) { Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -939,9 +988,12 @@ func TestAccountSign_rejectsFeeBumpTx(t *testing.T) { Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } @@ -1029,9 +1081,12 @@ func TestAccountSign_validContentTypeForm(t *testing.T) { Address: "GA6HNE7O2N2IXIOBZNZ4IPTS2P6DSAJJF5GD5PDLH5GYOZ6WMPSKCXD4", }) h := accountSignHandler{ - Logger: supportlog.DefaultLogger, - AccountStore: s, - SigningKey: keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), + Logger: supportlog.DefaultLogger, + AccountStore: s, + SigningKeys: []*keypair.Full{ + keypair.MustParseFull("SBIB72S6JMTGJRC6LMKLC5XMHZ2IOHZSZH4SASTN47LECEEJ7QEB6EYK"), // GBOG4KF66M4AFRBUHOTJQJRO7BGGFCSGIICTI5BHXHKXCWV2C67QRN5H + keypair.MustParseFull("SBJGZKZ7LU2FQNEFBUOBW4LHCA5BOZCABIJTR7BQIFWQ3P763ZW7MYDD"), // GAPE22DOMALCH42VOR4S3HN6KIZZ643G7D3GNTYF4YOWWXP6UVRAF5JS + }, NetworkPassphrase: network.TestNetworkPassphrase, } diff --git a/exp/services/recoverysigner/internal/serve/serve.go b/exp/services/recoverysigner/internal/serve/serve.go index 1ee0f9d570..e749b55cd3 100644 --- a/exp/services/recoverysigner/internal/serve/serve.go +++ b/exp/services/recoverysigner/internal/serve/serve.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/http" + "strings" firebaseauth "firebase.google.com/go/auth" "github.com/go-chi/chi" @@ -24,7 +25,7 @@ type Options struct { DatabaseURL string Port int NetworkPassphrase string - SigningKey string + SigningKeys string SEP10JWKS string SEP10JWTIssuer string FirebaseProjectID string @@ -63,7 +64,8 @@ func Serve(opts Options) { type handlerDeps struct { Logger *supportlog.Entry NetworkPassphrase string - SigningKey *keypair.Full + SigningKeys []*keypair.Full + SigningAddresses []*keypair.FromAddress AccountStore account.Store SEP10JWK jose.JSONWebKey SEP10JWTIssuer string @@ -75,14 +77,20 @@ func getHandlerDeps(opts Options) (handlerDeps, error) { // TODO: Replace this signing key with randomly generating a unique signing // key for each account so that it is not possible to identify which // accounts are recoverable via a recovery signer. - signingKey, err := keypair.ParseFull(opts.SigningKey) - if err != nil { - return handlerDeps{}, errors.Wrap(err, "parsing signing key seed") + signingKeys := []*keypair.Full{} + signingAddresses := []*keypair.FromAddress{} + for i, signingKeyStr := range strings.Split(opts.SigningKeys, ",") { + signingKey, err := keypair.ParseFull(signingKeyStr) + if err != nil { + return handlerDeps{}, errors.Wrap(err, "parsing signing key seed") + } + signingKeys = append(signingKeys, signingKey) + signingAddresses = append(signingAddresses, signingKey.FromAddress()) + opts.Logger.Info("Signing key ", i, ": ", signingKey.Address()) } - opts.Logger.Info("Signing key: ", signingKey.Address()) sep10JWKS := &jose.JSONWebKeySet{} - err = json.Unmarshal([]byte(opts.SEP10JWKS), sep10JWKS) + err := json.Unmarshal([]byte(opts.SEP10JWKS), sep10JWKS) if err != nil { return handlerDeps{}, errors.Wrap(err, "parsing SEP-10 JSON Web Key (JWK) Set") } @@ -136,7 +144,8 @@ func getHandlerDeps(opts Options) (handlerDeps, error) { deps := handlerDeps{ Logger: opts.Logger, NetworkPassphrase: opts.NetworkPassphrase, - SigningKey: signingKey, + SigningKeys: signingKeys, + SigningAddresses: signingAddresses, AccountStore: accountStore, SEP10JWK: sep10JWK, SEP10JWTIssuer: opts.SEP10JWTIssuer, @@ -158,34 +167,34 @@ func handler(deps handlerDeps) http.Handler { mux.Use(auth.SEP10Middleware(deps.SEP10JWTIssuer, deps.SEP10JWK)) mux.Use(auth.FirebaseMiddleware(auth.FirebaseTokenVerifierLive{AuthClient: deps.FirebaseAuthClient})) mux.Get("/", accountListHandler{ - Logger: deps.Logger, - SigningAddress: deps.SigningKey.FromAddress(), - AccountStore: deps.AccountStore, + Logger: deps.Logger, + SigningAddresses: deps.SigningAddresses, + AccountStore: deps.AccountStore, }.ServeHTTP) mux.Route("/{address}", func(mux chi.Router) { mux.Post("/", accountPostHandler{ - Logger: deps.Logger, - SigningAddress: deps.SigningKey.FromAddress(), - AccountStore: deps.AccountStore, + Logger: deps.Logger, + SigningAddresses: deps.SigningAddresses, + AccountStore: deps.AccountStore, }.ServeHTTP) mux.Put("/", accountPutHandler{ - Logger: deps.Logger, - SigningAddress: deps.SigningKey.FromAddress(), - AccountStore: deps.AccountStore, + Logger: deps.Logger, + SigningAddresses: deps.SigningAddresses, + AccountStore: deps.AccountStore, }.ServeHTTP) mux.Get("/", accountGetHandler{ - Logger: deps.Logger, - SigningAddress: deps.SigningKey.FromAddress(), - AccountStore: deps.AccountStore, + Logger: deps.Logger, + SigningAddresses: deps.SigningAddresses, + AccountStore: deps.AccountStore, }.ServeHTTP) mux.Delete("/", accountDeleteHandler{ - Logger: deps.Logger, - SigningAddress: deps.SigningKey.FromAddress(), - AccountStore: deps.AccountStore, + Logger: deps.Logger, + SigningAddresses: deps.SigningAddresses, + AccountStore: deps.AccountStore, }.ServeHTTP) signHandler := accountSignHandler{ Logger: deps.Logger, - SigningKey: deps.SigningKey, + SigningKeys: deps.SigningKeys, NetworkPassphrase: deps.NetworkPassphrase, AccountStore: deps.AccountStore, }