From 951f40dd32db235dedf230bd3823b1d630977ab2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 6 Aug 2020 19:02:25 +0300 Subject: [PATCH] Fix registering --- client.go | 24 +++++++++++------------- requests.go | 30 ++++++++++++++++++++++++++++-- responses.go | 15 ++++++++------- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/client.go b/client.go index a5ff54e3..cb79854e 100644 --- a/client.go +++ b/client.go @@ -301,7 +301,9 @@ func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{ req.Header.Set("Content-Type", "application/json") } req.Header.Set("User-Agent", cli.UserAgent) - req.Header.Set("Authorization", "Bearer "+cli.AccessToken) + if len(cli.AccessToken) > 0 { + req.Header.Set("Authorization", "Bearer "+cli.AccessToken) + } cli.LogRequest(req, logBody) res, err := cli.Client.Do(req) if res != nil { @@ -448,19 +450,15 @@ func (cli *Client) RegisterDummy(req *ReqRegister) (*RespRegister, error) { res, uia, err := cli.Register(req) if err != nil && uia == nil { return nil, err + } else if uia == nil { + return nil, errors.New("server did not return user-interactive auth flows") + } else if !uia.HasSingleStageFlow(AuthTypeDummy) { + return nil, errors.New("server does not support m.login.dummy") } - if uia != nil && uia.HasSingleStageFlow("m.login.dummy") { - req.Auth = struct { - Type string `json:"type"` - Session string `json:"session,omitempty"` - }{"m.login.dummy", uia.Session} - res, _, err = cli.Register(req) - if err != nil { - return nil, err - } - } - if res == nil { - return nil, fmt.Errorf("registration failed: does this server support m.login.dummy? ") + req.Auth = BaseAuthData{Type: AuthTypeDummy, Session: uia.Session} + res, _, err = cli.Register(req) + if err != nil { + return nil, err } return res, nil } diff --git a/requests.go b/requests.go index 74d474d8..e36e2fe5 100644 --- a/requests.go +++ b/requests.go @@ -8,6 +8,27 @@ import ( "maunium.net/go/mautrix/pushrules" ) +type AuthType string + +const ( + AuthTypePassword = "m.login.password" + AuthTypeReCAPTCHA = "m.login.recaptcha" + AuthTypeOAuth2 = "m.login.oauth2" + AuthTypeSSO = "m.login.sso" + AuthTypeEmail = "m.login.email.identity" + AuthTypeMSISDN = "m.login.msisdn" + AuthTypeToken = "m.login.token" + AuthTypeDummy = "m.login.dummy" +) + +type IdentifierType string + +const ( + IdentifierTypeUser = "m.id.user" + IdentifierTypeThirdParty = "m.id.thirdparty" + IdentifierTypePhone = "m.id.phone" +) + // ReqRegister is the JSON request for http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-register type ReqRegister struct { Username string `json:"username,omitempty"` @@ -18,8 +39,13 @@ type ReqRegister struct { Auth interface{} `json:"auth,omitempty"` } +type BaseAuthData struct { + Type AuthType `json:"type"` + Session string `json:"session"` +} + type UserIdentifier struct { - Type string `json:"type"` + Type IdentifierType `json:"type"` User string `json:"user,omitempty"` @@ -32,7 +58,7 @@ type UserIdentifier struct { // ReqLogin is the JSON request for http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-login type ReqLogin struct { - Type string `json:"type"` + Type AuthType `json:"type"` Identifier UserIdentifier `json:"identifier"` Password string `json:"password,omitempty"` Token string `json:"token,omitempty"` diff --git a/responses.go b/responses.go index 6a4d18fc..dfd6694e 100644 --- a/responses.go +++ b/responses.go @@ -91,17 +91,18 @@ type RespMediaUpload struct { // RespUserInteractive is the JSON response for https://matrix.org/docs/spec/client_server/r0.2.0.html#user-interactive-authentication-api type RespUserInteractive struct { Flows []struct { - Stages []string `json:"stages"` + Stages []AuthType `json:"stages"` } `json:"flows"` - Params map[string]interface{} `json:"params"` - Session string `json:"string"` - Completed []string `json:"completed"` - ErrCode string `json:"errcode"` - Error string `json:"error"` + Params map[AuthType]interface{} `json:"params"` + Session string `json:"string"` + Completed []string `json:"completed"` + + ErrCode string `json:"errcode"` + Error string `json:"error"` } // HasSingleStageFlow returns true if there exists at least 1 Flow with a single stage of stageName. -func (r RespUserInteractive) HasSingleStageFlow(stageName string) bool { +func (r RespUserInteractive) HasSingleStageFlow(stageName AuthType) bool { for _, f := range r.Flows { if len(f.Stages) == 1 && f.Stages[0] == stageName { return true