implement delete secret
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2024-01-09 15:08:11 +11:00
parent 90da2367be
commit 6423d83949
2 changed files with 94 additions and 53 deletions

View File

@@ -293,9 +293,6 @@ func UpdateSecret(c *gin.Context) {
}
if len(secretList) == 0 {
// TODO - also check secrets allowed for user
c.JSON(http.StatusBadRequest, gin.H{"error": "no secret matching search parameters"})
return
} else if len(secretList) == 1 {
@@ -339,42 +336,28 @@ func UpdateSecret(c *gin.Context) {
func DeleteSecret(c *gin.Context) {
var err error
var input SecretInput
var UserId int
var user_id int
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid JSON received : " + err.Error()})
c.JSON(http.StatusBadRequest, gin.H{"error": "DeleteSecret error binding to input JSON : " + err.Error()})
return
}
// Input validation
if input.DeviceCategory == "" && input.DeviceName == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "cannot store secret with empty deviceName and empty deviceCategory"})
return
}
log.Printf("DeleteSecret received JSON input '%v'\n", input)
/*
if input.SafeId == 0 && len(input.SafeName) == 0 {
errString := "StoreSecret no safe specified\n"
if len(input.SecretValue) == 0 {
errString := "DeleteSecret no updated secret specified\n"
log.Print(errString)
c.JSON(http.StatusBadRequest, gin.H{"error": errString})
return
}
*/
// Don't log this since it contains plaintext secrets
//log.Printf("StoreSecret received JSON input '%v'\n", input)
// Populate fields
s := models.Secret{}
s.UserName = input.UserName
s.DeviceName = input.DeviceName
s.DeviceCategory = input.DeviceCategory
// Query which safes the current user is allowed to access
// Temporarily disable because we should be able to figure it out without user specifying
/*
user_id, err := token.ExtractTokenID(c)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "error determining user"})
if input.SafeId == 0 && len(input.SafeName) == 0 {
errString := "UpdateSecret no safe specified\n"
log.Print(errString)
c.JSON(http.StatusBadRequest, gin.H{"error": errString})
return
}
*/
@@ -384,32 +367,58 @@ func DeleteSecret(c *gin.Context) {
c.JSON(http.StatusBadRequest, gin.H{"error": "error determining user"})
return
} else {
UserId = val.(int)
user_id = val.(int)
//log.Printf("user_id: %v\n", user_id)
}
safeId, err := FindSafeId(UserId, input)
// Populate fields
s := models.Secret{}
s.UserName = input.UserName
s.DeviceName = input.DeviceName
s.DeviceCategory = input.DeviceCategory
secretList, err := models.SecretsGetAllowed(&s, user_id)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
errString := fmt.Sprintf("error getting allowed secrets : '%s'", err)
log.Printf("DeleteSecret %s\n", errString)
c.JSON(http.StatusBadRequest, gin.H{"error": errString})
return
}
s.SafeId = safeId
// If this secret already exists in the database then generate an error
checkExists, err := models.GetSecrets(&s, false)
if len(secretList) == 0 {
errString := "no secret matching search parameters"
log.Printf("DeleteSecret %s\n", errString)
c.JSON(http.StatusBadRequest, gin.H{"error": errString})
return
} else if len(secretList) == 1 {
// Delete secret
log.Printf("secretList[0]: %v\n", secretList[0])
s.SecretId = secretList[0].SecretId
// check for empty fields in the update request and update from the existing record
if s.UserName == "" {
s.UserName = secretList[0].Secret.UserName
}
if s.DeviceCategory == "" {
s.DeviceCategory = secretList[0].DeviceCategory
}
if s.DeviceName == "" {
s.DeviceName = secretList[0].DeviceName
}
_, err = s.DeleteSecret()
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
c.JSON(http.StatusBadRequest, gin.H{"error": "DeleteSecret error deleting secret : " + err.Error()})
return
}
if len(checkExists) == 0 {
c.JSON(http.StatusBadRequest, gin.H{"error": "no secrets matched search parameters"})
return
} else if len(checkExists) == 1 {
c.JSON(http.StatusOK, gin.H{"message": "mock secret deleted successfully"})
// TODO delete secret
c.JSON(http.StatusOK, gin.H{"message": "secret deleted successfully"})
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": "multiple secrets matched search parameters, be more specific"})
errString := "multiple secrets matched search parameters, be more specific"
log.Printf("DeleteSecret %s\n", errString)
c.JSON(http.StatusBadRequest, gin.H{"error": errString})
return
}
}

View File

@@ -95,7 +95,8 @@ func SecretsGetAllowed(s *Secret, userId int) ([]UserSecret, error) {
}
// Query for user access
query += `UNION
query += `
UNION
SELECT users.UserId, users.GroupId, permissions.ReadOnly, permissions.SafeId, safes.SafeName, secrets.*
FROM users
INNER JOIN permissions ON users.UserId = permissions.UserId
@@ -137,6 +138,7 @@ func SecretsGetAllowed(s *Secret, userId int) ([]UserSecret, error) {
return secretResults, err
}
/*
// Decrypt the secret
_, err = r.DecryptSecret()
if err != nil {
@@ -146,7 +148,10 @@ func SecretsGetAllowed(s *Secret, userId int) ([]UserSecret, error) {
} else {
secretResults = append(secretResults, r)
}
*/
// Don't decrypt the secrets in the results of this query
secretResults = append(secretResults, r)
}
log.Printf("SecretsGetAllowedForGroup retrieved '%d' results\n", len(secretResults))
}
@@ -154,6 +159,7 @@ func SecretsGetAllowed(s *Secret, userId int) ([]UserSecret, error) {
return secretResults, nil
}
/*
func SecretsSearchAllSafes(s *Secret) ([]Secret, error) {
var err error
var secretResults []Secret
@@ -217,6 +223,7 @@ func SecretsSearchAllSafes(s *Secret) ([]Secret, error) {
return secretResults, nil
}
*/
// SecretsGetMultipleSafes queries the specified safes for matching secrets
func SecretsGetMultipleSafes(s *Secret, safeIds []int) ([]Secret, error) {
@@ -415,6 +422,31 @@ func (s *Secret) UpdateSecret() (*Secret, error) {
return s, nil
}
func (s *Secret) DeleteSecret() (*Secret, error) {
var err error
log.Printf("DeleteSecret deleting record with values '%v'\n", s)
if s.SecretId == 0 {
err = errors.New("unable to locate secret with empty secretId field")
log.Printf("DeleteSecret error in pre-check : '%s'\n", err)
return s, err
}
result, err := db.NamedExec((`DELETE FROM secrets WHERE SecretId = :SecretId`), s)
if err != nil {
log.Printf("DeleteSecret error executing sql record : '%s'\n", err)
return &Secret{}, err
} else {
affected, _ := result.RowsAffected()
id, _ := result.LastInsertId()
log.Printf("DeleteSecret delete returned result id '%d' affecting %d row(s).\n", id, affected)
}
return s, nil
}
// startCipher does the initial setup of the AES256 GCM mode cipher
func startCipher() (cipher.AEAD, error) {
key, err := ProvideKey()