add last updated tracking for secrets
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2024-01-16 16:21:41 +11:00
parent 498dd9a8c3
commit b278a3c7d8
3 changed files with 48 additions and 23 deletions

View File

@@ -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) {

View File

@@ -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

View File

@@ -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")