diff --git a/management/management.go b/management/management.go index 9fe8f2c0..37b50136 100644 --- a/management/management.go +++ b/management/management.go @@ -306,6 +306,35 @@ func (m *Management) Request(method, uri string, v interface{}, options ...Reque return nil } +// RequestWithCustomResponse replicates the behaviour of Request but allows to decode +// the response into a different type than the one on the request. +func (m *Management) RequestWithCustomResponse(method, uri string, payload interface{}, resp interface{}, options ...RequestOption) error { + + req, err := m.NewRequest(method, uri, payload, options...) + if err != nil { + return err + } + + res, err := m.Do(req) + if err != nil { + return err + } + + if res.StatusCode < http.StatusOK || res.StatusCode >= http.StatusBadRequest { + return newError(res.Body) + } + + if res.StatusCode != http.StatusNoContent && res.StatusCode != http.StatusAccepted { + err := json.NewDecoder(res.Body).Decode(res) + if err != nil { + return err + } + return res.Body.Close() + } + + return nil +} + // Error is an interface describing any error which could be returned by the // Auth0 Management API. type Error interface { diff --git a/management/user.go b/management/user.go index 0281ed16..ab0b14b0 100644 --- a/management/user.go +++ b/management/user.go @@ -93,6 +93,16 @@ type User struct { LoginsCount *int64 `json:"logins_count,omitempty"` } +// UserIdentityLink contains the data needed for linking an identity to a given user. +type UserIdentityLink struct { + // Connection id of the secondary user account being linked when more than one auth0 database provider exists. + ConnectionID *string `json:"connection_id,omitempty"` + // Secondary account user id. + UserID string `json:"user_id"` + // Identity provider of the secondary user account being linked. + Provider string `json:"provider"` +} + type UserIdentity struct { Connection *string `json:"connection,omitempty"` UserID *string `json:"-"` @@ -347,15 +357,6 @@ func (m *UserManager) Unblock(id string, opts ...RequestOption) error { // Link links two user accounts together forming a primary and secondary relationship. // // See: https://auth0.com/docs/api/management/v2#!/Users/post_identities -func (m *UserManager) Link(id string, il *IdentityLink, opts ...RequestOption) (err error) { - return m.Request("POST", m.URI("users", id, "identities"), il, opts...) -} - -// IdentityLink contains the data needed for linking an identity to a given user. -// -// Note: connection_id param is needed just to identify a particular database connection for the 'auth0' provider. -type IdentityLink struct { - ConnectionID *string `json:"connection_id,omitempty"` - UserID string `json:"user_id"` - Provider string `json:"provider"` +func (m *UserManager) Link(id string, il *UserIdentityLink, opts ...RequestOption) (resp []UserIdentity, err error) { + return m.RequestWithCustomResponse("POST", m.URI("users", id, "identities"), il, &resp, opts...) } diff --git a/management/user_test.go b/management/user_test.go index c6fa1c25..883ad050 100644 --- a/management/user_test.go +++ b/management/user_test.go @@ -211,7 +211,7 @@ func TestUser(t *testing.T) { { Email: auth0.String("alice@example.com"), Username: auth0.String("alice"), - Password: auth0.String("5301111b-b31b-47c4-bf3d-0c26ea57bdf4"), + Password: auth0.String("72aae3e7-1b9b-4ff4-8806-c4b0ce0ca424"), Connection: auth0.String("Username-Password-Authentication"), }, { @@ -235,7 +235,7 @@ func TestUser(t *testing.T) { } defer func() { for _, user := range allUsers { - m.User.Delete(auth0.StringValue(user.ID)) + m.User.Delete(user.GetID()) } }() @@ -262,34 +262,48 @@ func TestUser(t *testing.T) { }) t.Run("Link", func(t *testing.T) { - ulAlice, err := m.User.Search(Query(`email:"alice@example.com"`)) + cs, err := m.Connection.ReadByName("Username-Password-Authentication") if err != nil { t.Error(err) } - if len(ulAlice.Users) != 1 { - t.Error("unexpected number of users found") + + bruceWayne := &User{ + Email: auth0.String("bruce@wayne.com"), + Username: auth0.String("rich_boy"), + Password: auth0.String("72aae3e7-1b9b-4ff4-8806-c4b0ce0ca424"), + Connection: cs.Name, } - ulBob, err := m.User.Search(Query(`email:"bob@example.com"`)) + err := m.User.Create(bruceWayne) if err != nil { t.Error(err) } - if len(ulBob.Users) != 1 { - t.Error("unexpected number of users found") - } - cs, err := m.Connection.ReadByName("Username-Password-Authentication") + batman := &User{ + Email: auth0.String("batman@example.com"), + Username: auth0.String("dark_boy"), + Password: auth0.String("3665df77-7ebe-4448-84cb-cd7238f680e9"), + Connection: cs.Name, + } + err := m.User.Create(batman) if err != nil { t.Error(err) } // Make Bob to be a secondary identity of Alice - if err := m.User.Link(ulAlice.Users[0].GetID(), &IdentityLink{ + bruceIdentities, err := m.User.Link(bruceWayne.GetID(), &UserIdentityLink{ Provider: "auth0", - UserID: ulBob.Users[0].GetID(), + UserID: batman.GetID(), ConnectionID: cs.ID, - }); err != nil { + }) + if err != nil { t.Error(err) } + t.Logf("%v\n", bruceIdentities) + + t.Cleanup(func() { + m.User.Delete(bruceWayne.GetID()) + m.User.Delete(batman.GetID()) + }) }) }