Skip to content

Commit

Permalink
Implement EIP-4361 sign in with Ethereum (#5)
Browse files Browse the repository at this point in the history
* Blacklist some sytest tests that are failing in our environment

* Commenting out test that isn't reliably passing or failing, probably a race

* refresh latest dendrite main

* refresh latest dendrite main

* dendrite implementation of eip-4361

* simplify nonce generation

Co-authored-by: Brian Meek <[email protected]>
Co-authored-by: Tak Wai Wong <[email protected]>
  • Loading branch information
3 people committed Oct 25, 2022
1 parent 3145a9d commit a2d0ea1
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 49 deletions.
2 changes: 1 addition & 1 deletion clientapi/auth/user_interactive.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ func (u *UserInteractive) ResponseWithChallenge(sessionID string, response inter
// Verify returns an error/challenge response to send to the client, or nil if the user is authenticated.
// `bodyBytes` is the HTTP request body which must contain an `auth` key.
// Returns the login that was verified for additional checks if required.
func (u *UserInteractive) Verify(ctx context.Context, bodyBytes []byte) (*Login, *util.JSONResponse) {
func (u *UserInteractive) Verify(ctx context.Context, bodyBytes []byte, device *api.Device) (*Login, *util.JSONResponse) {
// TODO: rate limit

// "A client should first make a request with no auth parameter. The homeserver returns an HTTP 401 response, with a JSON body"
Expand Down
11 changes: 8 additions & 3 deletions clientapi/auth/user_interactive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ var (
serverName = gomatrixserverlib.ServerName("example.com")
// space separated localpart+password -> account
lookup = make(map[string]*api.Account)
device = &api.Device{
AccessToken: "flibble",
DisplayName: "My Device",
ID: "device_id_goes_here",
}
)

type fakeAccountDatabase struct {
Expand Down Expand Up @@ -55,7 +60,7 @@ func setup() *UserInteractive {
func TestUserInteractiveChallenge(t *testing.T) {
uia := setup()
// no auth key results in a challenge
_, errRes := uia.Verify(ctx, []byte(`{}`))
_, errRes := uia.Verify(ctx, []byte(`{}`), device)
if errRes == nil {
t.Fatalf("Verify succeeded with {} but expected failure")
}
Expand Down Expand Up @@ -95,7 +100,7 @@ func TestUserInteractivePasswordLogin(t *testing.T) {
}`),
}
for _, tc := range testCases {
_, errRes := uia.Verify(ctx, tc)
_, errRes := uia.Verify(ctx, tc, device)
if errRes != nil {
t.Errorf("Verify failed but expected success for request: %s - got %+v", string(tc), errRes)
}
Expand Down Expand Up @@ -176,7 +181,7 @@ func TestUserInteractivePasswordBadLogin(t *testing.T) {
},
}
for _, tc := range testCases {
_, errRes := uia.Verify(ctx, tc.body)
_, errRes := uia.Verify(ctx, tc.body, device)
if errRes == nil {
t.Errorf("Verify succeeded but expected failure for request: %s", string(tc.body))
continue
Expand Down
2 changes: 1 addition & 1 deletion clientapi/routing/deactivate.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func Deactivate(
}
}

login, errRes := userInteractiveAuth.Verify(ctx, bodyBytes)
login, errRes := userInteractiveAuth.Verify(ctx, bodyBytes, deviceAPI)
if errRes != nil {
return *errRes
}
Expand Down
2 changes: 1 addition & 1 deletion clientapi/routing/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func DeleteDeviceById(
sessionID = s
}

login, errRes := userInteractiveAuth.Verify(ctx, bodyBytes)
login, errRes := userInteractiveAuth.Verify(ctx, bodyBytes, device)
if errRes != nil {
switch data := errRes.JSON.(type) {
case auth.Challenge:
Expand Down
43 changes: 0 additions & 43 deletions setup/config/config_clientapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package config
import (
"fmt"
"time"

"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
)

type ClientAPI struct {
Expand Down Expand Up @@ -162,44 +160,3 @@ func (r *RateLimiting) Defaults() {
r.Threshold = 5
r.CooloffMS = 500
}

type ethereumAuthParams struct {
Version uint32 `json:"version"`
ChainIDs []string `json:"chain_ids"`
}

type ethereumAuthConfig struct {
Enabled bool `yaml:"enabled"`
Version uint32 `yaml:"version"`
ChainIDs []string `yaml:"chain_ids"`
}

type publicKeyAuthentication struct {
Ethereum ethereumAuthConfig `yaml:"ethereum"`
}

func (pk *publicKeyAuthentication) Enabled() bool {
return pk.Ethereum.Enabled
}

func (pk *publicKeyAuthentication) GetPublicKeyRegistrationFlows() []authtypes.Flow {
var flows []authtypes.Flow
if pk.Ethereum.Enabled {
flows = append(flows, authtypes.Flow{Stages: []authtypes.LoginType{authtypes.LoginTypePublicKeyEthereum}})
}

return flows
}

func (pk *publicKeyAuthentication) GetPublicKeyRegistrationParams() map[string]interface{} {
params := make(map[string]interface{})
if pk.Ethereum.Enabled {
p := ethereumAuthParams{
Version: pk.Ethereum.Version,
ChainIDs: pk.Ethereum.ChainIDs,
}
params[authtypes.LoginTypePublicKeyEthereum] = p
}

return params
}

0 comments on commit a2d0ea1

Please sign in to comment.