Skip to content

Commit

Permalink
core/sessions: switch to sqlutil.DataSource (#12809)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmank88 authored Apr 16, 2024
1 parent 0121a52 commit 0af4aca
Show file tree
Hide file tree
Showing 37 changed files with 683 additions and 673 deletions.
5 changes: 5 additions & 0 deletions .changeset/sweet-sloths-laugh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

core/sessions: switch to sqlutil.DataSource #internal
18 changes: 1 addition & 17 deletions core/chains/evm/forwarders/orm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,10 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
)

type TestORM struct {
ORM
db sqlutil.DataSource
}

func setupORM(t *testing.T) *TestORM {
t.Helper()

var (
db = pgtest.NewSqlxDB(t)
orm = NewORM(db)
)

return &TestORM{ORM: orm, db: db}
}

// Tests the atomicity of cleanup function passed to DeleteForwarder, during DELETE operation
func Test_DeleteForwarder(t *testing.T) {
t.Parallel()
orm := setupORM(t)
orm := NewORM(pgtest.NewSqlxDB(t))
addr := testutils.NewAddress()
chainID := testutils.FixtureChainID
ctx := testutils.Context(t)
Expand Down
10 changes: 7 additions & 3 deletions core/cmd/admin_commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

"github.com/smartcontractkit/chainlink/v2/core/cmd"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/sessions"
"github.com/smartcontractkit/chainlink/v2/core/web/presenters"
)
Expand Down Expand Up @@ -60,10 +61,11 @@ func TestShell_CreateUser(t *testing.T) {
}

func TestShell_ChangeRole(t *testing.T) {
ctx := testutils.Context(t)
app := startNewApplicationV2(t, nil)
client, _ := app.NewShellAndRenderer()
user := cltest.MustRandomUser(t)
require.NoError(t, app.AuthenticationProvider().CreateUser(&user))
require.NoError(t, app.AuthenticationProvider().CreateUser(ctx, &user))

tests := []struct {
name string
Expand Down Expand Up @@ -99,10 +101,11 @@ func TestShell_ChangeRole(t *testing.T) {
}

func TestShell_DeleteUser(t *testing.T) {
ctx := testutils.Context(t)
app := startNewApplicationV2(t, nil)
client, _ := app.NewShellAndRenderer()
user := cltest.MustRandomUser(t)
require.NoError(t, app.BasicAdminUsersORM().CreateUser(&user))
require.NoError(t, app.BasicAdminUsersORM().CreateUser(ctx, &user))

tests := []struct {
name string
Expand Down Expand Up @@ -133,10 +136,11 @@ func TestShell_DeleteUser(t *testing.T) {
}

func TestShell_ListUsers(t *testing.T) {
ctx := testutils.Context(t)
app := startNewApplicationV2(t, nil)
client, _ := app.NewShellAndRenderer()
user := cltest.MustRandomUser(t)
require.NoError(t, app.AuthenticationProvider().CreateUser(&user))
require.NoError(t, app.AuthenticationProvider().CreateUser(ctx, &user))

set := flag.NewFlagSet("test", 0)
flagSetApplyFromAction(client.ListUsers, set, "")
Expand Down
18 changes: 9 additions & 9 deletions core/cmd/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ func (f *fileSessionRequestBuilder) Build(file string) (sessions.SessionRequest,
// needed to access the API. Does nothing if API user already exists.
type APIInitializer interface {
// Initialize creates a new local Admin user for API access, or does nothing if one exists.
Initialize(orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error)
Initialize(ctx context.Context, orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error)
}

type promptingAPIInitializer struct {
Expand All @@ -804,9 +804,9 @@ func NewPromptingAPIInitializer(prompter Prompter) APIInitializer {
}

// Initialize uses the terminal to get credentials that it then saves in the store.
func (t *promptingAPIInitializer) Initialize(orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error) {
func (t *promptingAPIInitializer) Initialize(ctx context.Context, orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error) {
// Load list of users to determine which to assume, or if a user needs to be created
dbUsers, err := orm.ListUsers()
dbUsers, err := orm.ListUsers(ctx)
if err != nil {
return sessions.User{}, errors.Wrap(err, "Unable to List users for initialization")
}
Expand All @@ -826,7 +826,7 @@ func (t *promptingAPIInitializer) Initialize(orm sessions.BasicAdminUsersORM, lg
lggr.Errorw("Error creating API user", "err", err2)
continue
}
if err = orm.CreateUser(&user); err != nil {
if err = orm.CreateUser(ctx, &user); err != nil {
lggr.Errorf("Error creating API user: ", err, "err")
}
return user, err
Expand All @@ -840,7 +840,7 @@ func (t *promptingAPIInitializer) Initialize(orm sessions.BasicAdminUsersORM, lg

// Otherwise, multiple admin users exist, prompt for which to use
email := t.prompter.Prompt("Enter email of API user account to assume: ")
user, err := orm.FindUser(email)
user, err := orm.FindUser(ctx, email)

if err != nil {
return sessions.User{}, err
Expand All @@ -858,14 +858,14 @@ func NewFileAPIInitializer(file string) APIInitializer {
return fileAPIInitializer{file: file}
}

func (f fileAPIInitializer) Initialize(orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error) {
func (f fileAPIInitializer) Initialize(ctx context.Context, orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error) {
request, err := credentialsFromFile(f.file, lggr)
if err != nil {
return sessions.User{}, err
}

// Load list of users to determine which to assume, or if a user needs to be created
dbUsers, err := orm.ListUsers()
dbUsers, err := orm.ListUsers(ctx)
if err != nil {
return sessions.User{}, errors.Wrap(err, "Unable to List users for initialization")
}
Expand All @@ -876,7 +876,7 @@ func (f fileAPIInitializer) Initialize(orm sessions.BasicAdminUsersORM, lggr log
if err2 != nil {
return user, errors.Wrap(err2, "failed to instantiate new user")
}
return user, orm.CreateUser(&user)
return user, orm.CreateUser(ctx, &user)
}

// Attempt to contextually return the correct admin user, CLI access here implies admin
Expand All @@ -885,7 +885,7 @@ func (f fileAPIInitializer) Initialize(orm sessions.BasicAdminUsersORM, lggr log
}

// Otherwise, multiple admin users exist, attempt to load email specified in session request
user, err := orm.FindUser(request.Email)
user, err := orm.FindUser(ctx, request.Email)
if err != nil {
return sessions.User{}, err
}
Expand Down
5 changes: 3 additions & 2 deletions core/cmd/shell_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ func (s *Shell) RunNode(c *cli.Context) error {
}

func (s *Shell) runNode(c *cli.Context) error {
ctx := s.ctx()
lggr := logger.Sugared(s.Logger.Named("RunNode"))

var pwd, vrfpwd *string
Expand Down Expand Up @@ -448,11 +449,11 @@ func (s *Shell) runNode(c *cli.Context) error {
}

var user sessions.User
if user, err = NewFileAPIInitializer(c.String("api")).Initialize(authProviderORM, lggr); err != nil {
if user, err = NewFileAPIInitializer(c.String("api")).Initialize(ctx, authProviderORM, lggr); err != nil {
if !errors.Is(err, ErrNoCredentialFile) {
return errors.Wrap(err, "error creating api initializer")
}
if user, err = s.FallbackAPIInitializer.Initialize(authProviderORM, lggr); err != nil {
if user, err = s.FallbackAPIInitializer.Initialize(ctx, authProviderORM, lggr); err != nil {
if errors.Is(err, ErrorNoAPICredentialsAvailable) {
return errors.WithStack(err)
}
Expand Down
4 changes: 2 additions & 2 deletions core/cmd/shell_local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func TestShell_RunNodeWithPasswords(t *testing.T) {
})
db := pgtest.NewSqlxDB(t)
keyStore := cltest.NewKeyStore(t, db, cfg.Database())
authProviderORM := localauth.NewORM(db, time.Minute, logger.TestLogger(t), cfg.Database(), audit.NoopLogger)
authProviderORM := localauth.NewORM(db, time.Minute, logger.TestLogger(t), audit.NoopLogger)

lggr := logger.TestLogger(t)

Expand Down Expand Up @@ -174,7 +174,7 @@ func TestShell_RunNodeWithAPICredentialsFile(t *testing.T) {
c.Insecure.OCRDevelopmentMode = nil
})
db := pgtest.NewSqlxDB(t)
authProviderORM := localauth.NewORM(db, time.Minute, logger.TestLogger(t), cfg.Database(), audit.NoopLogger)
authProviderORM := localauth.NewORM(db, time.Minute, logger.TestLogger(t), audit.NoopLogger)

// Clear out fixture users/users created from the other test cases
// This asserts that on initial run with an empty users table that the credentials file will instantiate and
Expand Down
6 changes: 4 additions & 2 deletions core/cmd/shell_remote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -646,11 +646,12 @@ func TestShell_RunOCRJob_JobNotFound(t *testing.T) {

func TestShell_AutoLogin(t *testing.T) {
t.Parallel()
ctx := testutils.Context(t)

app := startNewApplicationV2(t, nil)

user := cltest.MustRandomUser(t)
require.NoError(t, app.BasicAdminUsersORM().CreateUser(&user))
require.NoError(t, app.BasicAdminUsersORM().CreateUser(ctx, &user))

sr := sessions.SessionRequest{
Email: user.Email,
Expand All @@ -674,11 +675,12 @@ func TestShell_AutoLogin(t *testing.T) {

func TestShell_AutoLogin_AuthFails(t *testing.T) {
t.Parallel()
ctx := testutils.Context(t)

app := startNewApplicationV2(t, nil)

user := cltest.MustRandomUser(t)
require.NoError(t, app.BasicAdminUsersORM().CreateUser(&user))
require.NoError(t, app.BasicAdminUsersORM().CreateUser(ctx, &user))

sr := sessions.SessionRequest{
Email: user.Email,
Expand Down
28 changes: 15 additions & 13 deletions core/cmd/shell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,10 @@ func TestTerminalAPIInitializer_InitializeWithoutAPIUser(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
lggr := logger.TestLogger(t)
orm := localauth.NewORM(db, time.Minute, lggr, pgtest.NewQConfig(true), audit.NoopLogger)
orm := localauth.NewORM(db, time.Minute, lggr, audit.NoopLogger)

mock := &cltest.MockCountingPrompter{T: t, EnteredStrings: test.enteredStrings, NotTerminal: !test.isTerminal}
tai := cmd.NewPromptingAPIInitializer(mock)
Expand All @@ -174,14 +175,14 @@ func TestTerminalAPIInitializer_InitializeWithoutAPIUser(t *testing.T) {
// create/run with a new admin user
pgtest.MustExec(t, db, "DELETE FROM users;")

user, err := tai.Initialize(orm, lggr)
user, err := tai.Initialize(ctx, orm, lggr)
if test.isError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, len(test.enteredStrings), mock.Count)

persistedUser, err := orm.FindUser(email)
persistedUser, err := orm.FindUser(ctx, email)
assert.NoError(t, err)

assert.Equal(t, user.Email, persistedUser.Email)
Expand All @@ -192,10 +193,10 @@ func TestTerminalAPIInitializer_InitializeWithoutAPIUser(t *testing.T) {
}

func TestTerminalAPIInitializer_InitializeWithExistingAPIUser(t *testing.T) {
ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
cfg := configtest.NewGeneralConfig(t, nil)
lggr := logger.TestLogger(t)
orm := localauth.NewORM(db, time.Minute, lggr, cfg.Database(), audit.NoopLogger)
orm := localauth.NewORM(db, time.Minute, lggr, audit.NoopLogger)

// Clear out fixture users/users created from the other test cases
// This asserts that on initial run with an empty users table that the credentials file will instantiate and
Expand All @@ -204,13 +205,13 @@ func TestTerminalAPIInitializer_InitializeWithExistingAPIUser(t *testing.T) {
require.NoError(t, err)

initialUser := cltest.MustRandomUser(t)
require.NoError(t, orm.CreateUser(&initialUser))
require.NoError(t, orm.CreateUser(ctx, &initialUser))

mock := &cltest.MockCountingPrompter{T: t}
tai := cmd.NewPromptingAPIInitializer(mock)

// If there is an existing user, and we are in the Terminal prompt, no input prompts required
user, err := tai.Initialize(orm, lggr)
user, err := tai.Initialize(ctx, orm, lggr)
assert.NoError(t, err)
assert.Equal(t, 0, mock.Count)

Expand All @@ -230,23 +231,24 @@ func TestFileAPIInitializer_InitializeWithoutAPIUser(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctx := testutils.Context(t)
db := pgtest.NewSqlxDB(t)
lggr := logger.TestLogger(t)
orm := localauth.NewORM(db, time.Minute, lggr, pgtest.NewQConfig(true), audit.NoopLogger)
orm := localauth.NewORM(db, time.Minute, lggr, audit.NoopLogger)

// Clear out fixture users/users created from the other test cases
// This asserts that on initial run with an empty users table that the credentials file will instantiate and
// create/run with a new admin user
pgtest.MustExec(t, db, "DELETE FROM users;")

tfi := cmd.NewFileAPIInitializer(test.file)
user, err := tfi.Initialize(orm, lggr)
user, err := tfi.Initialize(ctx, orm, lggr)
if test.wantError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, cltest.APIEmailAdmin, user.Email)
persistedUser, err := orm.FindUser(user.Email)
persistedUser, err := orm.FindUser(ctx, user.Email)
assert.NoError(t, err)
assert.Equal(t, persistedUser.Email, user.Email)
}
Expand All @@ -256,8 +258,7 @@ func TestFileAPIInitializer_InitializeWithoutAPIUser(t *testing.T) {

func TestFileAPIInitializer_InitializeWithExistingAPIUser(t *testing.T) {
db := pgtest.NewSqlxDB(t)
cfg := configtest.NewGeneralConfig(t, nil)
orm := localauth.NewORM(db, time.Minute, logger.TestLogger(t), cfg.Database(), audit.NoopLogger)
orm := localauth.NewORM(db, time.Minute, logger.TestLogger(t), audit.NoopLogger)

tests := []struct {
name string
Expand All @@ -270,9 +271,10 @@ func TestFileAPIInitializer_InitializeWithExistingAPIUser(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctx := testutils.Context(t)
lggr := logger.TestLogger(t)
tfi := cmd.NewFileAPIInitializer(test.file)
user, err := tfi.Initialize(orm, lggr)
user, err := tfi.Initialize(ctx, orm, lggr)
if test.wantError {
assert.Error(t, err)
} else {
Expand Down
3 changes: 2 additions & 1 deletion core/internal/cltest/cltest.go
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,7 @@ type User struct {

func (ta *TestApplication) NewHTTPClient(user *User) HTTPClientCleaner {
ta.t.Helper()
ctx := testutils.Context(ta.t)

if user == nil {
user = &User{}
Expand All @@ -604,7 +605,7 @@ func (ta *TestApplication) NewHTTPClient(user *User) HTTPClientCleaner {
u, err := clsessions.NewUser(user.Email, Password, user.Role)
require.NoError(ta.t, err)

err = ta.BasicAdminUsersORM().CreateUser(&u)
err = ta.BasicAdminUsersORM().CreateUser(ctx, &u)
require.NoError(ta.t, err)

sessionID := ta.MustSeedNewSession(user.Email)
Expand Down
12 changes: 7 additions & 5 deletions core/internal/cltest/mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"time"

"github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"

"github.com/jmoiron/sqlx"

Expand Down Expand Up @@ -312,10 +313,11 @@ func MustRandomUser(t testing.TB) sessions.User {
}

func NewUserWithSession(t testing.TB, orm sessions.AuthenticationProvider) sessions.User {
ctx := testutils.Context(t)
u := MustRandomUser(t)
require.NoError(t, orm.CreateUser(&u))
require.NoError(t, orm.CreateUser(ctx, &u))

_, err := orm.CreateSession(sessions.SessionRequest{
_, err := orm.CreateSession(ctx, sessions.SessionRequest{
Email: u.Email,
Password: Password,
})
Expand All @@ -332,13 +334,13 @@ func NewMockAPIInitializer(t testing.TB) *MockAPIInitializer {
return &MockAPIInitializer{t: t}
}

func (m *MockAPIInitializer) Initialize(orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error) {
if user, err := orm.FindUser(APIEmailAdmin); err == nil {
func (m *MockAPIInitializer) Initialize(ctx context.Context, orm sessions.BasicAdminUsersORM, lggr logger.Logger) (sessions.User, error) {
if user, err := orm.FindUser(ctx, APIEmailAdmin); err == nil {
return user, err
}
m.Count++
user := MustRandomUser(m.t)
return user, orm.CreateUser(&user)
return user, orm.CreateUser(ctx, &user)
}

func NewMockAuthenticatedHTTPClient(lggr logger.Logger, cfg cmd.ClientOpts, sessionID string) cmd.HTTPClient {
Expand Down
Loading

0 comments on commit 0af4aca

Please sign in to comment.