Skip to content

Commit

Permalink
Merge pull request #91 from MysteriumNetwork/feature/MYST-114-sign-re…
Browse files Browse the repository at this point in the history
…gister-identity

MYST-114 sign register identity request
  • Loading branch information
Waldz committed Jan 11, 2018
2 parents e6d7d40 + 76b137a commit 53b48ea
Show file tree
Hide file tree
Showing 11 changed files with 62 additions and 32 deletions.
4 changes: 1 addition & 3 deletions client_connection/manager.go
Expand Up @@ -16,8 +16,6 @@ type DialogEstablisherFactory func(identity identity.Identity) communication.Dia

type VpnClientFactory func(vpnSession session.SessionDto, identity identity.Identity) (openvpn.Client, error)

type SignerFactory func(id identity.Identity) identity.Signer

type connectionManager struct {
//these are passed on creation
mysteriumClient server.Client
Expand Down Expand Up @@ -113,7 +111,7 @@ func statusDisconnecting() ConnectionStatus {
return ConnectionStatus{Disconnecting, "", nil}
}

func ConfigureVpnClientFactory(mysteriumApiClient server.Client, vpnClientRuntimeDirectory string, signerFactory SignerFactory) VpnClientFactory {
func ConfigureVpnClientFactory(mysteriumApiClient server.Client, vpnClientRuntimeDirectory string, signerFactory identity.SignerFactory) VpnClientFactory {
return func(vpnSession session.SessionDto, id identity.Identity) (openvpn.Client, error) {
vpnConfig, err := openvpn.NewClientConfigFromString(
vpnSession.Config,
Expand Down
8 changes: 7 additions & 1 deletion cmd/mysterium_client/command_run/command.go
Expand Up @@ -14,13 +14,15 @@ import (
"github.com/mysterium/node/tequilapi/endpoints"
)

//NewCommand function created new client command with options passed from commandline
func NewCommand(options CommandOptions) *CommandRun {
return NewCommandWith(
options,
server.NewClient(),
)
}

//NewCommandWith does the same as NewCommand with posibility to override mysterium api client for external communication
func NewCommandWith(
options CommandOptions,
mysteriumClient server.Client,
Expand All @@ -45,7 +47,7 @@ func NewCommandWith(
connectionManager := client_connection.NewManager(mysteriumClient, dialogEstablisherFactory, vpnClientFactory)

router := tequilapi.NewApiRouter()
endpoints.AddRoutesForIdentities(router, identityManager, mysteriumClient)
endpoints.AddRoutesForIdentities(router, identityManager, mysteriumClient, signerFactory)
endpoints.AddRoutesForConnection(router, connectionManager)
endpoints.AddRoutesForProposals(router, mysteriumClient)

Expand All @@ -57,11 +59,13 @@ func NewCommandWith(
}
}

//CommandRun represent entry point for MysteriumVpn client with top level components
type CommandRun struct {
connectionManager client_connection.Manager
httpApiServer tequilapi.ApiServer
}

//Run starts tequilaApi service - does not block
func (cmd *CommandRun) Run() error {
err := cmd.httpApiServer.StartServing()
if err != nil {
Expand All @@ -76,10 +80,12 @@ func (cmd *CommandRun) Run() error {
return nil
}

//Wait blocks until tequilapi service is stopped
func (cmd *CommandRun) Wait() error {
return cmd.httpApiServer.Wait()
}

//Kill stops tequilapi service
func (cmd *CommandRun) Kill() {
cmd.httpApiServer.Stop()
cmd.connectionManager.Disconnect()
Expand Down
1 change: 1 addition & 0 deletions cmd/mysterium_server/command_run/factory.go
Expand Up @@ -38,6 +38,7 @@ func NewCommandWith(
identity.NewIdentityManager(keystoreInstance),
mysteriumClient,
cache,
func(id identity.Identity) identity.Signer { return identity.NewSigner(keystoreInstance, id) },
)

return &CommandRun{
Expand Down
19 changes: 12 additions & 7 deletions cmd/mysterium_server/command_run/identity_handler.go
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/mysterium/node/server"
)

//SelectIdentity selects lastUsed identity or creates new one if keyOption is not present
func SelectIdentity(identityHandler *identityHandler, keyOption string) (id identity.Identity, err error) {
if len(keyOption) > 0 {
return identityHandler.UseExisting(keyOption)
Expand All @@ -21,20 +22,24 @@ func SelectIdentity(identityHandler *identityHandler, keyOption string) (id iden
const nodeIdentityPassword = ""

type identityHandler struct {
manager identity.IdentityManagerInterface
identityApi server.Client
cache identity.IdentityCacheInterface
manager identity.IdentityManagerInterface
identityApi server.Client
cache identity.IdentityCacheInterface
signerFactory identity.SignerFactory
}

//NewNodeIdentityHandler creates new identity handler used by node
func NewNodeIdentityHandler(
manager identity.IdentityManagerInterface,
identityApi server.Client,
cache identity.IdentityCacheInterface,
signerFactory identity.SignerFactory,
) *identityHandler {
return &identityHandler{
manager: manager,
identityApi: identityApi,
cache: cache,
manager: manager,
identityApi: identityApi,
cache: cache,
signerFactory: signerFactory,
}
}

Expand Down Expand Up @@ -64,7 +69,7 @@ func (ih *identityHandler) UseNew() (id identity.Identity, err error) {
return
}

if err = ih.identityApi.RegisterIdentity(id); err != nil {
if err = ih.identityApi.RegisterIdentity(id, ih.signerFactory(id)); err != nil {
return
}

Expand Down
17 changes: 14 additions & 3 deletions cmd/mysterium_server/command_run/identity_handler_test.go
Expand Up @@ -8,12 +8,16 @@ import (
"github.com/stretchr/testify/assert"
)

var fakeSignerFactory = func(id identity.Identity) identity.Signer {
return &fakeSigner{}
}

func Test_identityHandler_UseExisting(t *testing.T) {
identityManager := identity.NewIdentityManagerFake()
client := server.NewClientFake()
cache := identity.NewIdentityCacheFake()

handler := NewNodeIdentityHandler(identityManager, client, cache)
handler := NewNodeIdentityHandler(identityManager, client, cache, fakeSignerFactory)

id, err := handler.UseExisting("address")
assert.Equal(t, identityManager.FakeIdentity1, id)
Expand All @@ -29,7 +33,7 @@ func Test_identityHandler_UseLast(t *testing.T) {
fakeIdentity := identity.FromAddress("abc")
cache.StoreIdentity(fakeIdentity)

handler := NewNodeIdentityHandler(identityManager, client, cache)
handler := NewNodeIdentityHandler(identityManager, client, cache, fakeSignerFactory)

id, err := handler.UseLast()
assert.Equal(t, fakeIdentity, id)
Expand All @@ -42,10 +46,17 @@ func Test_identityHandler_UseNew(t *testing.T) {
client := server.NewClientFake()
cache := identity.NewIdentityCacheFake()

handler := NewNodeIdentityHandler(identityManager, client, cache)
handler := NewNodeIdentityHandler(identityManager, client, cache, fakeSignerFactory)

id, err := handler.UseNew()
assert.Equal(t, identityManager.FakeIdentity2, client.RegisteredIdentity)
assert.Equal(t, identityManager.FakeIdentity2, id)
assert.Nil(t, err)
}

type fakeSigner struct {
}

func (fs *fakeSigner) Sign(message []byte) (identity.Signature, error) {
return identity.SignatureHex("deadbeef"), nil //real hex!
}
2 changes: 2 additions & 0 deletions identity/signer.go
Expand Up @@ -5,6 +5,8 @@ import (
"github.com/ethereum/go-ethereum/crypto"
)

type SignerFactory func(id Identity) Signer

type Signer interface {
Sign(message []byte) (Signature, error)
}
Expand Down
3 changes: 2 additions & 1 deletion server/interface.go
Expand Up @@ -6,8 +6,9 @@ import (
dto_discovery "github.com/mysterium/node/service_discovery/dto"
)

//Client interface for mysterium centralized api - will be removed in the future
type Client interface {
RegisterIdentity(identity identity.Identity) (err error)
RegisterIdentity(identity identity.Identity, signer identity.Signer) (err error)
NodeRegister(proposal dto_discovery.ServiceProposal) (err error)
NodeSendStats(nodeKey string) (err error)
FindProposals(nodeKey string) (proposals []dto_discovery.ServiceProposal, err error)
Expand Down
7 changes: 4 additions & 3 deletions server/mysterium_api.go
Expand Up @@ -24,6 +24,7 @@ type mysteriumApi struct {
http HttpTransport
}

//NewClient creates mysterium centralized api instance with real communcation
func NewClient() Client {
return &mysteriumApi{
&http.Client{
Expand All @@ -32,10 +33,10 @@ func NewClient() Client {
}
}

func (mApi *mysteriumApi) RegisterIdentity(identity identity.Identity) error {
req, err := newPostRequest("identities", dto.CreateIdentityRequest{
func (mApi *mysteriumApi) RegisterIdentity(identity identity.Identity, signer identity.Signer) error {
req, err := newSignedPostRequest("identities", dto.CreateIdentityRequest{
Identity: identity.Address,
})
}, signer)
if err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions server/mysterium_api_fake.go
Expand Up @@ -26,9 +26,9 @@ func (client *ClientFake) NodeRegister(proposal dto_discovery.ServiceProposal) (
return nil
}

func (client *ClientFake) RegisterIdentity(identity identity.Identity) (err error) {
client.RegisteredIdentity = identity
log.Info(mysteriumApiLogPrefix, "Fake identity registered: ", identity)
func (client *ClientFake) RegisterIdentity(newIdentity identity.Identity, signer identity.Signer) (err error) {
client.RegisteredIdentity = newIdentity
log.Info(mysteriumApiLogPrefix, "Fake newIdentity registered: ", newIdentity)

return nil
}
Expand Down
12 changes: 8 additions & 4 deletions tequilapi/endpoints/identities.go
Expand Up @@ -31,6 +31,7 @@ type identityRegistrationDto struct {
type identitiesApi struct {
idm identity.IdentityManagerInterface
mysteriumClient server.Client
signerFactory identity.SignerFactory
}

func idToDto(id identity.Identity) identityDto {
Expand All @@ -45,8 +46,9 @@ func mapIdentities(idArry []identity.Identity, f func(identity.Identity) identit
return
}

func NewIdentitiesEndpoint(idm identity.IdentityManagerInterface, mystClient server.Client) *identitiesApi {
return &identitiesApi{idm, mystClient}
//NewIdentitiesEndpoint creates identities api controller used by tequilapi service
func NewIdentitiesEndpoint(idm identity.IdentityManagerInterface, mystClient server.Client, signerFactory identity.SignerFactory) *identitiesApi {
return &identitiesApi{idm, mystClient, signerFactory}
}

func (endpoint *identitiesApi) List(resp http.ResponseWriter, request *http.Request, _ httprouter.Params) {
Expand Down Expand Up @@ -90,7 +92,7 @@ func (endpoint *identitiesApi) Register(resp http.ResponseWriter, request *http.
return
}

err = endpoint.mysteriumClient.RegisterIdentity(id)
err = endpoint.mysteriumClient.RegisterIdentity(id, endpoint.signerFactory(id))
if err != nil {
utils.SendError(resp, err, http.StatusInternalServerError)
return
Expand Down Expand Up @@ -129,12 +131,14 @@ func validateCreationRequest(createReq *identityCreationDto) (errors *validation
return
}

//AddRoutesForIdentities creates /identities endpoint on tequilapi service
func AddRoutesForIdentities(
router *httprouter.Router,
idm identity.IdentityManagerInterface,
mystClient server.Client,
signerFactory identity.SignerFactory,
) {
idmEnd := NewIdentitiesEndpoint(idm, mystClient)
idmEnd := NewIdentitiesEndpoint(idm, mystClient, signerFactory)
router.GET("/identities", idmEnd.List)
router.POST("/identities", idmEnd.Create)
router.PUT("/identities/:id/registration", idmEnd.Register)
Expand Down
15 changes: 8 additions & 7 deletions tequilapi/endpoints/identities_test.go
Expand Up @@ -14,8 +14,9 @@ import (
const identityUrl = "/irrelevant"

var (
mockIdm = identity.NewIdentityManagerFake()
mystClient = server.NewClientFake()
mockIdm = identity.NewIdentityManagerFake()
mystClient = server.NewClientFake()
fakeSignerFactory = func(id identity.Identity) identity.Signer { return nil } //it works in this case - it's passed to fake myst client
)

func TestRegisterExistingIdentityRequest(t *testing.T) {
Expand All @@ -28,7 +29,7 @@ func TestRegisterExistingIdentityRequest(t *testing.T) {
assert.Nil(t, err)
resp := httptest.NewRecorder()

handlerFunc := NewIdentitiesEndpoint(mockIdm, mystClient).Register
handlerFunc := NewIdentitiesEndpoint(mockIdm, mystClient, fakeSignerFactory).Register
handlerFunc(resp, req, nil)

assert.Equal(t, http.StatusNotImplemented, resp.Code)
Expand All @@ -50,7 +51,7 @@ func TestRegisterIdentitySuccess(t *testing.T) {
resp := httptest.NewRecorder()

mockIdm := identity.NewIdentityManagerFake()
handlerFunc := NewIdentitiesEndpoint(mockIdm, mystClient).Register
handlerFunc := NewIdentitiesEndpoint(mockIdm, mystClient, fakeSignerFactory).Register
handlerFunc(resp, req, nil)

assert.Equal(t, http.StatusAccepted, resp.Code)
Expand Down Expand Up @@ -82,7 +83,7 @@ func TestCreateNewIdentityNoPassword(t *testing.T) {
assert.Nil(t, err)

resp := httptest.NewRecorder()
handlerFunc := NewIdentitiesEndpoint(mockIdm, mystClient).Create
handlerFunc := NewIdentitiesEndpoint(mockIdm, mystClient, fakeSignerFactory).Create
handlerFunc(resp, req, nil)

assert.Equal(t, http.StatusUnprocessableEntity, resp.Code)
Expand All @@ -108,7 +109,7 @@ func TestCreateNewIdentity(t *testing.T) {

resp := httptest.NewRecorder()

handlerFunc := NewIdentitiesEndpoint(mockIdm, mystClient).Create
handlerFunc := NewIdentitiesEndpoint(mockIdm, mystClient, fakeSignerFactory).Create
handlerFunc(resp, req, nil)

assert.JSONEq(
Expand All @@ -124,7 +125,7 @@ func TestListIdentities(t *testing.T) {
req := httptest.NewRequest("GET", "/irrelevant", nil)
resp := httptest.NewRecorder()

handlerFunc := NewIdentitiesEndpoint(mockIdm, mystClient).List
handlerFunc := NewIdentitiesEndpoint(mockIdm, mystClient, fakeSignerFactory).List
handlerFunc(resp, req, nil)

assert.JSONEq(
Expand Down

0 comments on commit 53b48ea

Please sign in to comment.