diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/.DS_Store differ diff --git a/README.md b/README.md index ed5a6c4..3732e50 100644 --- a/README.md +++ b/README.md @@ -81,5 +81,34 @@ Data ### Secrets Operations #### Store +POST `/api/secret/store` + +``` +{ + "deviceName": "", + "deviceCategory": "", + "userName": "", + "secretValue": "" +} +``` + +Must be logged in to execute this command. Role of current user cannot be a ReadOnly role. Secret will be stored with the RoleId of the currently logged in user. Either deviceName or deviceCategory can be blank but not both. + #### Retrieve -#### Update \ No newline at end of file +GET `/api/secret/retrieve` + +Data +``` +{ + "deviceName": "", + "deviceCategory": "" +} +``` + +Must be logged in to execute this command. Only secrets registered with the current user's RoleId can be retrieved. + +Either deviceName or deviceCategory can be specified (or both). Wildcards are supported. +1. The percent sign % wildcard matches any sequence of zero or more characters. +2. The underscore _ wildcard matches any single character. + +#### Update diff --git a/controllers/auth.go b/controllers/auth.go index e1add1e..b7a6901 100644 --- a/controllers/auth.go +++ b/controllers/auth.go @@ -123,3 +123,15 @@ func CurrentUser(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "success", "data": u}) } + +func GetRoles(c *gin.Context) { + roles, err := models.QueryRoles() + + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"message": "success", "data": roles}) + +} diff --git a/controllers/store_secrets.go b/controllers/store_secrets.go index 04e7803..ebb5903 100644 --- a/controllers/store_secrets.go +++ b/controllers/store_secrets.go @@ -42,6 +42,11 @@ func StoreSecret(c *gin.Context) { s.RoleId = 1 } + if input.DeviceCategory == "" && input.DeviceName == "" { + c.JSON(http.StatusBadRequest, gin.H{"error": "cannot store secret with empty deviceName and empty deviceCategory"}) + return + } + // If this secret already exists in the database then generate an error checkExists, err := models.GetSecrets(&s) if err != nil { diff --git a/main.go b/main.go index a782ebb..00e2dd8 100644 --- a/main.go +++ b/main.go @@ -121,10 +121,11 @@ func main() { public := router.Group("/api") public.POST("/login", controllers.Login) - // TODO - this should be an authenticated route + // API calls that only an administrator can make adminOnly := router.Group("/api/admin") adminOnly.Use(middlewares.JwtAuthAdminMiddleware()) adminOnly.POST("/register", controllers.Register) + adminOnly.GET("/roles", controllers.GetRoles) // Get secrets protected := router.Group("/api/secret") diff --git a/models/role.go b/models/role.go new file mode 100644 index 0000000..167fea7 --- /dev/null +++ b/models/role.go @@ -0,0 +1,37 @@ +package models + +import "fmt" + +type Role struct { + RoleId int `db:"RoleId"` + RoleName string `db:"RoleName"` + ReadOnly bool `db:"ReadOnly"` + Admin bool `db:"Admin"` +} + +func QueryRoles() ([]Role, error) { + var results []Role + + // Query database for role definitions + rows, err := db.Queryx("SELECT * FROM roles") + + if err != nil { + fmt.Printf("QueryRoles error executing sql record : '%s'\n", err) + return results, err + } else { + // parse all the results into a slice + for rows.Next() { + var r Role + err = rows.StructScan(&r) + if err != nil { + fmt.Printf("QueryRoles error parsing sql record : '%s'\n", err) + return results, err + } + results = append(results, r) + + } + fmt.Printf("QueryRoles retrieved '%d' results\n", len(results)) + } + + return results, nil +}