diff --git a/app/models/account.go b/app/models/account.go index 3e9f012f9..4f689377f 100644 --- a/app/models/account.go +++ b/app/models/account.go @@ -44,13 +44,21 @@ func (a Account) MarshalJSON() ([]byte, error) { formattedPasswordChangedAt = a.PasswordChangedAt.Format(time.RFC3339) } - return json.Marshal(map[string]interface{}{ - "id": a.ID, - "username": a.Username, - "oauth_accounts": a.OauthAccounts, - "last_login_at": formattedLastLogin, - "password_changed_at": formattedPasswordChangedAt, - "locked": a.Locked, - "deleted": a.DeletedAt != nil, + return json.Marshal(struct { + ID int `json:"id"` + Username string `json:"username"` + OauthAccounts []*OauthAccount `json:"oauth_accounts"` + LastLoginAt string `json:"last_login_at"` + PasswordChangedAt string `json:"password_changed_at"` + Locked bool `json:"locked"` + Deleted bool `json:"deleted"` + }{ + ID: a.ID, + Username: a.Username, + OauthAccounts: a.OauthAccounts, + LastLoginAt: formattedLastLogin, + PasswordChangedAt: formattedPasswordChangedAt, + Locked: a.Locked, + Deleted: a.DeletedAt != nil, }) } diff --git a/app/models/oauth_account.go b/app/models/oauth_account.go index 6b4a03ff1..1c366c640 100644 --- a/app/models/oauth_account.go +++ b/app/models/oauth_account.go @@ -17,9 +17,13 @@ type OauthAccount struct { } func (o OauthAccount) MarshalJSON() ([]byte, error) { - return json.Marshal(map[string]interface{}{ - "provider": o.Provider, - "provider_account_id": o.ProviderID, - "email": o.Email, + return json.Marshal(struct { + Provider string `json:"provider"` + ProviderID string `json:"provider_account_id"` + Email string `json:"email"` + }{ + Provider: o.Provider, + ProviderID: o.ProviderID, + Email: o.Email, }) } diff --git a/app/services/account_getter_test.go b/app/services/account_getter_test.go index e9e9438ac..5938e0507 100644 --- a/app/services/account_getter_test.go +++ b/app/services/account_getter_test.go @@ -10,6 +10,15 @@ import ( ) func TestAccountGetter(t *testing.T) { + + t.Run("get non existing account", func(t *testing.T) { + accountStore := mock.NewAccountStore() + account, err := services.AccountGetter(accountStore, 9999) + + require.NotNil(t, err) + require.Nil(t, account) + }) + t.Run("returns empty map when no oauth accounts", func(t *testing.T) { accountStore := mock.NewAccountStore() acc, err := accountStore.Create("user@keratin.tech", []byte("password")) diff --git a/app/services/account_oauth_ender.go b/app/services/account_identity_remover.go similarity index 100% rename from app/services/account_oauth_ender.go rename to app/services/account_identity_remover.go diff --git a/app/services/identity_reconciler.go b/app/services/identity_reconciler.go index 160b09f19..8aa457a69 100644 --- a/app/services/identity_reconciler.go +++ b/app/services/identity_reconciler.go @@ -97,10 +97,10 @@ func updateUserInfo(accountStore data.AccountStore, accountID int, providerName continue } - if oAccount.Email == "" { + if oAccount.Email != providerUser.Email { _, err = accountStore.UpdateOauthAccount(accountID, oAccount.Provider, providerUser.Email) if err != nil { - return errors.Wrap(err, "UpdateOauthAccountEmail") + return errors.Wrap(err, "UpdateOauthAccount") } } } diff --git a/app/services/identity_reconciler_test.go b/app/services/identity_reconciler_test.go index 6fe989b33..0b35e9377 100644 --- a/app/services/identity_reconciler_test.go +++ b/app/services/identity_reconciler_test.go @@ -104,4 +104,25 @@ func TestIdentityReconciler(t *testing.T) { assert.Equal(t, 1, len(oAccounts)) assert.Equal(t, email, oAccounts[0].Email) }) + + t.Run("update oauth email when is outdated", func(t *testing.T) { + provider := "testProvider" + providerAccountId := "777" + email := "update-outdate-oauth-email@test.com" + + account, err := store.Create(email, []byte("password")) + require.NoError(t, err) + + err = store.AddOauthAccount(account.ID, provider, providerAccountId, "email@email.com", "TOKEN") + require.NoError(t, err) + + found, err := services.IdentityReconciler(store, cfg, provider, &oauth.UserInfo{ID: providerAccountId, Email: email}, &oauth2.Token{}, 0) + assert.NoError(t, err) + assert.NotNil(t, found) + + oAccounts, err := store.GetOauthAccounts(account.ID) + assert.NoError(t, err) + assert.Equal(t, 1, len(oAccounts)) + assert.Equal(t, email, oAccounts[0].Email) + }) } diff --git a/server/handlers/get_oauth_accounts_test.go b/server/handlers/get_oauth_accounts_test.go index 5530e11ac..b777a32af 100644 --- a/server/handlers/get_oauth_accounts_test.go +++ b/server/handlers/get_oauth_accounts_test.go @@ -1,6 +1,7 @@ package handlers_test import ( + "encoding/json" "net/http" "testing" @@ -29,7 +30,14 @@ func TestGetOauthInfo(t *testing.T) { }) t.Run("success", func(t *testing.T) { - expected := "{\"result\":[{\"email\":\"email\",\"provider\":\"test\",\"provider_account_id\":\"ID\"}]}" + var expected struct { + Result []struct { + Email string `json:"email"` + Provider string `json:"provider"` + ProviderAccountID string `json:"provider_account_id"` + } + } + account, err := app.AccountStore.Create("get-oauth-info@keratin.tech", []byte("password")) require.NoError(t, err) @@ -42,6 +50,12 @@ func TestGetOauthInfo(t *testing.T) { require.NoError(t, err) require.Equal(t, http.StatusOK, res.StatusCode) - require.Equal(t, []byte(expected), test.ReadBody(res)) + + json.Unmarshal(test.ReadBody(res), &expected) + + require.Equal(t, len(expected.Result), 1) + require.Equal(t, expected.Result[0].Email, "email") + require.Equal(t, expected.Result[0].Provider, "test") + require.Equal(t, expected.Result[0].ProviderAccountID, "ID") }) }