initial safes handler
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2024-01-10 11:29:21 +11:00
parent 8143470b5a
commit 50f078db7a
4 changed files with 141 additions and 11 deletions

View File

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

26
main.go
View File

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

View File

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

View File

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