Compare commits
13 commits
d023bb0adf
...
1c5cbd768d
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1c5cbd768d | ||
![]() |
bd434c3da7 | ||
![]() |
c9406b8e50 | ||
![]() |
9b9f6dd962 | ||
![]() |
18eefab292 | ||
![]() |
3adf0b7ef5 | ||
![]() |
a202eaa610 | ||
![]() |
acff254aa5 | ||
![]() |
3175c62e6d | ||
![]() |
b31349ec37 | ||
![]() |
4cfb227a1e | ||
![]() |
524baf90d2 | ||
![]() |
c5f0bc509e |
9 changed files with 115 additions and 7 deletions
11
Justfile
11
Justfile
|
@ -11,7 +11,7 @@ start-release: build-container-release remove-podman-containers
|
||||||
# Removes and stops any containers related to the project
|
# Removes and stops any containers related to the project
|
||||||
[private]
|
[private]
|
||||||
remove-podman-containers:
|
remove-podman-containers:
|
||||||
podman container rm -f ttime
|
podman container rm -fi ttime
|
||||||
|
|
||||||
# Saves the release container to a tarball, pigz is just gzip but multithreaded
|
# Saves the release container to a tarball, pigz is just gzip but multithreaded
|
||||||
save-release: build-container-release
|
save-release: build-container-release
|
||||||
|
@ -23,14 +23,14 @@ load-release file:
|
||||||
|
|
||||||
# Tests every part of the project
|
# Tests every part of the project
|
||||||
testall:
|
testall:
|
||||||
cd backend && make test
|
|
||||||
cd backend && make lint
|
|
||||||
cd frontend && npm test
|
cd frontend && npm test
|
||||||
cd frontend && npm run lint
|
cd frontend && npm run lint
|
||||||
|
cd backend && make test
|
||||||
|
cd backend && make lint
|
||||||
|
|
||||||
# Cleans up everything related to the project
|
# Cleans up everything related to the project
|
||||||
clean: remove-podman-containers
|
clean: remove-podman-containers
|
||||||
podman image rm -f ttime-server
|
podman image rm -fi ttime-server
|
||||||
rm -rf frontend/dist
|
rm -rf frontend/dist
|
||||||
rm -rf frontend/node_modules
|
rm -rf frontend/node_modules
|
||||||
rm -f ttime-server.tar.gz
|
rm -f ttime-server.tar.gz
|
||||||
|
@ -41,3 +41,6 @@ clean: remove-podman-containers
|
||||||
[confirm]
|
[confirm]
|
||||||
podman-clean:
|
podman-clean:
|
||||||
podman system reset --force
|
podman system reset --force
|
||||||
|
|
||||||
|
install-linter:
|
||||||
|
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.56.2
|
||||||
|
|
41
Makefile
Normal file
41
Makefile
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# Builds a release container
|
||||||
|
build-container-release:
|
||||||
|
podman build -t ttime-server -f container/Containerfile .
|
||||||
|
|
||||||
|
# Builds a release container and runs it
|
||||||
|
start-release: build-container-release remove-podman-containers
|
||||||
|
podman run -d -e DATABASE_URL=sqlite:release.db -p 8080:8080 --name ttime ttime-server
|
||||||
|
@echo "Started production ttime-server on http://localhost:8080"
|
||||||
|
|
||||||
|
# Removes and stops any containers related to the project
|
||||||
|
remove-podman-containers:
|
||||||
|
podman container rm -fi ttime
|
||||||
|
|
||||||
|
# Tests every part of the project
|
||||||
|
testall:
|
||||||
|
cd frontend && npm test
|
||||||
|
cd frontend && npm run lint
|
||||||
|
cd backend && make test
|
||||||
|
cd backend && make lint
|
||||||
|
|
||||||
|
# Cleans up everything related to the project
|
||||||
|
clean: remove-podman-containers
|
||||||
|
podman image rm -fi ttime-server
|
||||||
|
rm -rf frontend/dist
|
||||||
|
rm -rf frontend/node_modules
|
||||||
|
rm -f ttime-server.tar.gz
|
||||||
|
cd backend && make clean
|
||||||
|
@echo "Cleaned up!"
|
||||||
|
|
||||||
|
# Cleans up everything related to podman, not just the project. Make sure you understand what this means.
|
||||||
|
podman-clean:
|
||||||
|
podman system reset --force
|
||||||
|
|
||||||
|
# Installs the linter, which is not included in the ubuntu repo
|
||||||
|
install-linter:
|
||||||
|
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.56.2
|
||||||
|
|
||||||
|
# This installs just, a make alternative, which is slightly more ergonomic to use
|
||||||
|
install-just:
|
||||||
|
@echo "Installing just"
|
||||||
|
@curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin
|
|
@ -59,7 +59,7 @@ My recommendation would be to make WSL your primary development environment if y
|
||||||
You should consult the [WSL documentation](https://docs.microsoft.com/en-us/windows/wsl/install), but for any recent version of windows, installation essentially boils down to running the following command in **PowerShell as an administrator**:
|
You should consult the [WSL documentation](https://docs.microsoft.com/en-us/windows/wsl/install), but for any recent version of windows, installation essentially boils down to running the following command in **PowerShell as an administrator**:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
wsl --install
|
wsl --install -d Ubuntu-22.04 # To get a somewhat recent version of Go
|
||||||
```
|
```
|
||||||
|
|
||||||
If you get any errors related to virtualization, you will need to enable virtualization in the BIOS. This is a common issue, and you can find a guide for your specific motherboard online. This is a one-time operation and will not affect your windows installation. This setting is usually called "VT-x" or "AMD-V" and is usually found in the CPU settings. If you can't find it, shoot me a message and I'll find it for you.
|
If you get any errors related to virtualization, you will need to enable virtualization in the BIOS. This is a common issue, and you can find a guide for your specific motherboard online. This is a one-time operation and will not affect your windows installation. This setting is usually called "VT-x" or "AMD-V" and is usually found in the CPU settings. If you can't find it, shoot me a message and I'll find it for you.
|
||||||
|
|
|
@ -69,3 +69,7 @@ lint:
|
||||||
|
|
||||||
# Default target
|
# Default target
|
||||||
default: build
|
default: build
|
||||||
|
|
||||||
|
install-just:
|
||||||
|
@echo "Installing just"
|
||||||
|
@curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin
|
||||||
|
|
|
@ -10,8 +10,8 @@ require (
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/MicahParks/keyfunc/v2 v2.1.0 // indirect
|
github.com/MicahParks/keyfunc/v2 v2.1.0 // indirect
|
||||||
github.com/gofiber/contrib/jwt v1.0.8 // indirect
|
github.com/gofiber/contrib/jwt v1.0.8
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||||
)
|
)
|
||||||
|
|
||||||
// These are all for fiber
|
// These are all for fiber
|
||||||
|
|
|
@ -14,9 +14,13 @@ import (
|
||||||
type Database interface {
|
type Database interface {
|
||||||
AddUser(username string, password string) error
|
AddUser(username string, password string) error
|
||||||
RemoveUser(username string) error
|
RemoveUser(username string) error
|
||||||
|
PromoteToAdmin(username string) error
|
||||||
GetUserId(username string) (int, error)
|
GetUserId(username string) (int, error)
|
||||||
AddProject(name string, description string, username string) error
|
AddProject(name string, description string, username string) error
|
||||||
Migrate(dirname string) error
|
Migrate(dirname string) error
|
||||||
|
// AddTimeReport(projectname string, start time.Time, end time.Time) error
|
||||||
|
// AddUserToProject(username string, projectname string) error
|
||||||
|
// ChangeUserRole(username string, projectname string, role string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// This struct is a wrapper type that holds the database connection
|
// This struct is a wrapper type that holds the database connection
|
||||||
|
@ -30,6 +34,11 @@ var scripts embed.FS
|
||||||
|
|
||||||
const userInsert = "INSERT INTO users (username, password) VALUES (?, ?)"
|
const userInsert = "INSERT INTO users (username, password) VALUES (?, ?)"
|
||||||
const projectInsert = "INSERT INTO projects (name, description, user_id) SELECT ?, ?, id FROM users WHERE username = ?"
|
const projectInsert = "INSERT INTO projects (name, description, user_id) SELECT ?, ?, id FROM users WHERE username = ?"
|
||||||
|
const promoteToAdmin = "INSERT INTO site_admin (admin_id) SELECT id FROM users WHERE username = ?"
|
||||||
|
|
||||||
|
// const addTimeReport = ""
|
||||||
|
// const addUserToProject = ""
|
||||||
|
// const changeUserRole = ""
|
||||||
|
|
||||||
// DbConnect connects to the database
|
// DbConnect connects to the database
|
||||||
func DbConnect(dbpath string) Database {
|
func DbConnect(dbpath string) Database {
|
||||||
|
@ -48,6 +57,18 @@ func DbConnect(dbpath string) Database {
|
||||||
return &Db{db}
|
return &Db{db}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func (d *Db) AddTimeReport(projectname string, start time.Time, end time.Time) error {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (d *Db) AddUserToProject(username string, projectname string) error {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (d *Db) ChangeUserRole(username string, projectname string, role string) error {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
// AddUser adds a user to the database
|
// AddUser adds a user to the database
|
||||||
func (d *Db) AddUser(username string, password string) error {
|
func (d *Db) AddUser(username string, password string) error {
|
||||||
_, err := d.Exec(userInsert, username, password)
|
_, err := d.Exec(userInsert, username, password)
|
||||||
|
@ -60,6 +81,11 @@ func (d *Db) RemoveUser(username string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Db) PromoteToAdmin(username string) error {
|
||||||
|
_, err := d.Exec(promoteToAdmin, username)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Db) GetUserId(username string) (int, error) {
|
func (d *Db) GetUserId(username string) (int, error) {
|
||||||
var id int
|
var id int
|
||||||
err := d.Get(&id, "SELECT id FROM users WHERE username = ?", username)
|
err := d.Get(&id, "SELECT id FROM users WHERE username = ?", username)
|
||||||
|
|
|
@ -74,3 +74,32 @@ func TestDbRemoveUser(t *testing.T) {
|
||||||
t.Error("RemoveUser failed:", err)
|
t.Error("RemoveUser failed:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPromoteToAdmin(t *testing.T) {
|
||||||
|
db, err := setupState()
|
||||||
|
if err != nil {
|
||||||
|
t.Error("setupState failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.AddUser("test", "password")
|
||||||
|
if err != nil {
|
||||||
|
t.Error("AddUser failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.PromoteToAdmin("test")
|
||||||
|
if err != nil {
|
||||||
|
t.Error("PromoteToAdmin failed:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// func TestAddTimeReport(t *testing.T) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func TestAddUserToProject(t *testing.T) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func TestChangeUserRole(t *testing.T) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
4
backend/internal/database/migrations/0060_site_admin.sql
Normal file
4
backend/internal/database/migrations/0060_site_admin.sql
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
CREATE TABLE IF NOT EXISTS site_admin (
|
||||||
|
admin_id INTEGER PRIMARY KEY,
|
||||||
|
FOREIGN KEY (admin_id) REFERENCES users (id) ON DELETE CASCADE
|
||||||
|
)
|
|
@ -115,6 +115,7 @@ func (gs *GState) Login(c *fiber.Ctx) error {
|
||||||
|
|
||||||
// LoginRenew is a simple handler that renews the token
|
// LoginRenew is a simple handler that renews the token
|
||||||
func (gs *GState) LoginRenew(c *fiber.Ctx) error {
|
func (gs *GState) LoginRenew(c *fiber.Ctx) error {
|
||||||
|
// For testing: curl localhost:3000/restricted -H "Authorization: Bearer <token>"
|
||||||
user := c.Locals("user").(*jwt.Token)
|
user := c.Locals("user").(*jwt.Token)
|
||||||
claims := user.Claims.(jwt.MapClaims)
|
claims := user.Claims.(jwt.MapClaims)
|
||||||
claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
|
claims["exp"] = time.Now().Add(time.Hour * 72).Unix()
|
||||||
|
|
Loading…
Reference in a new issue