Merge branch 'BumBranch' into gruppDM

This commit is contained in:
Davenludd 2024-03-20 15:21:26 +01:00
commit 847073c6f8
8 changed files with 182 additions and 31 deletions

View file

@ -3,6 +3,7 @@ package database
import (
"embed"
"errors"
"fmt"
"path/filepath"
"ttime/internal/types"
@ -19,12 +20,14 @@ 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)
AddWeeklyReport(projectName string, userName string, week int, developmentTime int, meetingTime int, adminTime int, ownWorkTime int, studyTime int, testingTime int) error
AddUserToProject(username string, projectname string, role string) error
ChangeUserRole(username string, projectname string, role string) error
ChangeUserName(username string, newname string) error
GetAllUsersProject(projectname string) ([]UserProjectMember, error)
GetAllUsersApplication() ([]string, error)
GetProjectsForUser(username string) ([]types.Project, error)
@ -65,11 +68,14 @@ const addWeeklyReport = `WITH UserLookup AS (SELECT id FROM users WHERE username
VALUES ((SELECT id FROM ProjectLookup), (SELECT id FROM UserLookup),?, ?, ?, ?, ?, ?, ?);`
const addUserToProject = "INSERT INTO user_roles (user_id, project_id, p_role) VALUES (?, ?, ?)" // WIP
const changeUserRole = "UPDATE user_roles SET p_role = ? WHERE user_id = ? AND project_id = ?"
const changeUserName = "UPDATE user SET username = ? WHERE user_id = ?" // WIP
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 {
@ -165,6 +171,20 @@ func (d *Db) ChangeUserRole(username string, projectname string, role string) er
return err3
}
// ChangeUserRole changes the role of a user within a project.
func (d *Db) ChangeUserName(username string, newname string) error {
// Get the user ID
var userid int
userid, err := d.GetUserId(username)
if err != nil {
panic(err)
}
// Execute the SQL query to change the user's role
_, err2 := d.Exec(changeUserName, username, userid)
return err2
}
// GetUserRole retrieves the role of a user within a project.
func (d *Db) GetUserRole(username string, projectname string) (string, error) {
var role string
@ -225,6 +245,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 := `

View file

@ -22,23 +22,12 @@ 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
DeleteProject(c *fiber.Ctx) error // To delete a project // 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
ChangeUserName(c *fiber.Ctx) error // WIP
GetAllUsersProject(c *fiber.Ctx) error // WIP
}
// "Constructor"

View file

@ -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
@ -118,6 +130,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 {
@ -189,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
}

View file

@ -187,6 +187,20 @@ func (gs *GState) ListAllUsers(c *fiber.Ctx) error {
return c.JSON(users)
}
func (gs *GState) GetAllUsersProject(c *fiber.Ctx) error {
// Get all users from a project
projectName := c.Params("projectName")
users, err := gs.Db.GetAllUsersProject(projectName)
if err != nil {
log.Info("Error getting users from project:", err) // Debug print
return c.Status(500).SendString(err.Error())
}
log.Info("Returning all users")
// Return the list of users as JSON
return c.JSON(users)
}
// @Summary PromoteToAdmin
// @Description promote chosen user to admin
// @Tags User
@ -219,3 +233,37 @@ func (gs *GState) PromoteToAdmin(c *fiber.Ctx) error {
// Return a success message
return c.SendStatus(fiber.StatusOK)
}
// Changes a users name in the database
func (gs *GState) ChangeUserName(c *fiber.Ctx) error {
//check token and get username of current user
user := c.Locals("user").(*jwt.Token)
claims := user.Claims.(jwt.MapClaims)
projectManagerUsername := claims["name"].(string)
log.Info(projectManagerUsername)
// Extract the necessary parameters from the request
data := new(types.NameChange)
if err := c.BodyParser(data); err != nil {
log.Info("error parsing username, project or role")
return c.Status(400).SendString(err.Error())
}
// dubble diping and checcking if current user is
if ismanager, err := gs.Db.IsProjectManager(projectManagerUsername, c.Params(data.Name)); err != nil {
log.Warn("Error checking if projectmanager:", err)
return c.Status(500).SendString(err.Error())
} else if !ismanager {
log.Warn("tried changing name when not projectmanager:", err)
return c.Status(401).SendString("you can not change name when not projectManager")
}
// Change the user's name within the project in the database
if err := gs.Db.ChangeUserName(projectManagerUsername, data.Name); err != nil {
return c.Status(500).SendString(err.Error())
}
// Return a success message
return c.SendStatus(fiber.StatusOK)
}

View file

@ -19,3 +19,8 @@ type RoleChange struct {
Username string `json:"username"`
Projectname string `json:"projectname"`
}
type NameChange struct {
ID int `json:"id" db:"id"`
Name string `json:"name" db:"name"`
}

View file

@ -87,16 +87,21 @@ 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.Post("/api/project", gs.CreateProject)
server.Delete("api/project/:projectID", gs.DeleteProject) // WIP
server.Post("/api/project", gs.CreateProject) // WIP
server.Get("/api/project/:projectId", gs.GetProject)
server.Get("/api/project/getAllUsers", gs.GetAllUsersProject)
server.Get("/api/getWeeklyReport", gs.GetWeeklyReport)
server.Post("/api/signReport", gs.SignReport)
server.Put("/api/addUserToProject", gs.AddUserToProjectHandler)
server.Put("/api/changeUserName", gs.ChangeUserName)
server.Post("/api/promoteToAdmin", gs.PromoteToAdmin)
server.Get("/api/users/all", gs.ListAllUsers)
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 {

View file

@ -49,7 +49,7 @@ interface API {
week: string,
token: string,
): Promise<APIResponse<WeeklyReport>>;
getWeeklyReportsForProject(
getWeeklyReportsForUser(
username: string,
projectName: string,
token: string,
@ -276,19 +276,18 @@ export const api: API = {
}
},
async getWeeklyReportsForProject(
async getWeeklyReportsForUser(
username: string,
projectName: string,
token: string,
): Promise<APIResponse<WeeklyReport[]>> {
try {
const response = await fetch("/api/getWeeklyReportsUser", {
const response = await fetch(`/api/getWeeklyReportsUser?username=${username}&projectName=${projectName}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
body: JSON.stringify({ username, projectName }),
});
if (!response.ok) {

View file

@ -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()