diff --git a/controllers/controlSafes.go b/controllers/controlSafes.go new file mode 100644 index 0000000..66cc25c --- /dev/null +++ b/controllers/controlSafes.go @@ -0,0 +1,46 @@ +package controllers + +import ( + "fmt" + "log" + "net/http" + "smt/models" + + "github.com/gin-gonic/gin" +) + +// GetSafesHandler provides a list of all safes that a user has access to +func GetSafesHandler(c *gin.Context) { + var UserId int + if val, ok := c.Get("user-id"); !ok { + c.JSON(http.StatusBadRequest, gin.H{"error": "error determining user"}) + return + } else { + UserId = val.(int) + } + + safes, err := models.SafeListAllowed(UserId) + + if err != nil { + errString := fmt.Sprintf("error retrieving safes : '%s'", err) + log.Printf("GetSafesHandler %s\n", errString) + c.JSON(http.StatusBadRequest, gin.H{"error": errString}) + return + } + + c.JSON(http.StatusOK, gin.H{"message": "success", "data": safes}) +} + +// GetAllSafesHandler provides an admin user a list of all safes that exist in the database +func GetAllSafesHandler(c *gin.Context) { + safes, err := models.SafeList() + + if err != nil { + errString := fmt.Sprintf("error retrieving safes : '%s'", err) + log.Printf("GetSafesHandler %s\n", errString) + c.JSON(http.StatusBadRequest, gin.H{"error": errString}) + return + } + + c.JSON(http.StatusOK, gin.H{"message": "success", "data": safes}) +} diff --git a/main.go b/main.go index ed00702..a0b6f5d 100644 --- a/main.go +++ b/main.go @@ -259,26 +259,32 @@ func main() { // Other functions for admin adminOnly.POST("/unlock", controllers.Unlock) + adminOnly.POST("/safes/listall", controllers.GetAllSafesHandler) // Deprecated //adminOnly.GET("/roles", controllers.GetRoles) //adminOnly.POST("/role/add", controllers.AddRole) // Get secrets - protected := router.Group("/api/secret") - protected.Use(middlewares.JwtAuthMiddleware()) - protected.POST("/retrieve", controllers.RetrieveSecret) - protected.GET("/list", controllers.ListSecrets) - protected.POST("/retrieveMultiple", controllers.RetrieveMultpleSecrets) // TODO is this still required? - protected.POST("/store", controllers.StoreSecret) - protected.POST("/update", controllers.UpdateSecret) + secretRoutes := router.Group("/api/secret") + secretRoutes.Use(middlewares.JwtAuthMiddleware()) + secretRoutes.POST("/retrieve", controllers.RetrieveSecret) + secretRoutes.GET("/list", controllers.ListSecrets) + secretRoutes.POST("/retrieveMultiple", controllers.RetrieveMultpleSecrets) // TODO is this still required? + secretRoutes.POST("/store", controllers.StoreSecret) + secretRoutes.POST("/update", controllers.UpdateSecret) // TODO - protected.POST("/delete", controllers.DeleteSecret) + secretRoutes.POST("/delete", controllers.DeleteSecret) + + // Get Safes (only those user allowed to access) + safeRoutes := router.Group("/api/safe") + safeRoutes.Use(middlewares.JwtAuthMiddleware()) + safeRoutes.GET("/list", controllers.GetSafesHandler) // Support parameters in path // See https://gin-gonic.com/docs/examples/param-in-path/ - protected.GET("/retrieve/name/:devicename", controllers.RetrieveSecretByDevicename) - protected.GET("/retrieve/category/:devicecategory", controllers.RetrieveSecretByDevicecategory) + secretRoutes.GET("/retrieve/name/:devicename", controllers.RetrieveSecretByDevicename) + secretRoutes.GET("/retrieve/category/:devicecategory", controllers.RetrieveSecretByDevicecategory) // Initializing the server in a goroutine so that // it won't block the graceful shutdown handling below diff --git a/models/group.go b/models/group.go index df3f803..3bcbf59 100644 --- a/models/group.go +++ b/models/group.go @@ -30,7 +30,7 @@ func GroupGetByName(groupname string) (Group, error) { func GroupList() ([]Group, error) { var results []Group - // Query database for role definitions + // Query database for groups rows, err := db.Queryx("SELECT * FROM groups") if err != nil { diff --git a/models/safe.go b/models/safe.go index f86e73c..772d93a 100644 --- a/models/safe.go +++ b/models/safe.go @@ -1,6 +1,84 @@ package models +import ( + "errors" + "log" +) + type Safe struct { SafeId int `db:"SafeId"` SafeName string `db:"SafeName"` } + +// SafeGetByName queries the database for the specified safe name +func SafeGetByName(safename string) (Safe, error) { + var s Safe + + // Query database for matching group object + err := db.QueryRowx("SELECT * FROM safes WHERE SafeName=?", safename).StructScan(&s) + if err != nil { + return s, errors.New("safe not found") + } + + return s, nil +} + +// SafeList returns a list of all safes in database +func SafeList() ([]Safe, error) { + var results []Safe + + // Query database for safes + rows, err := db.Queryx("SELECT * FROM safes") + + if err != nil { + log.Printf("SafeList error executing sql record : '%s'\n", err) + return results, err + } else { + // parse all the results into a slice + for rows.Next() { + var s Safe + err = rows.StructScan(&s) + if err != nil { + log.Printf("SafeList error parsing sql record : '%s'\n", err) + return results, err + } + results = append(results, s) + + } + log.Printf("SafeList retrieved '%d' results\n", len(results)) + } + + return results, nil +} + +// SafeList returns a list of safes in database that a user has access to +func SafeListAllowed(userId int) ([]Safe, error) { + var results []Safe + + // Query database for safes + rows, err := db.Queryx(` + SELECT safes.* FROM safes INNER JOIN permissions ON safes.SafeId = permissions.SafeId INNER JOIN users ON users.GroupId = permissions.GroupId WHERE users.UserId = ? + UNION + SELECT safes.* FROM safes INNER JOIN permissions ON safes.SafeId = permissions.SafeId INNER JOIN users ON users.UserId = permissions.UserId WHERE users.UserId = ? + `, userId, userId) + + if err != nil { + log.Printf("SafeList error executing sql record : '%s'\n", err) + return results, err + } else { + // parse all the results into a slice + for rows.Next() { + var s Safe + err = rows.StructScan(&s) + if err != nil { + log.Printf("SafeList error parsing sql record : '%s'\n", err) + return results, err + } + results = append(results, s) + + } + log.Printf("SafeList retrieved '%d' results\n", len(results)) + } + + return results, nil +}