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…
	
	Add table
		Add a link
		
	
		Reference in a new issue