172 lines
4.1 KiB
Go
172 lines
4.1 KiB
Go
package server
|
|
|
|
import (
|
|
"PD2/internal/protocol"
|
|
"PD2/internal/utils/cryptoUtils"
|
|
"crypto/x509"
|
|
"log"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func HandleGetUserCert(c *gin.Context, dataStore DataStore) {
|
|
user := c.Param("user")
|
|
userCertPacket, err := dataStore.GetUserCertificate(user)
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
|
} else {
|
|
c.JSON(http.StatusOK, userCertPacket)
|
|
}
|
|
}
|
|
|
|
func HandleStoreUserCert(c *gin.Context, dataStore DataStore) {
|
|
user := c.Param("user")
|
|
var storeUserCert protocol.StoreUserCert
|
|
if err := c.Bind(storeUserCert); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
userCert, err := x509.ParseCertificate(storeUserCert.Certificate)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "User certificate is invalid"})
|
|
return
|
|
}
|
|
|
|
err = dataStore.storeUserCertIfNotExists(user, *userCert)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "User already has a certificate stored in the database"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{})
|
|
}
|
|
|
|
func HandleGetUnreadMsgsInfo(c *gin.Context, dataStore DataStore) {
|
|
user := c.Param("user")
|
|
pageStr := c.Query("page")
|
|
pagesizeStr := c.Query("pagesize")
|
|
|
|
var page int
|
|
var err error
|
|
if pageStr != "" {
|
|
page, err = strconv.Atoi(pageStr)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Page is not a number"})
|
|
}
|
|
} else {
|
|
page = 1
|
|
}
|
|
var pagesize int
|
|
if pagesizeStr != "" {
|
|
pagesize, err = strconv.Atoi(pagesizeStr)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Pagesize is not a number"})
|
|
}
|
|
} else {
|
|
pagesize = 5
|
|
}
|
|
|
|
if page <= 0 || pagesize <= 0 {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Page and Pagesize need to be >= 1"})
|
|
return
|
|
}
|
|
unreadMsgsInfo, err := dataStore.GetUnreadMsgsInfo(user, page, pagesize)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, unreadMsgsInfo)
|
|
}
|
|
|
|
func HandleSendMessage(c *gin.Context, dataStore DataStore) {
|
|
sender := c.Param("user")
|
|
|
|
var message protocol.SendMsg
|
|
if err := c.BindJSON(message); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
if message.ToUID == sender {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Message sender and receiver cannot be the same user"})
|
|
return
|
|
}
|
|
if !dataStore.userExists(message.ToUID) {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Message receiver does not exist"})
|
|
return
|
|
}
|
|
err := dataStore.AddMessageToQueue(sender, message)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, nil)
|
|
}
|
|
|
|
func HandleGetMessage(c *gin.Context, dataStore DataStore) {
|
|
user := c.Param("user")
|
|
numStr := c.Param("num")
|
|
num, err := strconv.Atoi(numStr)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
}
|
|
|
|
message, reportError := dataStore.GetMessage(user, num)
|
|
if reportError != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
|
}
|
|
dataStore.MarkMessageInQueueAsRead(user, num)
|
|
c.JSON(http.StatusOK, message)
|
|
}
|
|
|
|
func Run() {
|
|
//Open connection to DB
|
|
dataStore, err := OpenDB()
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
defer dataStore.db.Close()
|
|
|
|
//Read server keystore
|
|
keystorePassphrase := readStdin("Insert keystore passphrase")
|
|
serverKeyStore, err := cryptoUtils.LoadKeyStore("certs/server/server.p12", keystorePassphrase)
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
|
|
r := gin.Default()
|
|
|
|
r.GET("/message/:user/:num", func(c *gin.Context) {
|
|
HandleGetMessage(c, dataStore)
|
|
})
|
|
|
|
r.GET("/queue/:user", func(c *gin.Context) {
|
|
HandleGetUnreadMsgsInfo(c, dataStore)
|
|
})
|
|
|
|
r.GET("/cert/:user", func(c *gin.Context) {
|
|
HandleGetUserCert(c, dataStore)
|
|
})
|
|
|
|
r.POST("/message/:user", func(c *gin.Context) {
|
|
HandleSendMessage(c, dataStore)
|
|
})
|
|
|
|
r.POST("/cert/:user", func(c *gin.Context) {
|
|
HandleStoreUserCert(c, dataStore)
|
|
})
|
|
|
|
server := http.Server{
|
|
Addr: "0.0.0.0:8080",
|
|
Handler: r,
|
|
//TODO: Verify if it's the gateway
|
|
TLSConfig: serverKeyStore.GetServerTLSConfig(),
|
|
}
|
|
|
|
err = server.ListenAndServeTLS("", "")
|
|
if err != nil {
|
|
log.Fatal(err.Error())
|
|
}
|
|
}
|