admin only route is working
This commit is contained in:
20
controllers/retrieve_secrets.go
Normal file
20
controllers/retrieve_secrets.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type RetrieveInput struct {
|
||||
DeviceName string `json:"deviceName" binding:"required"`
|
||||
}
|
||||
|
||||
func Retrieve(c *gin.Context) {
|
||||
var input RetrieveInput
|
||||
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
}
|
24
controllers/store_secrets.go
Normal file
24
controllers/store_secrets.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// bindings are validated by https://github.com/go-playground/validator
|
||||
type StoreInput struct {
|
||||
RoleId int `json:"roleId"`
|
||||
DeviceName string `json:"deviceName" binding:"required"`
|
||||
UserName string `json:"userName" binding:"required"`
|
||||
SecretValue string `json:"secretValue" binding:"required"`
|
||||
}
|
||||
|
||||
func Store(c *gin.Context) {
|
||||
var input RetrieveInput
|
||||
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
}
|
14
main.go
14
main.go
@@ -25,7 +25,7 @@ func main() {
|
||||
|
||||
router := gin.Default()
|
||||
router.GET("/", func(c *gin.Context) {
|
||||
time.Sleep(10 * time.Second)
|
||||
//time.Sleep(10 * time.Second)
|
||||
c.String(http.StatusOK, "Welcome Gin Server")
|
||||
})
|
||||
|
||||
@@ -36,18 +36,18 @@ func main() {
|
||||
|
||||
// Register our routes
|
||||
public := router.Group("/api")
|
||||
public.POST("/register", controllers.Register)
|
||||
public.POST("/login", controllers.Login)
|
||||
|
||||
// This is just PoC really, we can get rid of it
|
||||
//protected := r.Group("/api/admin")
|
||||
//protected.Use(middlewares.JwtAuthMiddleware())
|
||||
//protected.GET("/user", controllers.CurrentUser)
|
||||
// TODO - this should be an authenticated route
|
||||
adminOnly := router.Group("/api/admin")
|
||||
adminOnly.Use(middlewares.JwtAuthAdminMiddleware())
|
||||
adminOnly.POST("/register", controllers.Register)
|
||||
|
||||
// Get secrets
|
||||
protected := router.Group("/api/secret")
|
||||
protected.Use(middlewares.JwtAuthMiddleware())
|
||||
protected.GET("/device", controllers.CurrentUser)
|
||||
protected.GET("/retrieve", controllers.Retrieve)
|
||||
protected.POST("/store", controllers.Store)
|
||||
|
||||
// Initializing the server in a goroutine so that
|
||||
// it won't block the graceful shutdown handling below
|
||||
|
@@ -1,8 +1,10 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"ccsecrets/models"
|
||||
"ccsecrets/utils/token"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -18,5 +20,45 @@ func JwtAuthMiddleware() gin.HandlerFunc {
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func JwtAuthAdminMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
|
||||
// TODO - also verify user role of admin
|
||||
|
||||
err := token.TokenValid(c)
|
||||
if err != nil {
|
||||
c.String(http.StatusUnauthorized, "Unauthorized")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
// Once we know the token is valid, figure out if this user is an admin
|
||||
user_id, err := token.ExtractTokenID(c)
|
||||
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
ur, err := models.GetUserRoleByID(user_id)
|
||||
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
fmt.Printf("JwtAuthAdminMiddleware retrieved UserRole object '%v'\n", ur)
|
||||
|
||||
if !ur.Admin {
|
||||
c.String(http.StatusUnauthorized, "User role is Non-Admin")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
// What does this do?
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
@@ -107,6 +107,14 @@ func CreateTables() {
|
||||
fmt.Printf("Error adding initial admin role : '%s'", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if _, err = db.Exec("INSERT INTO roles VALUES(2, 'UserRole', false, false);"); err != nil {
|
||||
fmt.Printf("Error adding initial admin role : '%s'", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if _, err = db.Exec("INSERT INTO roles VALUES(3, 'GuestRole', true, false);"); err != nil {
|
||||
fmt.Printf("Error adding initial admin role : '%s'", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Users table
|
||||
@@ -116,7 +124,7 @@ func CreateTables() {
|
||||
}
|
||||
rowCount, _ = CheckCount("users")
|
||||
if rowCount == 0 {
|
||||
if _, err = db.Exec("INSERT INTO users VALUES(1, 1, 'Administrator', 'password', 'token');"); err != nil {
|
||||
if _, err = db.Exec("INSERT INTO users VALUES(1, 1, 'Administrator', '$2a$10$k1qldm.bWqZsQWrKPdahR.Pfz5LxkMUka2.8INEeSD7euzkiznIR.', 'token');"); err != nil {
|
||||
fmt.Printf("Error adding initial admin role : '%s'", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
@@ -16,6 +16,13 @@ type User struct {
|
||||
AccessToken string `db:"AccessToken"`
|
||||
}
|
||||
|
||||
type UserRole struct {
|
||||
User
|
||||
RoleName string `db:"RoleName"`
|
||||
ReadOnly bool `db:"ReadOnly"`
|
||||
Admin bool `db:"Admin"`
|
||||
}
|
||||
|
||||
func (u *User) SaveUser() (*User, error) {
|
||||
|
||||
var err error
|
||||
@@ -81,7 +88,7 @@ func GetUserByID(uid uint) (User, error) {
|
||||
var u User
|
||||
|
||||
// Query database for matching user object
|
||||
err := db.QueryRowx("SELECT * FROM Users WHERE UserId=?", uid).StructScan(&u)
|
||||
err := db.QueryRowx("SELECT * FROM users INNER JOIN roles ON users.RoleId = roles.RoleId WHERE UserId=?", uid).StructScan(&u)
|
||||
if err != nil {
|
||||
return u, errors.New("user not found")
|
||||
}
|
||||
@@ -96,6 +103,22 @@ func GetUserByID(uid uint) (User, error) {
|
||||
|
||||
}
|
||||
|
||||
func GetUserRoleByID(uid uint) (UserRole, error) {
|
||||
|
||||
var ur UserRole
|
||||
|
||||
// Query database for matching user object
|
||||
fmt.Printf("GetUserRoleByID querying for userid '%d'\n", uid)
|
||||
err := db.QueryRowx("SELECT users.UserId, users.RoleId, users.UserName, users.Password, users.AccessToken, roles.RoleName, roles.ReadOnly, roles.Admin FROM users INNER JOIN roles ON users.RoleId = roles.RoleId WHERE users.UserId=?", uid).StructScan(&ur)
|
||||
if err != nil {
|
||||
fmt.Printf("GetUserRoleByID received error when querying database : '%s'\n", err)
|
||||
return ur, errors.New("GetUserRoleByID user not found")
|
||||
}
|
||||
|
||||
return ur, nil
|
||||
|
||||
}
|
||||
|
||||
func (u *User) PrepareGive() {
|
||||
u.Password = ""
|
||||
}
|
||||
|
Reference in New Issue
Block a user