From b278a3c7d89d7f28378fa1979de47df1838439cb Mon Sep 17 00:00:00 2001 From: Nathan Coad Date: Tue, 16 Jan 2024 16:21:41 +1100 Subject: [PATCH] add last updated tracking for secrets --- controllers/retrieveSecrets.go | 14 ++++++----- models/secret.go | 46 +++++++++++++++++++++------------- models/setup.go | 11 ++++++++ 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/controllers/retrieveSecrets.go b/controllers/retrieveSecrets.go index 6f5f7ed..546ce0a 100644 --- a/controllers/retrieveSecrets.go +++ b/controllers/retrieveSecrets.go @@ -5,6 +5,7 @@ import ( "log" "net/http" "smt/models" + "time" "github.com/gin-gonic/gin" ) @@ -19,12 +20,13 @@ type RetrieveInput struct { } type ListSecret struct { - SecretId int `db:"SecretId" json:"secretId"` - SafeId int `db:"SafeId" json:"safeId"` - DeviceName string `db:"DeviceName" json:"deviceName"` - DeviceCategory string `db:"DeviceCategory" json:"deviceCategory"` - UserName string `db:"UserName" json:"userName"` - Secret string `db:"Secret" json:"-"` + SecretId int `db:"SecretId" json:"secretId"` + SafeId int `db:"SafeId" json:"safeId"` + DeviceName string `db:"DeviceName" json:"deviceName"` + DeviceCategory string `db:"DeviceCategory" json:"deviceCategory"` + UserName string `db:"UserName" json:"userName"` + Secret string `db:"Secret" json:"-"` + LastUpdated time.Time `db:"LastUpdated" json:"lastUpdated"` } func RetrieveSecret(c *gin.Context) { diff --git a/models/secret.go b/models/secret.go index 2dfa697..866a9cb 100644 --- a/models/secret.go +++ b/models/secret.go @@ -11,28 +11,31 @@ import ( "log" "smt/utils" "strings" + "time" ) const nonceSize = 12 // We use the json:"-" field tag to prevent showing these details to the user type Secret struct { - SecretId int `db:"SecretId" json:"secretId"` - SafeId int `db:"SafeId" json:"safeId"` - DeviceName string `db:"DeviceName" json:"deviceName"` - DeviceCategory string `db:"DeviceCategory" json:"deviceCategory"` - UserName string `db:"UserName" json:"userName"` - Secret string `db:"Secret" json:"secret"` + SecretId int `db:"SecretId" json:"secretId"` + SafeId int `db:"SafeId" json:"safeId"` + DeviceName string `db:"DeviceName" json:"deviceName"` + DeviceCategory string `db:"DeviceCategory" json:"deviceCategory"` + UserName string `db:"UserName" json:"userName"` + Secret string `db:"Secret" json:"secret"` + LastUpdated time.Time `db:"LastUpdated" json:"lastUpdated"` } // SecretRestricted is for when we want to output a Secret but not the protected information type SecretRestricted struct { - SecretId int `db:"SecretId" json:"secretId"` - SafeId int `db:"SafeId" json:"safeId"` - DeviceName string `db:"DeviceName" json:"deviceName"` - DeviceCategory string `db:"DeviceCategory" json:"deviceCategory"` - UserName string `db:"UserName" json:"userName"` - Secret string `db:"Secret" json:"-"` + SecretId int `db:"SecretId" json:"secretId"` + SafeId int `db:"SafeId" json:"safeId"` + DeviceName string `db:"DeviceName" json:"deviceName"` + DeviceCategory string `db:"DeviceCategory" json:"deviceCategory"` + UserName string `db:"UserName" json:"userName"` + Secret string `db:"Secret" json:"-"` + LastUpdated time.Time `db:"LastUpdated" json:"lastUpdated"` } // Used for querying all secrets the user has access to @@ -51,11 +54,15 @@ func (s Secret) GetId() int { } func (s *Secret) SaveSecret() (*Secret, error) { - var err error + // Populate timestamp field if not already set + if s.LastUpdated.IsZero() { + s.LastUpdated = time.Now().UTC() + } + log.Printf("SaveSecret storing values '%v'\n", s) - result, err := db.NamedExec((`INSERT INTO secrets (SafeId, DeviceName, DeviceCategory, UserName, Secret) VALUES (:SafeId, :DeviceName, :DeviceCategory, :UserName, :Secret)`), s) + result, err := db.NamedExec((`INSERT INTO secrets (SafeId, DeviceName, DeviceCategory, UserName, Secret, LastUpdated) VALUES (:SafeId, :DeviceName, :DeviceCategory, :UserName, :Secret, :LastUpdated)`), s) if err != nil { log.Printf("StoreSecret error executing sql record : '%s'\n", err) @@ -79,7 +86,7 @@ func SecretsGetAllowed(s *Secret, userId int) ([]UserSecret, error) { queryArgs := []interface{}{} query := ` SELECT users.UserId AS UserUserId, permissions.*, - secrets.SecretId, secrets.SafeId, secrets.DeviceName, secrets.DeviceCategory, secrets.UserName + secrets.SecretId, secrets.SafeId, secrets.DeviceName, secrets.DeviceCategory, secrets.UserName, secrets.LastUpdated FROM users INNER JOIN groups ON users.GroupId = groups.GroupId INNER JOIN permissions ON groups.GroupId = permissions.GroupId @@ -112,7 +119,7 @@ func SecretsGetAllowed(s *Secret, userId int) ([]UserSecret, error) { query += ` UNION SELECT users.UserId AS UserUserId, permissions.*, - secrets.SecretId, secrets.SafeId, secrets.DeviceName, secrets.DeviceCategory, secrets.UserName + secrets.SecretId, secrets.SafeId, secrets.DeviceName, secrets.DeviceCategory, secrets.UserName, secrets.LastUpdated FROM users INNER JOIN permissions ON users.UserId = permissions.UserId INNER JOIN safes on permissions.SafeId = safes.SafeId @@ -256,6 +263,11 @@ func (s *Secret) UpdateSecret() (*Secret, error) { var err error + // Populate timestamp field if not already set + if s.LastUpdated.IsZero() { + s.LastUpdated = time.Now().UTC() + } + log.Printf("UpdateSecret storing values '%v'\n", s) if s.SecretId == 0 { @@ -264,7 +276,7 @@ func (s *Secret) UpdateSecret() (*Secret, error) { return s, err } - result, err := db.NamedExec((`UPDATE secrets SET DeviceName = :DeviceName, DeviceCategory = :DeviceCategory, UserName = :UserName, Secret = :Secret WHERE SecretId = :SecretId`), s) + result, err := db.NamedExec((`UPDATE secrets SET DeviceName = :DeviceName, DeviceCategory = :DeviceCategory, UserName = :UserName, Secret = :Secret, LastUpdated = :LastUpdated WHERE SecretId = :SecretId`), s) if err != nil { log.Printf("UpdateSecret error executing sql record : '%s'\n", err) return &Secret{}, err diff --git a/models/setup.go b/models/setup.go index 7354ce9..880566b 100644 --- a/models/setup.go +++ b/models/setup.go @@ -68,6 +68,7 @@ const createSecrets string = ` DeviceCategory VARCHAR, UserName VARCHAR, Secret VARCHAR, + LastUpdated datetime, FOREIGN KEY (SafeId) REFERENCES safes(SafeId) ); ` @@ -380,6 +381,16 @@ func CreateTables() { } } + secretsLastUpdatedCheck, _ := CheckColumnExists("secrets", "LastUpdated") + if !secretsLastUpdatedCheck { + // Add the column for LastUpdated in the secrets table + _, err := db.Exec("ALTER TABLE secrets ADD COLUMN LastUpdated datetime;") + if err != nil { + log.Printf("Error altering secrets table to add LastUpdated column : '%s'\n", err) + os.Exit(1) + } + } + /* // Database updates added after initial version released ldapCheck, _ := CheckColumnExists("roles", "LdapGroup")