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

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

View File

@ -0,0 +1,30 @@
name: build-docker-imge
on:
- push
- pull_request
jobs:
build:
name: Build the docker container
runs-on: ubuntu-latest
steps:
- name: "Print env"
run: echo WORKSPACE
- name: "Git clone"
run: git clone ${{ gitea.server_url }}/${{ gitea.repository }}.git .
- name: "LS"
run: ls -lisa
- name: "LS ECHO"
run: echo "$(ls)" "${{ gitea.repository }}" "${{ gitea.ref_name }}" "${{ gitea.sha }}"
- name: "Git checkout"
run: git checkout "${{ gitea.sha }}"
- uses: aevea/action-kaniko@master
name: Run Kaniko to build our docker container.
with:
image: kocoded/gitea-workspaces/szuntis-backend-main
tag: ${{ gitea.workflow_sha }}
tag_with_latest: true
registry: git.kocoder.xyz
username: ${{ secrets.CI_RUNNER_USER }}
password: ${{ secrets.CI_RUNNER_TOKEN }}
build_file: DOCKERFILE

27
DOCKERFILE Normal file
View File

@ -0,0 +1,27 @@
# syntax=docker/dockerfile:1
FROM golang:1.21.0
# Set destination for COPY
WORKDIR /app
# Download Go modules
COPY go.mod go.sum ./
RUN go mod download
# Copy the source code. Note the slash at the end, as explained in
# https://docs.docker.com/engine/reference/builder/#copy
COPY *.go ./
# Build
RUN CGO_ENABLED=0 GOOS=linux go build -o /szuntis-backend
# Optional:
# To bind to a TCP port, runtime parameters must be supplied to the docker command.
# But we can document in the Dockerfile what ports
# the application is going to listen on by default.
# https://docs.docker.com/engine/reference/builder/#expose
EXPOSE 3000
# Run
CMD ["/szuntis-backend"]

78
auth/memory.go Normal file
View File

@ -0,0 +1,78 @@
package auth
import (
"context"
"errors"
"git.kocoder.xyz/kocoded/szuntis-backend/repository"
"github.com/google/uuid"
"golang.org/x/crypto/bcrypt"
)
type authRepository struct {
users map[string]repository.User //map[LoginName]User
sessions map[uuid.UUID]string //map[sessionToken]email
}
func NewMemeoryAuthRepository() repository.AuthRepository {
return &authRepository{
users: map[string]repository.User{},
sessions: map[uuid.UUID]string{},
}
}
func (a *authRepository) GetUserByToken(ctx context.Context, userId uuid.UUID) (repository.User, error) {
ln, ok := a.sessions[userId]
if !ok {
return repository.User{}, errors.New("you have to be logged in to do that")
}
u, ok := a.users[ln]
if !ok {
return repository.User{}, errors.New("you have to be logged in to do that")
}
return u, nil
}
func (a *authRepository) Login(ctx context.Context, loginParams *repository.LoginParams) (uuid.UUID, error) {
u, ok := a.users[loginParams.LoginName]
if !ok {
return uuid.Nil, errors.New("couldn't log user in")
}
if err := bcrypt.CompareHashAndPassword(u.Password, []byte(loginParams.Password)); err != nil {
return uuid.Nil, errors.New("couldn't log user in")
}
sessionToken, err := uuid.NewUUID()
if err != nil {
return uuid.Nil, errors.New("couldn't log user in")
}
a.sessions[sessionToken] = loginParams.LoginName
return sessionToken, nil
}
func (a *authRepository) Register(ctx context.Context, registerParams *repository.RegisterParams) (bool, error) {
if _, ok := a.users[registerParams.LoginName]; ok {
return false, errors.New("couldn't register user")
}
res, err := bcrypt.GenerateFromPassword([]byte(registerParams.Password), 7)
if err != nil {
return false, errors.New("couldn't register user")
}
u := repository.User{
Username: registerParams.Username,
FirstName: registerParams.FirstName,
LastName: registerParams.LastName,
LoginName: registerParams.LoginName,
EmailAddress: registerParams.EmailAddress,
Password: res,
}
a.users[registerParams.LoginName] = u
return true, nil
}

59
authentication/types.go Normal file
View File

@ -0,0 +1,59 @@
package authentication
import (
"time"
"gorm.io/gorm"
)
type UserAccount struct {
gorm.Model
Username string
FirstName string
LastName string
}
type HashingAlgorithm struct {
gorm.Model
AlgoritmName string
}
type EmailValidationStatus struct {
gorm.Model
StatusDescription string
}
type UserLoginData struct {
gorm.Model
LoginName string
PasswordHash []byte
PassswordSalt []byte
EmailAddress string
ConfirmationToken string
TokenGenerationTime time.Time
PasswordRecoveryToken string
RecoveryTokenTime time.Time
EmailValidationStatusId int
EmailValidationStatus EmailValidationStatus
UserAccountID int
UserAccount UserAccount
HashingAlgorithmID int
HashingAlgorithm HashingAlgorithm
}
type UserLoginDataExternal struct {
gorm.Model
ExternalProviderToken string
ExternalProviderID int
ExternalProvider ExternalProvider
}
type ExternalProvider struct {
gorm.Model
ProviderName string
WSEndPoint string
}

33
go.mod Normal file
View File

@ -0,0 +1,33 @@
module git.kocoder.xyz/kocoded/szuntis-backend
go 1.23.0
require (
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/fasthttp/websocket v1.5.8 // indirect
github.com/gofiber/contrib/websocket v1.3.2 // indirect
github.com/gofiber/fiber/v2 v2.52.5 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgx/v5 v5.5.5 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/klauspost/compress v1.17.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.52.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.23.0 // indirect
golang.org/x/text v0.17.0 // indirect
gorm.io/driver/postgres v1.5.9 // indirect
gorm.io/gorm v1.25.11 // indirect
)

81
go.sum Normal file
View File

@ -0,0 +1,81 @@
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fasthttp/websocket v1.5.8 h1:k5DpirKkftIF/w1R8ZzjSgARJrs54Je9YJK37DL/Ah8=
github.com/fasthttp/websocket v1.5.8/go.mod h1:d08g8WaT6nnyvg9uMm8K9zMYyDjfKyj3170AtPRuVU0=
github.com/gofiber/contrib/websocket v1.3.2 h1:AUq5PYeKwK50s0nQrnluuINYeep1c4nRCJ0NWsV3cvg=
github.com/gofiber/contrib/websocket v1.3.2/go.mod h1:07u6QGMsvX+sx7iGNCl5xhzuUVArWwLQ3tBIH24i+S8=
github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511 h1:KanIMPX0QdEdB4R3CiimCAbxFrhB3j7h0/OvpYGVQa8=
github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0=
github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ=
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8=
gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg=
gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=

28
main.go Normal file
View File

@ -0,0 +1,28 @@
package main
import (
"log"
"git.kocoder.xyz/kocoded/szuntis-backend/auth"
"git.kocoder.xyz/kocoded/szuntis-backend/middleware"
"git.kocoder.xyz/kocoded/szuntis-backend/router"
"github.com/gofiber/fiber/v2"
)
func main() {
// dsn := "postgresql://app1:p5ohxMubZHhzsvSQevlFfw@cockroach-db-1-11072.7tc.aws-eu-central-1.cockroachlabs.cloud:26257/defaultdb?sslmode=verify-full"
// db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
// if err != nil {
// log.Fatal("failed to connect database", err)
// }
ar := auth.NewMemeoryAuthRepository()
app := fiber.New()
api := app.Group("/api")
router.NewAuthRouter(ar, middleware.NewAuthMiddleware(ar), api.Group("auth"))
router.NewWebSocketRouter(middleware.NewWsMiddleware(), api.Group("web"))
api.Use(middleware.NewWsMiddleware().IsWebscoketUpgrade)
log.Fatal(app.Listen(":3000"))
}

41
middleware/auth.go Normal file
View File

@ -0,0 +1,41 @@
package middleware
import (
"fmt"
"git.kocoder.xyz/kocoded/szuntis-backend/repository"
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
)
type AuthMiddleware struct {
ar repository.AuthRepository
}
func NewAuthMiddleware(ar repository.AuthRepository) AuthMiddleware {
return AuthMiddleware{
ar: ar,
}
}
func (am AuthMiddleware) IsAuthenticated(ctx *fiber.Ctx) error {
val := ctx.Cookies("session-token")
if val == "" {
fmt.Println(1)
return ctx.SendStatus(fiber.StatusUnauthorized)
}
token, err := uuid.Parse(val)
if err != nil {
fmt.Println(2)
return ctx.SendStatus(fiber.StatusUnauthorized)
}
u, err := am.ar.GetUserByToken(ctx.Context(), token)
if err != nil {
fmt.Println(3)
return ctx.SendStatus(fiber.StatusUnauthorized)
}
fmt.Println(4)
ctx.Locals("user", u)
return ctx.Next()
}

20
middleware/ws.go Normal file
View File

@ -0,0 +1,20 @@
package middleware
import (
"github.com/gofiber/contrib/websocket"
"github.com/gofiber/fiber/v2"
)
type WsMiddleware struct {
}
func NewWsMiddleware() WsMiddleware {
return WsMiddleware{}
}
func (wm WsMiddleware) IsWebscoketUpgrade(ctx *fiber.Ctx) error {
if websocket.IsWebSocketUpgrade(ctx) {
return ctx.Next()
}
return ctx.SendStatus(fiber.StatusUpgradeRequired)
}

36
repository/auth.go Normal file
View File

@ -0,0 +1,36 @@
package repository
import (
"context"
"github.com/google/uuid"
)
type LoginParams struct {
LoginName string `json:"loginname"`
Password string `json:"password"`
}
type RegisterParams struct {
Username string `json:"username"`
FirstName string `json:"firstname"`
LastName string `json:"lastname"`
LoginName string `json:"loginname"`
EmailAddress string `json:"emailaddress"`
Password string `json:"password"`
}
type User struct {
Username string `json:"username"`
FirstName string `json:"firstname"`
LastName string `json:"lastname"`
LoginName string `json:"loginname"`
EmailAddress string `json:"email"`
Password []byte
}
type AuthRepository interface {
GetUserByToken(ctx context.Context, userId uuid.UUID) (User, error)
Login(ctx context.Context, loginParams *LoginParams) (uuid.UUID, error)
Register(ctx context.Context, registerParams *RegisterParams) (bool, error)
}

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)
}
}
}

1
tmp/build-errors.log Normal file
View File

@ -0,0 +1 @@
exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1

BIN
tmp/main Executable file

Binary file not shown.