234 lines
5.8 KiB
Go
234 lines
5.8 KiB
Go
package gateway
|
|
|
|
import (
|
|
"PD2/internal/protocol"
|
|
"PD2/internal/utils/cryptoUtils"
|
|
"crypto/x509"
|
|
"log"
|
|
"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)
|
|
|
|
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)
|
|
}
|
|
}
|
|
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)
|
|
}
|
|
|
|
}
|
|
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
|
|
}
|
|
|
|
statusCode, body, err := forwardGetUserCert(keyStore.GetGatewayOutgoingTLSConfig(), certificateOwnerUID)
|
|
if err != nil {
|
|
log.Println(err.Error())
|
|
} else {
|
|
c.Data(statusCode, "application/json", body)
|
|
}
|
|
}
|
|
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
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
func HandleRegister(c *gin.Context, dataStore DataStore, keyStore cryptoUtils.KeyStore) {
|
|
postRegister := new(protocol.PostRegister)
|
|
err := c.BindJSON(postRegister)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Request body is not a PostRegister"})
|
|
return
|
|
}
|
|
|
|
userCert, err := x509.ParseCertificate(postRegister.Certificate)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "User certificate is invalid"})
|
|
return
|
|
}
|
|
|
|
err = keyStore.CheckCert(userCert, postRegister.UID, "MSG SERVICE")
|
|
if err != nil {
|
|
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)
|
|
}
|
|
|
|
}
|
|
|
|
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
|
|
}
|
|
jwToken, err := GenerateJWT(postLogin.UID)
|
|
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to create token"})
|
|
return
|
|
}
|
|
//Send token to user
|
|
c.JSON(http.StatusOK, gin.H{"token": jwToken})
|
|
}
|
|
|
|
func AuthMiddleware(c *gin.Context) {
|
|
token := c.GetHeader("Token")
|
|
if token == "" {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "No authentication token provided"})
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
uid, err := ValidateJWT(token)
|
|
if err != nil {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Token is invalid or has expired"})
|
|
c.Abort()
|
|
return
|
|
}
|
|
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)
|
|
})
|
|
|
|
auth.GET("/message/:num", func(c *gin.Context) {
|
|
HandleGetMessage(c, keyStore)
|
|
})
|
|
|
|
auth.GET("/queue", func(c *gin.Context) {
|
|
HandleGetUnreadMsgsInfo(c, keyStore)
|
|
})
|
|
|
|
auth.GET("/cert/:user", func(c *gin.Context) {
|
|
HandleGetUserCert(c, keyStore)
|
|
})
|
|
|
|
auth.POST("/message", func(c *gin.Context) {
|
|
HandleSendMessage(c, keyStore)
|
|
})
|
|
|
|
router.POST("/register", func(c *gin.Context) {
|
|
HandleRegister(c, dataStore, keyStore)
|
|
})
|
|
|
|
router.POST("/login", func(c *gin.Context) {
|
|
HandleLogin(c, dataStore, keyStore)
|
|
})
|
|
|
|
server := http.Server{
|
|
Addr: "0.0.0.0:9090",
|
|
Handler: router,
|
|
TLSConfig: keyStore.GetGatewayIncomingTLSConfig(),
|
|
}
|
|
|
|
err = server.ListenAndServeTLS("", "")
|
|
if err != nil {
|
|
log.Fatal(err.Error())
|
|
}
|
|
}
|