diff --git a/backend/internal/handlers/projects/AddUserToProject.go b/backend/internal/handlers/projects/AddUserToProject.go new file mode 100644 index 0000000..702b7dd --- /dev/null +++ b/backend/internal/handlers/projects/AddUserToProject.go @@ -0,0 +1,51 @@ +package projects + +import ( + db "ttime/internal/database" + + "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/log" + "github.com/golang-jwt/jwt/v5" +) + +// AddUserToProjectHandler is a handler that adds a user to a project with a specified role +func AddUserToProjectHandler(c *fiber.Ctx) error { + // Extract necessary parameters from the request + var requestData struct { + Username string `json:"username"` + ProjectName string `json:"projectName"` + Role string `json:"role"` + } + if err := c.BodyParser(&requestData); err != nil { + log.Info("Error parsing request body:", err) + return c.Status(400).SendString("Bad request") + } + + // Check if the user adding another user to the project is a site admin + user := c.Locals("user").(*jwt.Token) + claims := user.Claims.(jwt.MapClaims) + adminUsername := claims["name"].(string) + log.Info("Admin username from claims:", adminUsername) + + isAdmin, err := db.GetDb(c).IsSiteAdmin(adminUsername) + if err != nil { + log.Info("Error checking admin status:", err) + return c.Status(500).SendString(err.Error()) + } + + if !isAdmin { + log.Info("User is not a site admin:", adminUsername) + return c.Status(403).SendString("User is not a site admin") + } + + // Add the user to the project with the specified role + err = db.GetDb(c).AddUserToProject(requestData.Username, requestData.ProjectName, requestData.Role) + if err != nil { + log.Info("Error adding user to project:", err) + return c.Status(500).SendString(err.Error()) + } + + // Return success message + log.Info("User added to project successfully:", requestData.Username) + return c.SendStatus(fiber.StatusOK) +} diff --git a/backend/internal/handlers/projects/CreateProject.go b/backend/internal/handlers/projects/CreateProject.go new file mode 100644 index 0000000..cef2f2b --- /dev/null +++ b/backend/internal/handlers/projects/CreateProject.go @@ -0,0 +1,30 @@ +package projects + +import ( + db "ttime/internal/database" + "ttime/internal/types" + + "github.com/gofiber/fiber/v2" + "github.com/golang-jwt/jwt/v5" +) + +// CreateProject is a simple handler that creates a new project +func CreateProject(c *fiber.Ctx) error { + user := c.Locals("user").(*jwt.Token) + + p := new(types.NewProject) + if err := c.BodyParser(p); err != nil { + return c.Status(400).SendString(err.Error()) + } + + // Get the username from the token and set it as the owner of the project + // This is ugly but + claims := user.Claims.(jwt.MapClaims) + owner := claims["name"].(string) + + if err := db.GetDb(c).AddProject(p.Name, p.Description, owner); err != nil { + return c.Status(500).SendString(err.Error()) + } + + return c.Status(200).SendString("Project added") +} diff --git a/backend/internal/handlers/projects/DeleteProject.go b/backend/internal/handlers/projects/DeleteProject.go new file mode 100644 index 0000000..415424a --- /dev/null +++ b/backend/internal/handlers/projects/DeleteProject.go @@ -0,0 +1,19 @@ +package projects + +import ( + db "ttime/internal/database" + + "github.com/gofiber/fiber/v2" +) + +func DeleteProject(c *fiber.Ctx) error { + + projectID := c.Params("projectID") + username := c.Params("username") + + if err := db.GetDb(c).DeleteProject(projectID, username); err != nil { + return c.Status(500).SendString((err.Error())) + } + + return c.Status(200).SendString("Project deleted") +} diff --git a/backend/internal/handlers/projects/GetProject.go b/backend/internal/handlers/projects/GetProject.go new file mode 100644 index 0000000..03333ce --- /dev/null +++ b/backend/internal/handlers/projects/GetProject.go @@ -0,0 +1,38 @@ +package projects + +import ( + "strconv" + db "ttime/internal/database" + + "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/log" +) + +// GetProject retrieves a specific project by its ID +func GetProject(c *fiber.Ctx) error { + // Extract the project ID from the request parameters or body + projectID := c.Params("projectID") + if projectID == "" { + log.Info("No project ID provided") + return c.Status(400).SendString("No project ID provided") + } + log.Info("Getting project with ID: ", projectID) + + // Parse the project ID into an integer + projectIDInt, err := strconv.Atoi(projectID) + if err != nil { + log.Info("Invalid project ID") + return c.Status(400).SendString("Invalid project ID") + } + + // Get the project from the database by its ID + project, err := db.GetDb(c).GetProject(projectIDInt) + if err != nil { + log.Info("Error getting project:", err) + return c.Status(500).SendString(err.Error()) + } + + // Return the project as JSON + log.Info("Returning project: ", project.Name) + return c.JSON(project) +} diff --git a/backend/internal/handlers/projects/GetProjectTimes.go b/backend/internal/handlers/projects/GetProjectTimes.go new file mode 100644 index 0000000..573a95e --- /dev/null +++ b/backend/internal/handlers/projects/GetProjectTimes.go @@ -0,0 +1,63 @@ +package projects + +import ( + db "ttime/internal/database" + + "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/log" + "github.com/golang-jwt/jwt/v5" +) + +func GetProjectTimesHandler(c *fiber.Ctx) error { + // Get the username from the token + user := c.Locals("user").(*jwt.Token) + claims := user.Claims.(jwt.MapClaims) + username := claims["name"].(string) + + // Get project + projectName := c.Params("projectName") + if projectName == "" { + log.Info("No project name provided") + return c.Status(400).SendString("No project name provided") + } + + // Get all users in the project and roles + userProjects, err := db.GetDb(c).GetAllUsersProject(projectName) + if err != nil { + log.Info("Error getting users in project:", err) + return c.Status(500).SendString(err.Error()) + } + + // If the user is member + isMember := false + for _, userProject := range userProjects { + if userProject.Username == username { + isMember = true + break + } + } + + // If the user is admin + if !isMember { + isAdmin, err := db.GetDb(c).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 member nor a site admin:", username) + return c.Status(403).SendString("User is neither a project member nor a site admin") + } + } + + // Get project times + projectTimes, err := db.GetDb(c).GetProjectTimes(projectName) + if err != nil { + log.Info("Error getting project times:", err) + return c.Status(500).SendString(err.Error()) + } + + // Return project times as JSON + log.Info("Returning project times for project:", projectName) + return c.JSON(projectTimes) +} diff --git a/backend/internal/handlers/projects/GetUserProject.go b/backend/internal/handlers/projects/GetUserProject.go new file mode 100644 index 0000000..99ed63b --- /dev/null +++ b/backend/internal/handlers/projects/GetUserProject.go @@ -0,0 +1,25 @@ +package projects + +import ( + db "ttime/internal/database" + + "github.com/gofiber/fiber/v2" + "github.com/golang-jwt/jwt/v5" +) + +// GetUserProjects returns all projects that the user is a member of +func GetUserProjects(c *fiber.Ctx) error { + // First we get the username from the token + user := c.Locals("user").(*jwt.Token) + claims := user.Claims.(jwt.MapClaims) + username := claims["name"].(string) + + // Then dip into the database to get the projects + projects, err := db.GetDb(c).GetProjectsForUser(username) + if err != nil { + return c.Status(500).SendString(err.Error()) + } + + // Return a json serialized list of projects + return c.JSON(projects) +} diff --git a/backend/internal/handlers/projects/IsProjectManager.go b/backend/internal/handlers/projects/IsProjectManager.go new file mode 100644 index 0000000..678fad5 --- /dev/null +++ b/backend/internal/handlers/projects/IsProjectManager.go @@ -0,0 +1,32 @@ +package projects + +import ( + db "ttime/internal/database" + + "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/log" + "github.com/golang-jwt/jwt/v5" +) + +// IsProjectManagerHandler is a handler that checks if a user is a project manager for a given project +func IsProjectManagerHandler(c *fiber.Ctx) error { + // Get the username from the token + user := c.Locals("user").(*jwt.Token) + claims := user.Claims.(jwt.MapClaims) + username := claims["name"].(string) + + // Extract necessary parameters from the request query string + projectName := c.Params("projectName") + + log.Info("Checking if user ", username, " is a project manager for project ", projectName) + + // Check if the user is a project manager for the specified project + isManager, err := db.GetDb(c).IsProjectManager(username, projectName) + if err != nil { + log.Info("Error checking project manager status:", err) + return c.Status(500).SendString(err.Error()) + } + + // Return the result as JSON + return c.JSON(fiber.Map{"isProjectManager": isManager}) +} diff --git a/backend/internal/handlers/projects/ListAllUserProjects.go b/backend/internal/handlers/projects/ListAllUserProjects.go new file mode 100644 index 0000000..e0bcaf5 --- /dev/null +++ b/backend/internal/handlers/projects/ListAllUserProjects.go @@ -0,0 +1,55 @@ +package projects + +import ( + db "ttime/internal/database" + + "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/log" + "github.com/golang-jwt/jwt/v5" +) + +func ListAllUsersProject(c *fiber.Ctx) error { + // Extract the project name from the request parameters or body + projectName := c.Params("projectName") + if projectName == "" { + log.Info("No project name provided") + 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 := db.GetDb(c).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 := db.GetDb(c).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 := db.GetDb(c).GetAllUsersProject(projectName) + if err != nil { + log.Info("Error getting users for project:", err) + return c.Status(500).SendString(err.Error()) + } + + log.Info("Returning users for project: ", projectName) + + // Return the list of users as JSON + return c.JSON(users) +} diff --git a/backend/internal/handlers/projects/ProjectRoleChange.go b/backend/internal/handlers/projects/ProjectRoleChange.go new file mode 100644 index 0000000..266127d --- /dev/null +++ b/backend/internal/handlers/projects/ProjectRoleChange.go @@ -0,0 +1,45 @@ +package projects + +import ( + db "ttime/internal/database" + "ttime/internal/types" + + "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/log" + "github.com/golang-jwt/jwt/v5" +) + +// ProjectRoleChange is a handler that changes a user's role within a project +func ProjectRoleChange(c *fiber.Ctx) error { + + //check token and get username of current user + user := c.Locals("user").(*jwt.Token) + claims := user.Claims.(jwt.MapClaims) + username := claims["name"].(string) + + // Extract the necessary parameters from the request + data := new(types.RoleChange) + if err := c.BodyParser(data); err != nil { + log.Info("error parsing username, project or role") + return c.Status(400).SendString(err.Error()) + } + + log.Info("Changing role for user: ", username, " in project: ", data.Projectname, " to: ", data.Role) + + // Dubble diping and checcking if current user is + if ismanager, err := db.GetDb(c).IsProjectManager(username, data.Projectname); err != nil { + log.Warn("Error checking if projectmanager:", err) + return c.Status(500).SendString(err.Error()) + } else if !ismanager { + log.Warn("User is not projectmanager") + return c.Status(401).SendString("User is not projectmanager") + } + + // Change the user's role within the project in the database + if err := db.GetDb(c).ChangeUserRole(username, data.Projectname, data.Role); err != nil { + return c.Status(500).SendString(err.Error()) + } + + // Return a success message + return c.SendStatus(fiber.StatusOK) +} diff --git a/backend/internal/handlers/projects/RemoveProject.go b/backend/internal/handlers/projects/RemoveProject.go new file mode 100644 index 0000000..7b140dd --- /dev/null +++ b/backend/internal/handlers/projects/RemoveProject.go @@ -0,0 +1,35 @@ +package projects + +import ( + db "ttime/internal/database" + + "github.com/gofiber/fiber/v2" + "github.com/gofiber/fiber/v2/log" + "github.com/golang-jwt/jwt/v5" +) + +func RemoveProject(c *fiber.Ctx) error { + user := c.Locals("user").(*jwt.Token) + claims := user.Claims.(jwt.MapClaims) + username := claims["name"].(string) + + // Check if the user is a site admin + isAdmin, err := db.GetDb(c).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 not a site admin:", username) + return c.Status(403).SendString("User is not a site admin") + } + + projectName := c.Params("projectName") + + if err := db.GetDb(c).RemoveProject(projectName); err != nil { + return c.Status(500).SendString((err.Error())) + } + + return c.Status(200).SendString("Project deleted") +} diff --git a/backend/internal/handlers/projects/handlers_project_related.go b/backend/internal/handlers/projects/handlers_project_related.go deleted file mode 100644 index 3429504..0000000 --- a/backend/internal/handlers/projects/handlers_project_related.go +++ /dev/null @@ -1,316 +0,0 @@ -package projects - -import ( - "strconv" - db "ttime/internal/database" - "ttime/internal/types" - - "github.com/gofiber/fiber/v2" - "github.com/gofiber/fiber/v2/log" - "github.com/golang-jwt/jwt/v5" -) - -// CreateProject is a simple handler that creates a new project -func CreateProject(c *fiber.Ctx) error { - user := c.Locals("user").(*jwt.Token) - - p := new(types.NewProject) - if err := c.BodyParser(p); err != nil { - return c.Status(400).SendString(err.Error()) - } - - // Get the username from the token and set it as the owner of the project - // This is ugly but - claims := user.Claims.(jwt.MapClaims) - owner := claims["name"].(string) - - if err := db.GetDb(c).AddProject(p.Name, p.Description, owner); err != nil { - return c.Status(500).SendString(err.Error()) - } - - return c.Status(200).SendString("Project added") -} - -func DeleteProject(c *fiber.Ctx) error { - - projectID := c.Params("projectID") - username := c.Params("username") - - if err := db.GetDb(c).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 GetUserProjects(c *fiber.Ctx) error { - // First we get the username from the token - user := c.Locals("user").(*jwt.Token) - claims := user.Claims.(jwt.MapClaims) - username := claims["name"].(string) - - // Then dip into the database to get the projects - projects, err := db.GetDb(c).GetProjectsForUser(username) - if err != nil { - return c.Status(500).SendString(err.Error()) - } - - // Return a json serialized list of projects - return c.JSON(projects) -} - -// ProjectRoleChange is a handler that changes a user's role within a project -func ProjectRoleChange(c *fiber.Ctx) error { - - //check token and get username of current user - user := c.Locals("user").(*jwt.Token) - claims := user.Claims.(jwt.MapClaims) - username := claims["name"].(string) - - // Extract the necessary parameters from the request - data := new(types.RoleChange) - if err := c.BodyParser(data); err != nil { - log.Info("error parsing username, project or role") - return c.Status(400).SendString(err.Error()) - } - - log.Info("Changing role for user: ", username, " in project: ", data.Projectname, " to: ", data.Role) - - // Dubble diping and checcking if current user is - if ismanager, err := db.GetDb(c).IsProjectManager(username, data.Projectname); err != nil { - log.Warn("Error checking if projectmanager:", err) - return c.Status(500).SendString(err.Error()) - } else if !ismanager { - log.Warn("User is not projectmanager") - return c.Status(401).SendString("User is not projectmanager") - } - - // Change the user's role within the project in the database - if err := db.GetDb(c).ChangeUserRole(username, data.Projectname, data.Role); err != nil { - return c.Status(500).SendString(err.Error()) - } - - // Return a success message - return c.SendStatus(fiber.StatusOK) -} - -// GetProject retrieves a specific project by its ID -func GetProject(c *fiber.Ctx) error { - // Extract the project ID from the request parameters or body - projectID := c.Params("projectID") - if projectID == "" { - log.Info("No project ID provided") - return c.Status(400).SendString("No project ID provided") - } - log.Info("Getting project with ID: ", projectID) - - // Parse the project ID into an integer - projectIDInt, err := strconv.Atoi(projectID) - if err != nil { - log.Info("Invalid project ID") - return c.Status(400).SendString("Invalid project ID") - } - - // Get the project from the database by its ID - project, err := db.GetDb(c).GetProject(projectIDInt) - if err != nil { - log.Info("Error getting project:", err) - return c.Status(500).SendString(err.Error()) - } - - // Return the project as JSON - log.Info("Returning project: ", project.Name) - return c.JSON(project) -} - -func ListAllUsersProject(c *fiber.Ctx) error { - // Extract the project name from the request parameters or body - projectName := c.Params("projectName") - if projectName == "" { - log.Info("No project name provided") - 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 := db.GetDb(c).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 := db.GetDb(c).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 := db.GetDb(c).GetAllUsersProject(projectName) - if err != nil { - log.Info("Error getting users for project:", err) - return c.Status(500).SendString(err.Error()) - } - - log.Info("Returning users for project: ", projectName) - - // Return the list of users as JSON - return c.JSON(users) -} - -// AddUserToProjectHandler is a handler that adds a user to a project with a specified role -func AddUserToProjectHandler(c *fiber.Ctx) error { - // Extract necessary parameters from the request - var requestData struct { - Username string `json:"username"` - ProjectName string `json:"projectName"` - Role string `json:"role"` - } - if err := c.BodyParser(&requestData); err != nil { - log.Info("Error parsing request body:", err) - return c.Status(400).SendString("Bad request") - } - - // Check if the user adding another user to the project is a site admin - user := c.Locals("user").(*jwt.Token) - claims := user.Claims.(jwt.MapClaims) - adminUsername := claims["name"].(string) - log.Info("Admin username from claims:", adminUsername) - - isAdmin, err := db.GetDb(c).IsSiteAdmin(adminUsername) - if err != nil { - log.Info("Error checking admin status:", err) - return c.Status(500).SendString(err.Error()) - } - - if !isAdmin { - log.Info("User is not a site admin:", adminUsername) - return c.Status(403).SendString("User is not a site admin") - } - - // Add the user to the project with the specified role - err = db.GetDb(c).AddUserToProject(requestData.Username, requestData.ProjectName, requestData.Role) - if err != nil { - log.Info("Error adding user to project:", err) - return c.Status(500).SendString(err.Error()) - } - - // Return success message - log.Info("User added to project successfully:", requestData.Username) - return c.SendStatus(fiber.StatusOK) -} - -// IsProjectManagerHandler is a handler that checks if a user is a project manager for a given project -func IsProjectManagerHandler(c *fiber.Ctx) error { - // Get the username from the token - user := c.Locals("user").(*jwt.Token) - claims := user.Claims.(jwt.MapClaims) - username := claims["name"].(string) - - // Extract necessary parameters from the request query string - projectName := c.Params("projectName") - - log.Info("Checking if user ", username, " is a project manager for project ", projectName) - - // Check if the user is a project manager for the specified project - isManager, err := db.GetDb(c).IsProjectManager(username, projectName) - if err != nil { - log.Info("Error checking project manager status:", err) - return c.Status(500).SendString(err.Error()) - } - - // Return the result as JSON - return c.JSON(fiber.Map{"isProjectManager": isManager}) -} - -func GetProjectTimesHandler(c *fiber.Ctx) error { - // Get the username from the token - user := c.Locals("user").(*jwt.Token) - claims := user.Claims.(jwt.MapClaims) - username := claims["name"].(string) - - // Get project - projectName := c.Params("projectName") - if projectName == "" { - log.Info("No project name provided") - return c.Status(400).SendString("No project name provided") - } - - // Get all users in the project and roles - userProjects, err := db.GetDb(c).GetAllUsersProject(projectName) - if err != nil { - log.Info("Error getting users in project:", err) - return c.Status(500).SendString(err.Error()) - } - - // If the user is member - isMember := false - for _, userProject := range userProjects { - if userProject.Username == username { - isMember = true - break - } - } - - // If the user is admin - if !isMember { - isAdmin, err := db.GetDb(c).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 member nor a site admin:", username) - return c.Status(403).SendString("User is neither a project member nor a site admin") - } - } - - // Get project times - projectTimes, err := db.GetDb(c).GetProjectTimes(projectName) - if err != nil { - log.Info("Error getting project times:", err) - return c.Status(500).SendString(err.Error()) - } - - // Return project times as JSON - log.Info("Returning project times for project:", projectName) - return c.JSON(projectTimes) -} - -func RemoveProject(c *fiber.Ctx) error { - user := c.Locals("user").(*jwt.Token) - claims := user.Claims.(jwt.MapClaims) - username := claims["name"].(string) - - // Check if the user is a site admin - isAdmin, err := db.GetDb(c).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 not a site admin:", username) - return c.Status(403).SendString("User is not a site admin") - } - - projectName := c.Params("projectName") - - if err := db.GetDb(c).RemoveProject(projectName); err != nil { - return c.Status(500).SendString((err.Error())) - } - - return c.Status(200).SendString("Project deleted") -}