124 lines
3.6 KiB
Go
124 lines
3.6 KiB
Go
package app
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
common "access-manager-api/app/common"
|
|
"access-manager-api/app/pve"
|
|
|
|
"github.com/gin-contrib/sessions"
|
|
"github.com/gin-contrib/sessions/cookie"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type UserSession struct {
|
|
PVE common.Backend
|
|
Realm struct {
|
|
Name string
|
|
Handler common.Backend
|
|
}
|
|
DB common.Backend
|
|
}
|
|
|
|
var Version = "1.0.0"
|
|
var Config common.Config
|
|
var RootSession *UserSession
|
|
var UserSessions map[string]*UserSession
|
|
var Realms map[string]common.Realm
|
|
|
|
func Run() {
|
|
configPath := flag.String("config", "config.json", "path to config.json file")
|
|
flag.Parse()
|
|
|
|
// load config values
|
|
Config = common.GetConfig(*configPath)
|
|
// already exits if failed
|
|
log.Printf("Read in config from %s\n", *configPath)
|
|
|
|
// setup gin
|
|
gin.SetMode(gin.ReleaseMode)
|
|
router := gin.Default()
|
|
|
|
// setup api auth cookies
|
|
SetupAPISessionStore(router, &Config)
|
|
|
|
// setup root api token
|
|
client, code, err := pve.NewClientFromAPIToken(Config.PVE)
|
|
if err != nil {
|
|
log.Fatalf("error initializing pve root client: %d %s", code, err)
|
|
}
|
|
RootSession = &UserSession{
|
|
PVE: client,
|
|
}
|
|
|
|
// get realms from proxmox
|
|
Realms = make(map[string]common.Realm)
|
|
Realms = RootSession.PVE.(pve.ProxmoxClient).GetRealms()
|
|
|
|
// make global session map
|
|
UserSessions = make(map[string]*UserSession)
|
|
|
|
router.GET("/version", func(c *gin.Context) {
|
|
c.JSON(http.StatusOK, gin.H{"version": Version})
|
|
})
|
|
|
|
router.POST("/ticket", POST_Ticket)
|
|
router.DELETE("/ticket", DELETE_Ticket)
|
|
router.GET("/pools/:poolid", GET_Pool)
|
|
router.POST("/pools/:poolid", POST_Pool)
|
|
router.DELETE("/pools/:poolid", DELETE_Pool)
|
|
router.GET("/groups/:groupname", GET_Group)
|
|
router.POST("/groups/:groupname", POST_Group)
|
|
router.DELETE("/groups/:groupname", DELETE_Group)
|
|
router.POST("/pools/:poolid/groups/:groupname", POST_Pool_Group)
|
|
router.DELETE("/pools/:poolid/groups/:groupname")
|
|
router.GET("/users/:username", GET_User)
|
|
router.POST("/users/:username", POST_User)
|
|
router.DELETE("/users/:username", DELETE_User)
|
|
router.POST("/groups/:groupname/users/:username", POST_Group_User)
|
|
router.DELETE("/groups/:groupname/users/:username", DELETE_Group_User)
|
|
|
|
log.Printf("Starting Access Manager API on port %s\n", strconv.Itoa(Config.ListenPort))
|
|
|
|
err = router.Run("0.0.0.0:" + strconv.Itoa(Config.ListenPort))
|
|
if err != nil {
|
|
log.Fatalf("Error starting router: %s", err.Error())
|
|
}
|
|
}
|
|
|
|
func SetupAPISessionStore(router *gin.Engine, config *common.Config) {
|
|
authKey := make([]byte, 32)
|
|
encrKey := make([]byte, 32)
|
|
n, _ := rand.Read(authKey) // rand Read never returns an error, always crashes on error
|
|
log.Printf("Generated cookie session authentication key of length %d\n", n)
|
|
n, _ = rand.Read(encrKey) // rand Read never returns an error, always crashes on error
|
|
log.Printf("Generated cookie session encryption key of length %d\n", n)
|
|
|
|
store := cookie.NewStore(authKey, encrKey)
|
|
store.Options(sessions.Options{
|
|
Path: config.SessionCookie.Path,
|
|
HttpOnly: config.SessionCookie.HttpOnly,
|
|
Secure: config.SessionCookie.Secure,
|
|
MaxAge: config.SessionCookie.MaxAge,
|
|
})
|
|
router.Use(sessions.Sessions(config.SessionCookieName, store))
|
|
|
|
log.Printf("Started cookie store (Name: %s Params: %+v)\n", config.SessionCookieName, config.SessionCookie)
|
|
}
|
|
|
|
func GetUserSessionFromContext(c *gin.Context) (*UserSession, int, error) {
|
|
session := sessions.Default(c)
|
|
SessionUUID := session.Get("SessionUUID")
|
|
if SessionUUID == nil {
|
|
return nil, http.StatusUnauthorized, fmt.Errorf("no auth session found")
|
|
}
|
|
uuid := SessionUUID.(string)
|
|
usersession := UserSessions[uuid]
|
|
return usersession, http.StatusOK, nil
|
|
}
|