mirror of https://github.com/matrix-org/gomatrix
Merge pull request #4 from matrix-org/kegan/registration
Add Register functions
This commit is contained in:
commit
8db775656f
89
client.go
89
client.go
|
@ -75,7 +75,9 @@ func (cli *Client) BuildBaseURL(urlPath ...string) string {
|
||||||
parts = append(parts, urlPath...)
|
parts = append(parts, urlPath...)
|
||||||
hsURL.Path = path.Join(parts...)
|
hsURL.Path = path.Join(parts...)
|
||||||
query := hsURL.Query()
|
query := hsURL.Query()
|
||||||
|
if cli.AccessToken != "" {
|
||||||
query.Set("access_token", cli.AccessToken)
|
query.Set("access_token", cli.AccessToken)
|
||||||
|
}
|
||||||
hsURL.RawQuery = query.Encode()
|
hsURL.RawQuery = query.Encode()
|
||||||
return hsURL.String()
|
return hsURL.String()
|
||||||
}
|
}
|
||||||
|
@ -162,9 +164,9 @@ func (cli *Client) StopSync() {
|
||||||
// MakeRequest makes a JSON HTTP request to the given URL.
|
// MakeRequest makes a JSON HTTP request to the given URL.
|
||||||
// If "resBody" is not nil, the response body will be json.Unmarshalled into it.
|
// If "resBody" is not nil, the response body will be json.Unmarshalled into it.
|
||||||
//
|
//
|
||||||
// Returns the HTTP body as bytes on 2xx. Returns an error if the response is not 2xx. This error
|
// Returns the HTTP body as bytes on 2xx with a nil error. Returns an error if the response is not 2xx along
|
||||||
// is an HTTPError which includes the returned HTTP status code and possibly a RespError as the
|
// with the HTTP body bytes if it got that far. This error is an HTTPError which includes the returned
|
||||||
// WrappedError, if the HTTP body could be decoded as a RespError.
|
// HTTP status code and possibly a RespError as the WrappedError, if the HTTP body could be decoded as a RespError.
|
||||||
func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{}, resBody interface{}) ([]byte, error) {
|
func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{}, resBody interface{}) ([]byte, error) {
|
||||||
var req *http.Request
|
var req *http.Request
|
||||||
var err error
|
var err error
|
||||||
|
@ -205,7 +207,7 @@ func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{
|
||||||
msg = msg + ": " + string(contents)
|
msg = msg + ": " + string(contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, HTTPError{
|
return contents, HTTPError{
|
||||||
Code: res.StatusCode,
|
Code: res.StatusCode,
|
||||||
Message: msg,
|
Message: msg,
|
||||||
WrappedError: wrap,
|
WrappedError: wrap,
|
||||||
|
@ -253,6 +255,85 @@ func (cli *Client) SyncRequest(timeout int, since, filterID string, fullState bo
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cli *Client) register(u string, req *ReqRegister) (resp *RespRegister, uiaResp *RespUserInteractive, err error) {
|
||||||
|
var bodyBytes []byte
|
||||||
|
bodyBytes, err = cli.MakeRequest("POST", u, req, nil)
|
||||||
|
if err != nil {
|
||||||
|
httpErr, ok := err.(HTTPError)
|
||||||
|
if !ok { // network error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if httpErr.Code == 401 {
|
||||||
|
// body should be RespUserInteractive, if it isn't, fail with the error
|
||||||
|
err = json.Unmarshal(bodyBytes, &uiaResp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// body should be RespRegister
|
||||||
|
err = json.Unmarshal(bodyBytes, &resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register makes an HTTP request according to http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-register
|
||||||
|
//
|
||||||
|
// Registers with kind=user. For kind=guest, see RegisterGuest.
|
||||||
|
func (cli *Client) Register(req *ReqRegister) (*RespRegister, *RespUserInteractive, error) {
|
||||||
|
u := cli.BuildURL("register")
|
||||||
|
return cli.register(u, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterGuest makes an HTTP request according to http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-register
|
||||||
|
// with kind=guest.
|
||||||
|
//
|
||||||
|
// For kind=user, see Register.
|
||||||
|
func (cli *Client) RegisterGuest(req *ReqRegister) (*RespRegister, *RespUserInteractive, error) {
|
||||||
|
query := map[string]string{
|
||||||
|
"kind": "guest",
|
||||||
|
}
|
||||||
|
u := cli.BuildURLWithQuery([]string{"register"}, query)
|
||||||
|
return cli.register(u, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterDummy performs m.login.dummy registration according to https://matrix.org/docs/spec/client_server/r0.2.0.html#dummy-auth
|
||||||
|
//
|
||||||
|
// Only a username and password need to be provided on the ReqRegister struct. Most local/developer homeservers will allow registration
|
||||||
|
// this way. If the homeserver does not, an error is returned. If "setOnClient" is true, the access_token and user_id will be set on
|
||||||
|
// this client instance.
|
||||||
|
//
|
||||||
|
// res, err := cli.RegisterDummy(&gomatrix.ReqRegister{
|
||||||
|
// Username: "alice",
|
||||||
|
// Password: "wonderland",
|
||||||
|
// }, false)
|
||||||
|
// if err != nil {
|
||||||
|
// panic(err)
|
||||||
|
// }
|
||||||
|
// token := res.AccessToken
|
||||||
|
func (cli *Client) RegisterDummy(req *ReqRegister, setOnClient bool) (*RespRegister, error) {
|
||||||
|
res, uia, err := cli.Register(req)
|
||||||
|
if err != nil && uia == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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?")
|
||||||
|
}
|
||||||
|
if setOnClient {
|
||||||
|
cli.UserID = res.UserID
|
||||||
|
cli.AccessToken = res.AccessToken
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
// JoinRoom joins the client to a room ID or alias. See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-join-roomidoralias
|
// JoinRoom joins the client to a room ID or alias. See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-join-roomidoralias
|
||||||
//
|
//
|
||||||
// If serverName is specified, this will be added as a query param to instruct the homeserver to join via that server. If content is specified, it will
|
// If serverName is specified, this will be added as a query param to instruct the homeserver to join via that server. If content is specified, it will
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package gomatrix
|
||||||
|
|
||||||
|
// 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"`
|
||||||
|
BindEmail bool `json:"bind_email,omitempty"`
|
||||||
|
Password string `json:"password,omitempty"`
|
||||||
|
DeviceID string `json:"device_id,omitempty"`
|
||||||
|
InitialDeviceDisplayName string `json:"initial_device_display_name"`
|
||||||
|
Auth interface{} `json:"auth,omitempty"`
|
||||||
|
}
|
31
responses.go
31
responses.go
|
@ -35,6 +35,37 @@ type RespMediaUpload struct {
|
||||||
ContentURI string `json:"content_uri"`
|
ContentURI string `json:"content_uri"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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"`
|
||||||
|
} `json:"flows"`
|
||||||
|
Params map[string]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 {
|
||||||
|
for _, f := range r.Flows {
|
||||||
|
if len(f.Stages) == 1 && f.Stages[0] == stageName {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// RespRegister is the JSON response for http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-register
|
||||||
|
type RespRegister struct {
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
DeviceID string `json:"device_id"`
|
||||||
|
HomeServer string `json:"home_server"`
|
||||||
|
RefreshToken string `json:"refresh_token"`
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
}
|
||||||
|
|
||||||
// RespSync is the JSON response for http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-sync
|
// RespSync is the JSON response for http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-sync
|
||||||
type RespSync struct {
|
type RespSync struct {
|
||||||
NextBatch string `json:"next_batch"`
|
NextBatch string `json:"next_batch"`
|
||||||
|
|
Loading…
Reference in New Issue