From b13a8b54323db49cb72f7f248f4b867b7d993264 Mon Sep 17 00:00:00 2001 From: dDogge Date: Wed, 20 Mar 2024 00:35:37 +0100 Subject: [PATCH 1/6] Merge --- .../handlers/handlers_project_related.go | 25 +++++++++++++++++ backend/main.go | 2 ++ testing.py | 28 +++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/backend/internal/handlers/handlers_project_related.go b/backend/internal/handlers/handlers_project_related.go index 2ab5869..a92616d 100644 --- a/backend/internal/handlers/handlers_project_related.go +++ b/backend/internal/handlers/handlers_project_related.go @@ -118,6 +118,31 @@ func (gs *GState) ListAllUsersProject(c *fiber.Ctx) error { return c.Status(400).SendString("No project name provided") } + // Get the user token + userToken := c.Locals("user").(*jwt.Token) + claims := userToken.Claims.(jwt.MapClaims) + username := claims["name"].(string) + + // Check if the user is a project manager for the specified project + isManager, err := gs.Db.IsProjectManager(username, projectName) + if err != nil { + log.Info("Error checking project manager status:", err) + return c.Status(500).SendString(err.Error()) + } + + // If the user is not a project manager, check if the user is a site admin + if !isManager { + isAdmin, err := gs.Db.IsSiteAdmin(username) + if err != nil { + log.Info("Error checking admin status:", err) + return c.Status(500).SendString(err.Error()) + } + if !isAdmin { + log.Info("User is neither a project manager nor a site admin:", username) + return c.Status(403).SendString("User is neither a project manager nor a site admin") + } + } + // Get all users associated with the project from the database users, err := gs.Db.GetAllUsersProject(projectName) if err != nil { diff --git a/backend/main.go b/backend/main.go index 60027fd..b907177 100644 --- a/backend/main.go +++ b/backend/main.go @@ -97,6 +97,8 @@ func main() { server.Get("/api/getWeeklyReportsUser", gs.GetWeeklyReportsUserHandler) server.Get("api/checkIfProjectManager", gs.IsProjectManagerHandler) server.Post("/api/ProjectRoleChange", gs.ProjectRoleChange) + server.Get("/api/getUsersProject/:projectName", gs.ListAllUsersProject) + // Announce the port we are listening on and start the server err = server.Listen(fmt.Sprintf(":%d", conf.Port)) if err != nil { diff --git a/testing.py b/testing.py index 0b803f5..491419f 100644 --- a/testing.py +++ b/testing.py @@ -40,6 +40,7 @@ getUserProjectsPath = base_url + "/api/getUserProjects" getWeeklyReportsUserPath = base_url + "/api/getWeeklyReportsUser" checkIfProjectManagerPath = base_url + "/api/checkIfProjectManager" ProjectRoleChangePath = base_url + "/api/ProjectRoleChange" +getUsersProjectPath = base_url + "/api/getUsersProject" #ta bort auth i handlern för att få testet att gå igenom def test_ProjectRoleChange(): @@ -338,7 +339,33 @@ def test_check_if_project_manager(): assert response.status_code == 200, "Check if project manager failed" gprint("test_check_if_project_manager successful") +def test_list_all_users_project(): + # Log in as a user who is a member of the project + admin_username = randomString() + admin_password = "admin_password2" + dprint( + "Registering with username: ", admin_username, " and password: ", admin_password + ) + response = requests.post( + registerPath, json={"username": admin_username, "password": admin_password} + ) + dprint(response.text) + # Log in as the admin + admin_token = login(admin_username, admin_password).json()["token"] + response = requests.post( + promoteToAdminPath, + json={"username": admin_username}, + headers={"Authorization": "Bearer " + admin_token}, + ) + + # Make a request to list all users associated with the project + response = requests.get( + getUsersProjectPath + "/" + projectName, + headers={"Authorization": "Bearer " + admin_token}, + ) + assert response.status_code == 200, "List all users project failed" + gprint("test_list_all_users_project sucessful") if __name__ == "__main__": @@ -354,3 +381,4 @@ if __name__ == "__main__": test_get_weekly_reports_user() test_check_if_project_manager() test_ProjectRoleChange() + test_list_all_users_project() From a468b896db0018d70e6b350b76a4f0cdcd1f9143 Mon Sep 17 00:00:00 2001 From: borean Date: Wed, 20 Mar 2024 10:41:16 +0100 Subject: [PATCH 2/6] WIP for funcs that need to be implemented --- backend/internal/handlers/global_state.go | 27 +++++++++++------------ 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/backend/internal/handlers/global_state.go b/backend/internal/handlers/global_state.go index 5d01368..1492a09 100644 --- a/backend/internal/handlers/global_state.go +++ b/backend/internal/handlers/global_state.go @@ -22,20 +22,19 @@ type GlobalState interface { PromoteToAdmin(c *fiber.Ctx) error GetWeeklyReportsUserHandler(c *fiber.Ctx) error IsProjectManagerHandler(c *fiber.Ctx) error - // GetProject(c *fiber.Ctx) error // To get a specific project - // UpdateProject(c *fiber.Ctx) error // To update a project - // DeleteProject(c *fiber.Ctx) error // To delete a project - // CreateTask(c *fiber.Ctx) error // To create a new task - // GetTasks(c *fiber.Ctx) error // To get all tasks - // GetTask(c *fiber.Ctx) error // To get a specific task - // UpdateTask(c *fiber.Ctx) error // To update a task - // DeleteTask(c *fiber.Ctx) error // To delete a task - // CreateCollection(c *fiber.Ctx) error // To create a new collection - // GetCollections(c *fiber.Ctx) error // To get all collections - // GetCollection(c *fiber.Ctx) error // To get a specific collection - // UpdateCollection(c *fiber.Ctx) error // To update a collection - // DeleteCollection(c *fiber.Ctx) error // To delete a collection - // SignCollection(c *fiber.Ctx) error // To sign a collection + // UpdateProject(c *fiber.Ctx) error // To update a project // WIP + // DeleteProject(c *fiber.Ctx) error // To delete a project // WIP + // CreateTask(c *fiber.Ctx) error // To create a new task // WIP + // GetTasks(c *fiber.Ctx) error // To get all tasks // WIP + // GetTask(c *fiber.Ctx) error // To get a specific task // WIP + // UpdateTask(c *fiber.Ctx) error // To update a task // WIP + // DeleteTask(c *fiber.Ctx) error // To delete a task // WIP + // CreateCollection(c *fiber.Ctx) error // To create a new collection // WIP + // GetCollections(c *fiber.Ctx) error // To get all collections // WIP + // GetCollection(c *fiber.Ctx) error // To get a specific collection // WIP + // UpdateCollection(c *fiber.Ctx) error // To update a collection // WIP + // DeleteCollection(c *fiber.Ctx) error // To delete a collection // WIP + // SignCollection(c *fiber.Ctx) error // To sign a collection // WIP ListAllUsers(c *fiber.Ctx) error // To get a list of all users in the application database ListAllUsersProject(c *fiber.Ctx) error // To get a list of all users for a specific project ProjectRoleChange(c *fiber.Ctx) error // To change a users role in a project From cd74758b2f647c291e86b96be1f8c6c3e345c0c1 Mon Sep 17 00:00:00 2001 From: borean Date: Wed, 20 Mar 2024 11:09:48 +0100 Subject: [PATCH 3/6] DeleteProject added in db.go, untested --- backend/internal/database/db.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/backend/internal/database/db.go b/backend/internal/database/db.go index 842ffbd..92cbc71 100644 --- a/backend/internal/database/db.go +++ b/backend/internal/database/db.go @@ -3,6 +3,7 @@ package database import ( "embed" "errors" + "fmt" "path/filepath" "ttime/internal/types" @@ -19,6 +20,7 @@ type Database interface { PromoteToAdmin(username string) error GetUserId(username string) (int, error) AddProject(name string, description string, username string) error + // DeleteProject(name string, username string) error Migrate() error MigrateSampleData() error GetProjectId(projectname string) (int, error) @@ -70,6 +72,8 @@ const getProjectsForUser = `SELECT p.id, p.name, p.description FROM projects p JOIN user_roles ur ON p.id = ur.project_id JOIN users u ON ur.user_id = u.id WHERE u.username = ?` +const deleteProject = `DELETE FROM projects + WHERE id = ? AND owner_username = ?` // DbConnect connects to the database func DbConnect(dbpath string) Database { @@ -225,6 +229,21 @@ func (d *Db) AddProject(name string, description string, username string) error return err } +func (d *Db) DeleteProject(projectID string, username string) error { + tx := d.MustBegin() + + _, err := tx.Exec(deleteProject, projectID, username) + + if err != nil { + if rollbackErr := tx.Rollback(); rollbackErr != nil { + return fmt.Errorf("error rolling back transaction: %v, delete error: %v", rollbackErr, err) + } + panic(err) + } + + return err +} + func (d *Db) GetAllUsersProject(projectname string) ([]UserProjectMember, error) { // Define the SQL query to fetch users and their roles for a given project query := ` From dce91943b329eb3a308d7bcbd72625959f59269a Mon Sep 17 00:00:00 2001 From: borean Date: Wed, 20 Mar 2024 11:22:33 +0100 Subject: [PATCH 4/6] Added DeleteProject handler, untested --- backend/internal/database/db.go | 2 +- .../internal/handlers/handlers_project_related.go | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/backend/internal/database/db.go b/backend/internal/database/db.go index 92cbc71..680d7e2 100644 --- a/backend/internal/database/db.go +++ b/backend/internal/database/db.go @@ -20,7 +20,7 @@ type Database interface { PromoteToAdmin(username string) error GetUserId(username string) (int, error) AddProject(name string, description string, username string) error - // DeleteProject(name string, username string) error + DeleteProject(name string, username string) error Migrate() error MigrateSampleData() error GetProjectId(projectname string) (int, error) diff --git a/backend/internal/handlers/handlers_project_related.go b/backend/internal/handlers/handlers_project_related.go index a92616d..be4ffef 100644 --- a/backend/internal/handlers/handlers_project_related.go +++ b/backend/internal/handlers/handlers_project_related.go @@ -30,6 +30,18 @@ func (gs *GState) CreateProject(c *fiber.Ctx) error { return c.Status(200).SendString("Project added") } +func (gs *GState) DeleteProject(c *fiber.Ctx) error { + + projectID := c.Params("projectID") + username := c.Params("username") + + if err := gs.Db.DeleteProject(projectID, username); err != nil { + return c.Status(500).SendString((err.Error())) + } + + return c.Status(200).SendString("Project deleted") +} + // GetUserProjects returns all projects that the user is a member of func (gs *GState) GetUserProjects(c *fiber.Ctx) error { // First we get the username from the token From c01dd21b0a202220fb9cb8a6ef12d9e619fed2f9 Mon Sep 17 00:00:00 2001 From: borean Date: Wed, 20 Mar 2024 11:23:24 +0100 Subject: [PATCH 5/6] uncommented --- backend/internal/handlers/global_state.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/internal/handlers/global_state.go b/backend/internal/handlers/global_state.go index 1492a09..7a4213b 100644 --- a/backend/internal/handlers/global_state.go +++ b/backend/internal/handlers/global_state.go @@ -23,7 +23,7 @@ type GlobalState interface { GetWeeklyReportsUserHandler(c *fiber.Ctx) error IsProjectManagerHandler(c *fiber.Ctx) error // UpdateProject(c *fiber.Ctx) error // To update a project // WIP - // DeleteProject(c *fiber.Ctx) error // To delete a project // WIP + DeleteProject(c *fiber.Ctx) error // To delete a project // WIP // CreateTask(c *fiber.Ctx) error // To create a new task // WIP // GetTasks(c *fiber.Ctx) error // To get all tasks // WIP // GetTask(c *fiber.Ctx) error // To get a specific task // WIP From bb93cef1d3fbda86d34fb3053b4dd8ceeb4d305c Mon Sep 17 00:00:00 2001 From: borean Date: Wed, 20 Mar 2024 11:43:47 +0100 Subject: [PATCH 6/6] New deleteproject handler, WIP --- backend/internal/handlers/handlers_project_related.go | 5 +++++ backend/main.go | 1 + 2 files changed, 6 insertions(+) diff --git a/backend/internal/handlers/handlers_project_related.go b/backend/internal/handlers/handlers_project_related.go index be4ffef..7b95c26 100644 --- a/backend/internal/handlers/handlers_project_related.go +++ b/backend/internal/handlers/handlers_project_related.go @@ -226,3 +226,8 @@ func (gs *GState) IsProjectManagerHandler(c *fiber.Ctx) error { // Return the result as JSON return c.JSON(map[string]bool{"isProjectManager": isManager}) } + +func (gs *GState) CreateTask(c *fiber.Ctx) error { + + return nil +} diff --git a/backend/main.go b/backend/main.go index b907177..d0ccdb1 100644 --- a/backend/main.go +++ b/backend/main.go @@ -87,6 +87,7 @@ func main() { server.Get("/api/getUserProjects", gs.GetUserProjects) server.Post("/api/loginrenew", gs.LoginRenew) server.Delete("/api/userdelete/:username", gs.UserDelete) // Perhaps just use POST to avoid headaches + server.Delete("api/project", gs.DeleteProject) // WIP server.Post("/api/project", gs.CreateProject) server.Get("/api/project/:projectId", gs.GetProject) server.Get("/api/getWeeklyReport", gs.GetWeeklyReport)