Experiment with Authentication and Websockets
Some checks failed
build-docker-imge / Build the docker container (push) Failing after 2m24s

This commit is contained in:
2024-08-27 18:20:17 +02:00
parent 768c178218
commit 1e41dd833f
16 changed files with 687 additions and 0 deletions

70
router/auth.go Normal file
View File

@ -0,0 +1,70 @@
package router
import (
"errors"
"git.kocoder.xyz/kocoded/szuntis-backend/middleware"
"git.kocoder.xyz/kocoded/szuntis-backend/repository"
"github.com/gofiber/fiber/v2"
)
type AuthRouter struct {
authRepo repository.AuthRepository
}
func NewAuthRouter(authRepo repository.AuthRepository, authMiddleware middleware.AuthMiddleware, auth fiber.Router) error {
router := &AuthRouter{authRepo: authRepo}
auth.Post("/login", router.HandleLogin)
auth.Post("/register", router.HandleRegister)
auth.Get("/username", authMiddleware.IsAuthenticated, router.GetName)
return nil
}
func (ar AuthRouter) GetName(ctx *fiber.Ctx) error {
user, ok := ctx.Locals("user").(repository.User)
if !ok {
return ctx.SendStatus(fiber.StatusUnauthorized)
}
return ctx.SendString(user.Username)
}
func (ar AuthRouter) HandleLogin(ctx *fiber.Ctx) error {
params := repository.LoginParams{}
if err := ctx.BodyParser(&params); err != nil {
return err
}
token, err := ar.authRepo.Login(ctx.Context(), &params)
if err != nil {
return err
}
cookie := &fiber.Cookie{
Name: "session-token",
Value: token.String(),
MaxAge: 5,
}
ctx.Cookie(cookie)
return ctx.SendString("Success!!!!!")
}
func (ar AuthRouter) HandleRegister(ctx *fiber.Ctx) error {
params := repository.RegisterParams{}
if err := ctx.BodyParser(&params); err != nil {
return err
}
ok, err := ar.authRepo.Register(ctx.Context(), &params)
if err != nil {
return err
}
if ok {
return ctx.SendString("User registered successfully, please check your inbox & proceed to login.")
}
return errors.New("")
}

100
router/home.html Normal file
View File

@ -0,0 +1,100 @@
<!-- See https://github.com/gorilla/websocket/blob/master/examples/chat/home.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Chat Example</title>
<script type="text/javascript">
window.onload = function () {
var conn;
var msg = document.getElementById("msg");
var log = document.getElementById("log");
function appendLog(item) {
var doScroll = log.scrollTop > log.scrollHeight - log.clientHeight - 1;
log.appendChild(item);
if (doScroll) {
log.scrollTop = log.scrollHeight - log.clientHeight;
}
}
document.getElementById("form").onsubmit = function () {
if (!conn) {
return false;
}
if (!msg.value) {
return false;
}
conn.send(msg.value);
msg.value = "";
return false;
};
if (window["WebSocket"]) {
conn = new WebSocket("ws://" + document.location.host + "/api/web/ws");
conn.onclose = function (evt) {
var item = document.createElement("div");
item.innerHTML = "<b>Connection closed.</b>";
appendLog(item);
};
conn.onmessage = function (evt) {
var messages = evt.data.split('\n');
for (var i = 0; i < messages.length; i++) {
var item = document.createElement("div");
item.innerText = messages[i];
appendLog(item);
}
};
} else {
var item = document.createElement("div");
item.innerHTML = "<b>Your browser does not support WebSockets.</b>";
appendLog(item);
}
};
</script>
<style type="text/css">
html {
overflow: hidden;
}
body {
overflow: hidden;
padding: 0;
margin: 0;
width: 100%;
height: 100%;
background: gray;
}
#log {
background: white;
margin: 0;
padding: 0.5em 0.5em 0.5em 0.5em;
position: absolute;
top: 0.5em;
left: 0.5em;
right: 0.5em;
bottom: 3em;
overflow: auto;
}
#form {
padding: 0 0.5em 0 0.5em;
margin: 0;
position: absolute;
bottom: 1em;
left: 0px;
width: 100%;
overflow: hidden;
}
</style>
</head>
<body>
<div id="log"></div>
<form id="form">
<input type="submit" value="Send" />
<input type="text" id="msg" size="64" autofocus autocomplete="off" />
</form>
</body>
</html>

BIN
router/home.html.fiber.gz Normal file

Binary file not shown.

83
router/websocket.go Normal file
View File

@ -0,0 +1,83 @@
package router
import (
"fmt"
"git.kocoder.xyz/kocoded/szuntis-backend/middleware"
"github.com/gofiber/contrib/websocket"
"github.com/gofiber/fiber/v2"
)
type WebSocketRouter struct {
}
func NewWebSocketRouter(authMiddleware middleware.WsMiddleware, ws fiber.Router) error {
router := &WebSocketRouter{}
go RunHub()
ws.Get("/", func(c *fiber.Ctx) error {
return c.SendFile("/home/kocoder/szuntis-viel-zu-fiel/szuntis-backend/router/home.html", true)
})
ws.Get("/ws", authMiddleware.IsWebscoketUpgrade, websocket.New(router.Upgrade))
return nil
}
type Client struct{}
var Clients = make(map[*websocket.Conn]Client)
var Register = make(chan *websocket.Conn)
var Broadcast = make(chan string)
var Unregister = make(chan *websocket.Conn)
func RunHub() {
for {
select {
case conn := <-Register:
Clients[conn] = Client{}
fmt.Println("Connection registered")
case message := <-Broadcast:
fmt.Println("Recieved BC request: " + message)
for connection := range Clients {
if err := connection.WriteMessage(websocket.TextMessage, []byte(message)); err != nil {
fmt.Println("Write error: ", err)
Unregister <- connection
connection.WriteMessage(websocket.CloseMessage, []byte{})
connection.Close()
}
}
case connection := <-Unregister:
delete(Clients, connection)
fmt.Println("Unregistered Connection")
}
}
}
func (ws WebSocketRouter) Upgrade(c *websocket.Conn) {
defer func() {
fmt.Println(1)
Unregister <- c
c.Close()
}()
fmt.Println(2)
Register <- c
fmt.Println(12)
for {
messageType, message, err := c.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
fmt.Println("Read error: ", err)
}
fmt.Println("ASDF")
return //Call defered function to close the connection
}
if messageType == websocket.TextMessage {
fmt.Println("Messgae", string(message))
Broadcast <- string(message)
} else {
fmt.Println("Websocket message received of type: ", messageType)
}
}
}