Skip to content

Commit

Permalink
Fix the file permissions on the sqlite db.
Browse files Browse the repository at this point in the history
This ensures that the permissions on the file that SQLite is using are
correct (0600) i.e. user read/write.
  • Loading branch information
bigkevmcd committed Nov 1, 2024
1 parent 8f384ef commit c16b2c8
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 3 deletions.
22 changes: 22 additions & 0 deletions pkg/cache/sql/db/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"database/sql"
"encoding/gob"
"fmt"
"io/fs"
"os"
"reflect"
"sync"
Expand All @@ -22,6 +23,8 @@ import (
const (
// InformerObjectCacheDBPath is where SQLite's object database file will be stored relative to process running lasso
InformerObjectCacheDBPath = "informer_object_cache.db"

informerObjectCachePerms fs.FileMode = 0600
)

// Client is a database client that provides encrypting, decrypting, and database resetting.
Expand Down Expand Up @@ -104,6 +107,7 @@ func NewClient(c Connection, encryptor Encryptor, decryptor Decryptor) (*Client,
if err != nil {
return nil, err
}

return client, nil
}

Expand Down Expand Up @@ -320,6 +324,12 @@ func (c *Client) NewConnection() error {
return err
}

// Touch the file first which means that when SQLite opens it, it will
// retain the permissions.
if err := touchFile(InformerObjectCacheDBPath, informerObjectCachePerms); err != nil {
return nil
}

sqlDB, err := sql.Open("sqlite", "file:"+InformerObjectCacheDBPath+"?"+
// open SQLite file in read-write mode, creating it if it does not exist
"mode=rwc&"+
Expand All @@ -343,3 +353,15 @@ func (c *Client) NewConnection() error {
c.conn = sqlDB
return nil
}

// This acts like "touch" for non-existent files...setting the correct
// permissions.
func touchFile(filename string, perms fs.FileMode) error {
f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, perms)
if err != nil {
return err
}
defer f.Close()

return nil
}
36 changes: 33 additions & 3 deletions pkg/cache/sql/db/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"fmt"
"io/fs"
"math"
"os"
"reflect"
Expand Down Expand Up @@ -50,6 +51,7 @@ func TestNewClient(t *testing.T) {
t.Run(test.description, func(t *testing.T) { test.test(t) })
}
}

func TestQueryForRows(t *testing.T) {
type testCase struct {
description string
Expand Down Expand Up @@ -567,24 +569,36 @@ func TestNewConnection(t *testing.T) {
}

var tests []testCase
tests = append(tests, testCase{description: "Prepare() with no errors", test: func(t *testing.T) {
tests = append(tests, testCase{description: "NewConnection replaces file", test: func(t *testing.T) {
c := SetupMockConnection(t)
e := SetupMockEncryptor(t)
d := SetupMockDecryptor(t)

client := SetupClient(t, c, e, d)
sqlStmt := &sql.Stmt{}
c.EXPECT().Prepare("something").Return(sqlStmt, nil)
c.EXPECT().Close().Return(nil)

err := client.NewConnection()
assert.Nil(t, err)

// Create a transaction to ensure that the file is written to disk.
txC, err := client.BeginTx(context.Background(), false)
assert.NoError(t, err)
assert.NoError(t, txC.Commit())

assert.FileExists(t, InformerObjectCacheDBPath)
assertFileHasPermissions(t, InformerObjectCacheDBPath, 0600)

err = os.Remove(InformerObjectCacheDBPath)
if err != nil {
assert.Fail(t, "could not remove object cache path after test")
}
},
})

t.Parallel()
for _, test := range tests {
t.Run(test.description, func(t *testing.T) { test.test(t) })
}
}

func TestCommit(t *testing.T) {
Expand Down Expand Up @@ -619,3 +633,19 @@ func SetupClient(t *testing.T, connection Connection, encryptor Encryptor, decry
c, _ := NewClient(connection, encryptor, decryptor)
return c
}

func assertFileHasPermissions(t *testing.T, fname string, wantPerms fs.FileMode) bool {
t.Helper()
info, err := os.Lstat(fname)
if err != nil {
if os.IsNotExist(err) {
return assert.Fail(t, fmt.Sprintf("unable to find file %q", fname))
}
return assert.Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", fname, err))
}

// Stringifying the perms makes it easier to read than a Hex comparison.
assert.Equal(t, wantPerms.String(), info.Mode().Perm().String())

return true
}

0 comments on commit c16b2c8

Please sign in to comment.