package controllers import ( "log" "net/http" "smt/models" "smt/utils/token" "github.com/gin-gonic/gin" ) type RetrieveInput struct { DeviceName string `json:"deviceName"` DeviceCategory string `json:"deviceCategory"` UserName string `json:"userName"` SafeId int `json:"safeId"` SafeName string `json:"safeName"` } type ListSecret struct { SecretId int `db:"SecretId" json:"-"` //RoleId int `db:"RoleId" json:"-"` SafeId int `db:"SafeId"` DeviceName string `db:"DeviceName"` DeviceCategory string `db:"DeviceCategory"` UserName string `db:"UserName"` Secret string `db:"Secret" json:"-"` } func RetrieveSecret(c *gin.Context) { var input RetrieveInput var results []models.Secret var userIsAdmin bool = false // Validate the input matches our struct if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } log.Printf("RetrieveSecret received JSON input '%v'\n", input) /* // Get the user and role id of the requestor u, err := models.UserGetRoleFromToken(c) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } */ // Populate fields s := models.Secret{} //s.RoleId = u.RoleId s.DeviceName = input.DeviceName s.DeviceCategory = input.DeviceCategory s.UserName = input.UserName user_id, err := token.ExtractTokenID(c) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "error determining user"}) return } // Work out which safe to query for this user if the safe was not specified safeList, err := models.UserGetSafesAllowed(int(user_id)) // If there was only one result then just use that if len(safeList) == 0 { // check if the user is an admin, if not then they seem to have access to zero safes if !models.UserCheckIfAdmin(int(user_id)) { c.JSON(http.StatusBadRequest, gin.H{"error": "user has no access to any secrets"}) return } // Don't apply a role filter if user has admin role results, err = models.GetSecrets(&s, userIsAdmin) } else if len(safeList) == 1 { s.SafeId = safeList[0].SafeId userIsAdmin = safeList[0].AdminUser || safeList[0].AdminGroup // Don't apply a role filter if user has admin role results, err = models.GetSecrets(&s, userIsAdmin) } else { // TODO - this is tricky. How to query multiple safes? var safeIds []int for _, safe := range safeList { safeIds = append(safeIds, safe.SafeId) } results, err = models.SecretsGetMultipleSafes(&s, false, safeIds) } if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if len(results) == 1 { // output results as json c.JSON(http.StatusOK, gin.H{"message": "success", "data": results}) } else if len(results) > 1 { c.JSON(http.StatusBadRequest, gin.H{"error": "found multiple matching secrets, use retrieveMultiple instead"}) return } else { c.JSON(http.StatusBadRequest, gin.H{"error": "found no matching secrets"}) return } } func RetrieveSecretByDevicename(c *gin.Context) { DeviceName := c.Param("devicename") if DeviceName == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "no devicename value specified"}) return } // Create object based on specified data s := models.Secret{DeviceName: DeviceName} //s.DeviceName = DeviceName retrieveSpecifiedSecret(&s, c) } func RetrieveSecretByDevicecategory(c *gin.Context) { DeviceCategory := c.Param("devicecategory") if DeviceCategory == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "no devicecategory value specified"}) return } // Create object based on specified data s := models.Secret{DeviceCategory: DeviceCategory} retrieveSpecifiedSecret(&s, c) } func retrieveSpecifiedSecret(s *models.Secret, c *gin.Context) { /* // Get the user and role id of the requestor u, err := models.UserGetRoleFromToken(c) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } s.RoleId = u.RoleId results, err := models.GetSecrets(s, false) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } */ var results []models.Secret var userIsAdmin = false user_id, err := token.ExtractTokenID(c) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "error determining user"}) return } // Work out which safe to query for this user if the safe was not specified safeList, err := models.UserGetSafesAllowed(int(user_id)) // If there was only one result then just use that if len(safeList) == 0 { // check if the user is an admin, if not then they seem to have access to zero safes if !models.UserCheckIfAdmin(int(user_id)) { c.JSON(http.StatusBadRequest, gin.H{"error": "user has no access to any secrets"}) return } // Don't apply a role filter if user has admin role results, err = models.GetSecrets(s, userIsAdmin) } else if len(safeList) == 1 { s.SafeId = safeList[0].SafeId userIsAdmin = safeList[0].AdminUser || safeList[0].AdminGroup // Don't apply a role filter if user has admin role results, err = models.GetSecrets(s, userIsAdmin) } else { // TODO - this is tricky. How to query multiple safes? var safeIds []int for _, safe := range safeList { safeIds = append(safeIds, safe.SafeId) } results, err = models.SecretsGetMultipleSafes(s, false, safeIds) } if len(results) == 1 { // output results as json c.JSON(http.StatusOK, gin.H{"message": "success", "data": results}) } else if len(results) > 1 { c.JSON(http.StatusBadRequest, gin.H{"error": "found multiple matching secrets"}) return } else { c.JSON(http.StatusBadRequest, gin.H{"error": "found no matching secrets"}) return } } func ListSecrets(c *gin.Context) { var output []ListSecret // TODO implement with new schema /* var results []models.Secret // Get the user and role id of the requestor u, err := models.UserGetRoleFromToken(c) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // If user is admin then list everything, otherwise only list for current role results, err = models.GetSecrets(&models.Secret{RoleId: u.RoleId}, u.Admin) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } for _, v := range results { output = append(output, ListSecret(v)) } */ // output results as json c.JSON(http.StatusOK, gin.H{"message": "success", "data": output}) } func RetrieveMultpleSecrets(c *gin.Context) { // TODO implement with new schema /* var input RetrieveInput // Validate the input matches our struct if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } log.Printf("StoreSecret received JSON input '%v'\n", input) // Get the user and role id of the requestor user_id, err := token.ExtractTokenID(c) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } u, err := models.GetUserRoleByID(user_id) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // Populate fields s := models.Secret{} s.RoleId = u.RoleId s.DeviceName = input.DeviceName s.DeviceCategory = input.DeviceCategory results, err := models.GetSecrets(&s, false) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // output results as json c.JSON(http.StatusOK, gin.H{"message": "success", "data": results}) */ }