CSI-ES-2324/Projs/PD2/internal/gateway/gateway.go

235 lines
5.8 KiB
Go
Raw Normal View History

package gateway
2024-05-29 17:33:36 +01:00
import (
2024-05-30 15:48:28 +01:00
"PD2/internal/protocol"
"PD2/internal/utils/cryptoUtils"
"crypto/x509"
"log"
2024-05-29 17:33:36 +01:00
"net/http"
"github.com/gin-gonic/gin"
)
func HandleGetMessage(c *gin.Context, keyStore cryptoUtils.KeyStore) {
uid, exists := c.Get("uid")
if !exists {
c.JSON(http.StatusBadRequest, gin.H{"error": "User does not exist"})
return
}
uidString := uid.(string)
2024-05-29 17:33:36 +01:00
num := c.Param("num")
if num == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "User does not exist"})
return
}
statusCode, body, err := forwardGetMessage(keyStore.GetGatewayOutgoingTLSConfig(), uidString, num)
if err != nil {
log.Println(err.Error())
} else {
c.Data(statusCode, "application/json", body)
}
2024-05-29 17:33:36 +01:00
}
func HandleGetUnreadMsgsInfo(c *gin.Context, keyStore cryptoUtils.KeyStore) {
page := c.Query("page")
pagesize := c.Query("pagesize")
uid, exists := c.Get("uid")
if !exists {
c.JSON(http.StatusBadRequest, gin.H{"error": "User does not exist"})
return
}
uidString := uid.(string)
statusCode, body, err := forwardGetUnreadMsgsInfo(keyStore.GetGatewayOutgoingTLSConfig(), uidString, page, pagesize)
if err != nil {
log.Println(err.Error())
} else {
c.Data(statusCode, "application/json", body)
}
2024-05-29 17:33:36 +01:00
}
func HandleGetUserCert(c *gin.Context, keyStore cryptoUtils.KeyStore) {
certificateOwnerUID := c.Param("user")
if certificateOwnerUID == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "User does not exist"})
return
}
2024-05-29 17:33:36 +01:00
statusCode, body, err := forwardGetUserCert(keyStore.GetGatewayOutgoingTLSConfig(), certificateOwnerUID)
if err != nil {
log.Println(err.Error())
} else {
c.Data(statusCode, "application/json", body)
}
2024-05-29 17:33:36 +01:00
}
func HandleSendMessage(c *gin.Context, keyStore cryptoUtils.KeyStore) {
sendMsg := new(protocol.SendMsg)
err := c.BindJSON(sendMsg)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Request body is not a SendMsg"})
return
}
uid, exists := c.Get("uid")
if !exists {
c.JSON(http.StatusBadRequest, gin.H{"error": "User does not exist"})
return
}
2024-05-29 17:33:36 +01:00
uidString := uid.(string)
statusCode, body, err := forwardSendMessage(keyStore.GetGatewayOutgoingTLSConfig(), uidString, *sendMsg)
if err != nil {
log.Println(err.Error())
} else {
c.Data(statusCode, "application/json", body)
}
2024-05-29 17:33:36 +01:00
}
func HandleRegister(c *gin.Context, dataStore DataStore, keyStore cryptoUtils.KeyStore) {
postRegister := new(protocol.PostRegister)
err := c.BindJSON(postRegister)
if err != nil {
2024-05-30 15:48:28 +01:00
c.JSON(http.StatusBadRequest, gin.H{"error": "Request body is not a PostRegister"})
return
}
userCert, err := x509.ParseCertificate(postRegister.Certificate)
if err != nil {
2024-05-30 15:48:28 +01:00
c.JSON(http.StatusBadRequest, gin.H{"error": "User certificate is invalid"})
return
}
2024-05-30 15:48:28 +01:00
err = keyStore.CheckCert(userCert, postRegister.UID, "MSG SERVICE")
if err != nil {
2024-05-30 15:48:28 +01:00
c.JSON(http.StatusBadRequest, gin.H{"error": "User certificate is invalid, not trusted, belongs to another user or has incorrect usage field"})
return
}
hashedPassword, err := HashPassword(postRegister.Password)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not hash password"})
return
}
err = dataStore.InsertUser(postRegister.UID, hashedPassword)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not insert user into DB"})
return
}
storeUserCertificate := protocol.NewStoreUserCert(userCert.Raw)
statusCode, body, err := forwardStoreUserCert(keyStore.GetGatewayOutgoingTLSConfig(), postRegister.UID, storeUserCertificate)
if err != nil {
log.Println(err.Error())
} else {
c.Data(statusCode, "application/json", body)
}
2024-05-29 17:33:36 +01:00
}
func HandleLogin(c *gin.Context, dataStore DataStore, keyStore cryptoUtils.KeyStore) {
postLogin := new(protocol.PostLogin)
err := c.BindJSON(postLogin)
if err != nil {
c.AbortWithStatus(http.StatusBadRequest)
}
hashedPassword, err := dataStore.GetPassword(postLogin.UID)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user id or password"})
return
}
err = CheckPassword(hashedPassword, postLogin.Password)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user id or password"})
return
}
2024-05-30 15:48:28 +01:00
jwToken, err := GenerateJWT(postLogin.UID)
2024-05-30 15:48:28 +01:00
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to create token"})
return
2024-05-30 15:48:28 +01:00
}
//Send token to user
c.JSON(http.StatusOK, gin.H{"token": jwToken})
2024-05-29 17:33:36 +01:00
}
func AuthMiddleware(c *gin.Context) {
token := c.GetHeader("Token")
if token == "" {
2024-05-30 15:48:28 +01:00
c.JSON(http.StatusUnauthorized, gin.H{"error": "No authentication token provided"})
c.Abort()
return
2024-05-30 15:48:28 +01:00
}
uid, err := ValidateJWT(token)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is invalid or has expired"})
c.Abort()
return
2024-05-30 15:48:28 +01:00
}
c.Set("uid", uid)
c.Next()
}
func Run() {
dataStore, err := OpenDB()
if err != nil {
log.Fatalln("Error opening the database")
}
defer dataStore.db.Close()
passphrase := readStdin("Insert keystore passphrase")
keyStore, err := cryptoUtils.LoadKeyStore("certs/gateway/gateway.p12", passphrase)
if err != nil {
log.Fatalln(err.Error())
}
router := gin.Default()
auth := router.Group("/", func(c *gin.Context) {
AuthMiddleware(c)
})
2024-05-29 17:33:36 +01:00
auth.GET("/message/:num", func(c *gin.Context) {
HandleGetMessage(c, keyStore)
2024-05-29 17:33:36 +01:00
})
auth.GET("/queue", func(c *gin.Context) {
HandleGetUnreadMsgsInfo(c, keyStore)
2024-05-29 17:33:36 +01:00
})
auth.GET("/cert/:user", func(c *gin.Context) {
HandleGetUserCert(c, keyStore)
2024-05-29 17:33:36 +01:00
})
auth.POST("/message", func(c *gin.Context) {
HandleSendMessage(c, keyStore)
2024-05-29 17:33:36 +01:00
})
router.POST("/register", func(c *gin.Context) {
HandleRegister(c, dataStore, keyStore)
})
router.POST("/login", func(c *gin.Context) {
HandleLogin(c, dataStore, keyStore)
})
2024-05-29 17:33:36 +01:00
server := http.Server{
Addr: "0.0.0.0:9090",
2024-05-29 17:33:36 +01:00
Handler: router,
2024-05-30 15:48:28 +01:00
TLSConfig: keyStore.GetGatewayIncomingTLSConfig(),
2024-05-29 17:33:36 +01:00
}
2024-05-30 15:48:28 +01:00
err = server.ListenAndServeTLS("", "")
if err != nil {
log.Fatal(err.Error())
}
}