init
This commit is contained in:
51
network/http/context/context.go
Normal file
51
network/http/context/context.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"go_oxspeak_server/models"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// Context wrapper avec des helpers
|
||||
// NE contient PAS de dépendances globales (DB, Config, etc.)
|
||||
type Context struct {
|
||||
*gin.Context
|
||||
}
|
||||
|
||||
func NewContext(c *gin.Context) *Context {
|
||||
return &Context{Context: c}
|
||||
}
|
||||
|
||||
// Helpers pour accéder aux données de REQUÊTE
|
||||
|
||||
func (c *Context) GetCurrentUser() (*models.User, bool) {
|
||||
value, exists := c.Get("currentUser")
|
||||
if !exists {
|
||||
return nil, false
|
||||
}
|
||||
user, ok := value.(*models.User)
|
||||
return user, ok
|
||||
}
|
||||
|
||||
func (c *Context) MustGetCurrentUser() *models.User {
|
||||
user, ok := c.GetCurrentUser()
|
||||
if !ok {
|
||||
c.AbortWithStatusJSON(401, gin.H{"error": "Unauthorized"})
|
||||
panic("no authenticated user")
|
||||
}
|
||||
return user
|
||||
}
|
||||
|
||||
func (c *Context) GetRequestID() string {
|
||||
value, exists := c.Get("requestID")
|
||||
if !exists {
|
||||
return ""
|
||||
}
|
||||
id, _ := value.(string)
|
||||
return id
|
||||
}
|
||||
|
||||
func (c *Context) IsAuthenticated() bool {
|
||||
_, exists := c.GetCurrentUser()
|
||||
return exists
|
||||
}
|
||||
13
network/http/handler/handler.go
Normal file
13
network/http/handler/handler.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package handler
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type Handler struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewHandler(db *gorm.DB) *Handler {
|
||||
return &Handler{
|
||||
DB: db,
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"go_oxspeak_server/models"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type ChannelHandler struct {
|
||||
*Handler
|
||||
}
|
||||
|
||||
func AddChannelRoutes(rg *gin.RouterGroup, h *Handler) {
|
||||
channel := rg.Group("/channel")
|
||||
|
||||
handler := &ChannelHandler{h}
|
||||
channel.GET("/:id", handler.getChannels)
|
||||
|
||||
}
|
||||
|
||||
func (h *Handler) getChannels(c *gin.Context) {
|
||||
var users []models.User
|
||||
h.DB.Find(&users)
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"go_oxspeak_server/database"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func CreateRouter() *gin.Engine {
|
||||
router := gin.Default()
|
||||
|
||||
handler := &Handler{DB: database.DB}
|
||||
|
||||
api := router.Group("/api")
|
||||
{
|
||||
AddChannelRoutes(api, handler)
|
||||
}
|
||||
|
||||
router.GET("/health", handler.healthcheck)
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
func (h *Handler) healthcheck(c *gin.Context) {
|
||||
c.JSON(200, gin.H{"status": "ok"})
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
package handlers
|
||||
1
network/http/middleware/auth.go
Normal file
1
network/http/middleware/auth.go
Normal file
@@ -0,0 +1 @@
|
||||
package middleware
|
||||
@@ -1,10 +1,6 @@
|
||||
package http
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
import "github.com/gin-gonic/gin"
|
||||
|
||||
// CORSMiddleware configure les headers CORS
|
||||
func CORSMiddleware() gin.HandlerFunc {
|
||||
@@ -22,11 +18,3 @@ func CORSMiddleware() gin.HandlerFunc {
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// LoggingMiddleware personnalisé (optionnel, Gin en a un par défaut)
|
||||
func LoggingMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
log.Printf("[HTTP] %s %s", c.Request.Method, c.Request.URL.Path)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"go_oxspeak_server/network/http/handlers"
|
||||
"go_oxspeak_server/network/http/web"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -12,7 +12,7 @@ type Server struct {
|
||||
}
|
||||
|
||||
func NewServer(addr string) *Server {
|
||||
router := handlers.CreateRouter()
|
||||
router := web.CreateRouter()
|
||||
|
||||
s := &Server{
|
||||
router: router,
|
||||
|
||||
46
network/http/web/api/category.go
Normal file
46
network/http/web/api/category.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"go_oxspeak_server/models"
|
||||
"go_oxspeak_server/network/http/handler"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type CategoryHandler struct {
|
||||
*handler.Handler
|
||||
}
|
||||
|
||||
func NewCategoryHandler(h *handler.Handler) *CategoryHandler {
|
||||
return &CategoryHandler{h}
|
||||
}
|
||||
|
||||
func (h *CategoryHandler) RegisterRoutes(rg *gin.RouterGroup) {
|
||||
category := rg.Group("/category")
|
||||
category.GET("/", h.getCategories)
|
||||
category.GET("/:id/", h.getCategory)
|
||||
category.POST("/", h.addCategory)
|
||||
category.PUT("/:id/", h.updateCategory)
|
||||
category.DELETE("/:id/", h.deleteCategory)
|
||||
}
|
||||
|
||||
func (h *CategoryHandler) getCategories(c *gin.Context) {
|
||||
var categories []models.Category
|
||||
h.DB.Find(&categories)
|
||||
}
|
||||
|
||||
func (h *CategoryHandler) getCategory(c *gin.Context) {
|
||||
var category models.Category
|
||||
h.DB.Find(&category)
|
||||
}
|
||||
|
||||
func (h *CategoryHandler) addCategory(c *gin.Context) {
|
||||
|
||||
}
|
||||
|
||||
func (h *CategoryHandler) updateCategory(c *gin.Context) {
|
||||
|
||||
}
|
||||
|
||||
func (h *CategoryHandler) deleteCategory(c *gin.Context) {
|
||||
}
|
||||
51
network/http/web/api/channel.go
Normal file
51
network/http/web/api/channel.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"go_oxspeak_server/models"
|
||||
"go_oxspeak_server/network/http/handler"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type ChannelHandler struct {
|
||||
*handler.Handler
|
||||
}
|
||||
|
||||
func NewChannelHandler(h *handler.Handler) *ChannelHandler {
|
||||
return &ChannelHandler{h}
|
||||
}
|
||||
|
||||
func (h *ChannelHandler) RegisterRoutes(rg *gin.RouterGroup) {
|
||||
channel := rg.Group("/channel")
|
||||
channel.GET("/", h.getChannels)
|
||||
channel.GET("/:id/", h.getChannel)
|
||||
channel.POST("/", h.addChannel)
|
||||
channel.PUT("/:id/", h.updateChannel)
|
||||
channel.DELETE("/:id/", h.deleteChannel)
|
||||
|
||||
}
|
||||
|
||||
func (h *ChannelHandler) getChannels(c *gin.Context) {
|
||||
var users []models.User
|
||||
h.DB.Find(&users)
|
||||
|
||||
}
|
||||
|
||||
func (h *ChannelHandler) getChannel(c *gin.Context) {
|
||||
var user models.User
|
||||
h.DB.Find(&user)
|
||||
}
|
||||
|
||||
func (h *ChannelHandler) addChannel(c *gin.Context) {
|
||||
|
||||
}
|
||||
|
||||
func (h *ChannelHandler) updateChannel(c *gin.Context) {
|
||||
var user models.User
|
||||
h.DB.Find(&user)
|
||||
}
|
||||
|
||||
func (h *ChannelHandler) deleteChannel(c *gin.Context) {
|
||||
var user models.User
|
||||
h.DB.Find(&user)
|
||||
}
|
||||
46
network/http/web/api/message.go
Normal file
46
network/http/web/api/message.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"go_oxspeak_server/models"
|
||||
"go_oxspeak_server/network/http/handler"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type MessageHandler struct {
|
||||
*handler.Handler
|
||||
}
|
||||
|
||||
func NewMessageHandler(h *handler.Handler) *MessageHandler {
|
||||
return &MessageHandler{h}
|
||||
}
|
||||
|
||||
func (h *MessageHandler) RegisterRoutes(rg *gin.RouterGroup) {
|
||||
message := rg.Group("/message")
|
||||
message.GET("/", h.getMessages)
|
||||
message.GET("/:id/", h.getMessage)
|
||||
message.POST("/", h.addMessage)
|
||||
message.PUT("/:id/", h.updateMessage)
|
||||
message.DELETE("/:id/", h.deleteMessage)
|
||||
}
|
||||
|
||||
func (h *MessageHandler) getMessages(c *gin.Context) {
|
||||
var messages []models.Message
|
||||
h.DB.Find(&messages)
|
||||
}
|
||||
|
||||
func (h *MessageHandler) getMessage(c *gin.Context) {
|
||||
var message models.Message
|
||||
h.DB.Find(&message)
|
||||
}
|
||||
|
||||
func (h *MessageHandler) addMessage(c *gin.Context) {
|
||||
|
||||
}
|
||||
|
||||
func (h *MessageHandler) updateMessage(c *gin.Context) {
|
||||
|
||||
}
|
||||
|
||||
func (h *MessageHandler) deleteMessage(c *gin.Context) {
|
||||
}
|
||||
46
network/http/web/api/server.go
Normal file
46
network/http/web/api/server.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"go_oxspeak_server/models"
|
||||
"go_oxspeak_server/network/http/handler"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type ServerHandler struct {
|
||||
*handler.Handler
|
||||
}
|
||||
|
||||
func NewServerHandler(h *handler.Handler) *ServerHandler {
|
||||
return &ServerHandler{h}
|
||||
}
|
||||
|
||||
func (h *ServerHandler) RegisterRoutes(rg *gin.RouterGroup) {
|
||||
server := rg.Group("/server")
|
||||
server.GET("/", h.getServers)
|
||||
server.GET("/:id/", h.getServer)
|
||||
server.POST("/", h.addServer)
|
||||
server.PUT("/:id/", h.updateServer)
|
||||
server.DELETE("/:id/", h.deleteServer)
|
||||
}
|
||||
|
||||
func (h *ServerHandler) getServers(c *gin.Context) {
|
||||
var servers []models.Server
|
||||
h.DB.Find(&servers)
|
||||
}
|
||||
|
||||
func (h *ServerHandler) getServer(c *gin.Context) {
|
||||
var server models.Server
|
||||
h.DB.Find(&server)
|
||||
}
|
||||
|
||||
func (h *ServerHandler) addServer(c *gin.Context) {
|
||||
|
||||
}
|
||||
|
||||
func (h *ServerHandler) updateServer(c *gin.Context) {
|
||||
|
||||
}
|
||||
|
||||
func (h *ServerHandler) deleteServer(c *gin.Context) {
|
||||
}
|
||||
72
network/http/web/auth.go
Normal file
72
network/http/web/auth.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"go_oxspeak_server/models"
|
||||
"go_oxspeak_server/network/http/handler"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type AuthHandler struct {
|
||||
*handler.Handler
|
||||
}
|
||||
|
||||
func NewAuthHandler(h *handler.Handler) *AuthHandler {
|
||||
return &AuthHandler{h}
|
||||
}
|
||||
|
||||
func (h *AuthHandler) RegisterRoutes(rg *gin.RouterGroup) {
|
||||
channel := rg.Group("/channel")
|
||||
channel.GET("/login/", h.authenticate)
|
||||
|
||||
}
|
||||
|
||||
type AuthRequest struct {
|
||||
PublicKey string `json:"pub_key" binding:"required"`
|
||||
}
|
||||
|
||||
type AuthResponse struct {
|
||||
JWT string `json:"JWT"`
|
||||
}
|
||||
|
||||
func (h *AuthHandler) authenticate(c *gin.Context) {
|
||||
var req AuthRequest
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
var user models.User
|
||||
result := h.DB.Where("public_key = ?", req.PublicKey).First(&user)
|
||||
if result.Error != nil {
|
||||
if result.Error == gorm.ErrRecordNotFound {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid public key"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal server error"})
|
||||
}
|
||||
|
||||
// Generate token
|
||||
claims := jwt.MapClaims{
|
||||
"user_id": user.ID,
|
||||
"expiration_date": time.Now().Add(time.Hour * 72).Unix(),
|
||||
"creation_date": time.Now().Unix(),
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodES256, claims)
|
||||
// TODO: Remplacer par votre clé secrète (utiliser une variable d'environnement)
|
||||
secretKey := []byte("votre-cle-secrete-a-changer")
|
||||
|
||||
jwtString, err := token.SignedString(secretKey)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur lors de la génération du JWT"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, AuthResponse{JWT: jwtString})
|
||||
}
|
||||
48
network/http/web/main.go
Normal file
48
network/http/web/main.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"go_oxspeak_server/database"
|
||||
"go_oxspeak_server/network/http/handler"
|
||||
"go_oxspeak_server/network/http/middleware"
|
||||
"go_oxspeak_server/network/http/web/api"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func CreateRouter() *gin.Engine {
|
||||
router := gin.Default()
|
||||
|
||||
// Register middleware
|
||||
router.Use(middleware.CORSMiddleware())
|
||||
|
||||
// Create base handler
|
||||
baseHandler := handler.NewHandler(database.DB)
|
||||
|
||||
// Create specific handler
|
||||
authHandler := NewAuthHandler(baseHandler)
|
||||
serverHandler := api.NewServerHandler(baseHandler)
|
||||
categoryHandler := api.NewCategoryHandler(baseHandler)
|
||||
channelHandler := api.NewChannelHandler(baseHandler)
|
||||
messageHandler := api.NewMessageHandler(baseHandler)
|
||||
|
||||
authGroup := router.Group("/auth")
|
||||
{
|
||||
authHandler.RegisterRoutes(authGroup)
|
||||
}
|
||||
|
||||
apiGroup := router.Group("/api")
|
||||
{
|
||||
serverHandler.RegisterRoutes(apiGroup)
|
||||
channelHandler.RegisterRoutes(apiGroup)
|
||||
categoryHandler.RegisterRoutes(apiGroup)
|
||||
messageHandler.RegisterRoutes(apiGroup)
|
||||
}
|
||||
|
||||
router.GET("/health", healthcheck)
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
func healthcheck(c *gin.Context) {
|
||||
c.JSON(200, gin.H{"status": "ok"})
|
||||
}
|
||||
38
network/http/web/ws.go
Normal file
38
network/http/web/ws.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"go_oxspeak_server/network/http/handler"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
type WSHandler struct {
|
||||
*handler.Handler
|
||||
}
|
||||
|
||||
func NewWSHandler(h *handler.Handler) *WSHandler {
|
||||
return &WSHandler{h}
|
||||
}
|
||||
|
||||
func (h *WSHandler) RegisterRoutes(rg *gin.RouterGroup) {
|
||||
ws := rg.Group("/ws")
|
||||
ws.GET("/", h.handleWS)
|
||||
}
|
||||
|
||||
var upgrader = websocket.Upgrader{}
|
||||
|
||||
func (h *WSHandler) handleWS(c *gin.Context) {
|
||||
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
for {
|
||||
_, _, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
1
network/websocket/hub.go
Normal file
1
network/websocket/hub.go
Normal file
@@ -0,0 +1 @@
|
||||
package websocket
|
||||
Reference in New Issue
Block a user