Merge branch 'dev' into gruppPP

This commit is contained in:
Peter KW 2024-03-20 00:32:15 +01:00
commit 4630fb336f
10 changed files with 308 additions and 5 deletions

View file

@ -32,8 +32,10 @@ type Database interface {
GetProject(projectId int) (types.Project, error) GetProject(projectId int) (types.Project, error)
GetUserRole(username string, projectname string) (string, error) GetUserRole(username string, projectname string) (string, error)
GetWeeklyReport(username string, projectName string, week int) (types.WeeklyReport, error) GetWeeklyReport(username string, projectName string, week int) (types.WeeklyReport, error)
GetWeeklyReportsUser(username string, projectname string) ([]types.WeeklyReportList, error)
SignWeeklyReport(reportId int, projectManagerId int) error SignWeeklyReport(reportId int, projectManagerId int) error
IsSiteAdmin(username string) (bool, error) IsSiteAdmin(username string) (bool, error)
IsProjectManager(username string, projectname string) (bool, error)
} }
// This struct is a wrapper type that holds the database connection // This struct is a wrapper type that holds the database connection
@ -402,6 +404,57 @@ func (d *Db) Migrate() error {
return nil return nil
} }
// GetWeeklyReportsUser retrieves weekly reports for a specific user and project.
func (d *Db) GetWeeklyReportsUser(username string, projectName string) ([]types.WeeklyReportList, error) {
query := `
SELECT
wr.week,
wr.development_time,
wr.meeting_time,
wr.admin_time,
wr.own_work_time,
wr.study_time,
wr.testing_time,
wr.signed_by
FROM
weekly_reports wr
INNER JOIN
users u ON wr.user_id = u.id
INNER JOIN
projects p ON wr.project_id = p.id
WHERE
u.username = ? AND p.name = ?
`
var reports []types.WeeklyReportList
if err := d.Select(&reports, query, username, projectName); err != nil {
return nil, err
}
return reports, nil
}
// IsProjectManager checks if a given username is a project manager for the specified project
func (d *Db) IsProjectManager(username string, projectname string) (bool, error) {
// Define the SQL query to check if the user is a project manager for the project
query := `
SELECT COUNT(*) FROM user_roles
JOIN users ON user_roles.user_id = users.id
JOIN projects ON user_roles.project_id = projects.id
WHERE users.username = ? AND projects.name = ? AND user_roles.p_role = 'project_manager'
`
// Execute the query
var count int
err := d.Get(&count, query, username, projectname)
if err != nil {
return false, err
}
// If count is greater than 0, the user is a project manager for the project
return count > 0, nil
}
// MigrateSampleData applies sample data to the database. // MigrateSampleData applies sample data to the database.
func (d *Db) MigrateSampleData() error { func (d *Db) MigrateSampleData() error {
// Insert sample data // Insert sample data

View file

@ -566,3 +566,94 @@ func TestGetProject(t *testing.T) {
t.Errorf("Expected Name to be testproject, got %s", project.Name) t.Errorf("Expected Name to be testproject, got %s", project.Name)
} }
} }
func TestGetWeeklyReportsUser(t *testing.T) {
db, err := setupState()
if err != nil {
t.Error("setupState failed:", err)
}
err = db.AddUser("testuser", "password")
if err != nil {
t.Error("AddUser failed:", err)
}
err = db.AddProject("testproject", "description", "testuser")
if err != nil {
t.Error("AddProject failed:", err)
}
err = db.AddWeeklyReport("testproject", "testuser", 1, 1, 1, 1, 1, 1, 1)
if err != nil {
t.Error("AddWeeklyReport failed:", err)
}
err = db.AddWeeklyReport("testproject", "testuser", 2, 1, 1, 1, 1, 1, 1)
if err != nil {
t.Error("AddWeeklyReport failed:", err)
}
reports, err := db.GetWeeklyReportsUser("testuser", "testproject")
if err != nil {
t.Error("GetWeeklyReportsUser failed:", err)
}
// Check if the retrieved reports match the expected values
if len(reports) != 2 {
t.Errorf("Expected 1 report, got %d", len(reports))
}
}
func TestIsProjectManager(t *testing.T) {
db, err := setupState()
if err != nil {
t.Error("setupState failed:", err)
}
// Add a project manager
err = db.AddUser("projectManager", "password")
if err != nil {
t.Error("AddUser failed:", err)
}
// Add a regular user
err = db.AddUser("testuser", "password")
if err != nil {
t.Error("AddUser failed:", err)
}
// Add project
err = db.AddProject("testproject", "description", "projectManager")
if err != nil {
t.Error("AddProject failed:", err)
}
// Add both regular users as members to the project
err = db.AddUserToProject("testuser", "testproject", "member")
if err != nil {
t.Error("AddUserToProject failed:", err)
}
err = db.AddUserToProject("projectManager", "testproject", "project_manager")
if err != nil {
t.Error("AddUserToProject failed:", err)
}
// Check if the regular user is not a project manager
isManager, err := db.IsProjectManager("testuser", "testproject")
if err != nil {
t.Error("IsProjectManager failed:", err)
}
if isManager {
t.Error("Expected testuser not to be a project manager, but it is.")
}
// Check if the project manager is indeed a project manager
isManager, err = db.IsProjectManager("projectManager", "testproject")
if err != nil {
t.Error("IsProjectManager failed:", err)
}
if !isManager {
t.Error("Expected projectManager to be a project manager, but it's not.")
}
}

View file

@ -20,6 +20,8 @@ type GlobalState interface {
GetProject(c *fiber.Ctx) error GetProject(c *fiber.Ctx) error
AddUserToProjectHandler(c *fiber.Ctx) error AddUserToProjectHandler(c *fiber.Ctx) error
PromoteToAdmin(c *fiber.Ctx) error 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 // GetProject(c *fiber.Ctx) error // To get a specific project
// UpdateProject(c *fiber.Ctx) error // To update a project // UpdateProject(c *fiber.Ctx) error // To update a project
// DeleteProject(c *fiber.Ctx) error // To delete a project // DeleteProject(c *fiber.Ctx) error // To delete a project

View file

@ -49,13 +49,31 @@ func (gs *GState) GetUserProjects(c *fiber.Ctx) error {
// ProjectRoleChange is a handler that changes a user's role within a project // ProjectRoleChange is a handler that changes a user's role within a project
func (gs *GState) ProjectRoleChange(c *fiber.Ctx) error { func (gs *GState) ProjectRoleChange(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 // Extract the necessary parameters from the request
username := c.Params("username") data := new(types.RoleChange)
projectName := c.Params("projectName") if err := c.BodyParser(data); err != nil {
role := c.Params("role") 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, data.Projectname); err != nil {
log.Warn("Error checking if projectmanager:", err)
return c.Status(500).SendString(err.Error())
} else if !ismanager {
log.Warn("tried chaning role when not projectmanager:", err)
return c.Status(401).SendString("you can not change role when not projectManager")
}
// Change the user's role within the project in the database // Change the user's role within the project in the database
if err := gs.Db.ChangeUserRole(username, projectName, role); err != nil { if err := gs.Db.ChangeUserRole(data.Username, data.Projectname, data.Role); err != nil {
return c.Status(500).SendString(err.Error()) return c.Status(500).SendString(err.Error())
} }
@ -154,3 +172,20 @@ func (gs *GState) AddUserToProjectHandler(c *fiber.Ctx) error {
log.Info("User added to project successfully:", requestData.Username) log.Info("User added to project successfully:", requestData.Username)
return c.SendStatus(fiber.StatusOK) return c.SendStatus(fiber.StatusOK)
} }
// IsProjectManagerHandler is a handler that checks if a user is a project manager for a given project
func (gs *GState) IsProjectManagerHandler(c *fiber.Ctx) error {
// Extract necessary parameters from the request query string
username := c.Query("username")
projectName := c.Query("projectName")
// 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())
}
// Return the result as JSON
return c.JSON(map[string]bool{"isProjectManager": isManager})
}

View file

@ -114,3 +114,22 @@ func (gs *GState) SignReport(c *fiber.Ctx) error {
return c.Status(200).SendString("Weekly report signed successfully") return c.Status(200).SendString("Weekly report signed successfully")
} }
// GetWeeklyReportsUserHandler retrieves all weekly reports for a user in a specific project
func (gs *GState) GetWeeklyReportsUserHandler(c *fiber.Ctx) error {
// Extract necessary parameters from the request
username := c.Params("username")
projectName := c.Params("projectName")
// Retrieve weekly reports for the user in the project from the database
reports, err := gs.Db.GetWeeklyReportsUser(username, projectName)
if err != nil {
log.Info("Error getting weekly reports for user:", err)
return c.Status(500).SendString(err.Error())
}
log.Info("Returning weekly reports for user:", username, "in project:", projectName)
// Return the list of reports as JSON
return c.JSON(reports)
}

View file

@ -101,10 +101,15 @@ func (gs *GState) Login(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusUnauthorized) return c.SendStatus(fiber.StatusUnauthorized)
} }
isAdmin, err := gs.Db.IsSiteAdmin(u.Username)
if err != nil {
log.Info("Error checking admin status:", err)
return c.Status(500).SendString(err.Error())
}
// Create the Claims // Create the Claims
claims := jwt.MapClaims{ claims := jwt.MapClaims{
"name": u.Username, "name": u.Username,
"admin": false, "admin": isAdmin,
"exp": time.Now().Add(time.Hour * 72).Unix(), "exp": time.Now().Add(time.Hour * 72).Unix(),
} }

View file

@ -20,6 +20,27 @@ type NewWeeklyReport struct {
TestingTime int `json:"testingTime"` TestingTime int `json:"testingTime"`
} }
type WeeklyReportList struct {
// The name of the project, as it appears in the database
ProjectName string `json:"projectName" db:"project_name"`
// The week number
Week int `json:"week" db:"week"`
// Total time spent on development
DevelopmentTime int `json:"developmentTime" db:"development_time"`
// Total time spent in meetings
MeetingTime int `json:"meetingTime" db:"meeting_time"`
// Total time spent on administrative tasks
AdminTime int `json:"adminTime" db:"admin_time"`
// Total time spent on personal projects
OwnWorkTime int `json:"ownWorkTime" db:"own_work_time"`
// Total time spent on studying
StudyTime int `json:"studyTime" db:"study_time"`
// Total time spent on testing
TestingTime int `json:"testingTime" db:"testing_time"`
// The project manager who signed it
SignedBy *int `json:"signedBy" db:"signed_by"`
}
type WeeklyReport struct { type WeeklyReport struct {
// The ID of the report // The ID of the report
ReportId int `json:"reportId" db:"report_id"` ReportId int `json:"reportId" db:"report_id"`

View file

@ -13,3 +13,9 @@ type NewProject struct {
Name string `json:"name"` Name string `json:"name"`
Description string `json:"description"` Description string `json:"description"`
} }
type RoleChange struct {
Role string `json:"role" tstype:"'project_manager' | 'user'"`
Username string `json:"username"`
Projectname string `json:"projectname"`
}

View file

@ -94,6 +94,9 @@ func main() {
server.Put("/api/addUserToProject", gs.AddUserToProjectHandler) server.Put("/api/addUserToProject", gs.AddUserToProjectHandler)
server.Post("/api/promoteToAdmin", gs.PromoteToAdmin) server.Post("/api/promoteToAdmin", gs.PromoteToAdmin)
server.Get("/api/users/all", gs.ListAllUsers) 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)
// Announce the port we are listening on and start the server // Announce the port we are listening on and start the server
err = server.Listen(fmt.Sprintf(":%d", conf.Port)) err = server.Listen(fmt.Sprintf(":%d", conf.Port))
if err != nil { if err != nil {

View file

@ -37,6 +37,37 @@ signReportPath = base_url + "/api/signReport"
addUserToProjectPath = base_url + "/api/addUserToProject" addUserToProjectPath = base_url + "/api/addUserToProject"
promoteToAdminPath = base_url + "/api/promoteToAdmin" promoteToAdminPath = base_url + "/api/promoteToAdmin"
getUserProjectsPath = base_url + "/api/getUserProjects" getUserProjectsPath = base_url + "/api/getUserProjects"
getWeeklyReportsUserPath = base_url + "/api/getWeeklyReportsUser"
checkIfProjectManagerPath = base_url + "/api/checkIfProjectManager"
ProjectRoleChangePath = base_url + "/api/ProjectRoleChange"
#ta bort auth i handlern för att få testet att gå igenom
def test_ProjectRoleChange():
dprint("Testing ProjectRoleChange")
project_manager = randomString()
register(project_manager, "project_manager_password")
token = login(project_manager, "project_manager_password").json()[
"token"
]
response = requests.post(
addProjectPath,
json={"name": projectName, "description": "This is a project"},
headers={"Authorization": "Bearer " + token},
)
response = requests.post(
ProjectRoleChangePath,
headers={"Authorization": "Bearer " + token},
json={
"username": username,
"projectName": projectName,
"week": 1
},
)
if response.status_code != 200:
print("auth not working, för att man inte kan få tag på pm token atm, för att få igenom det så ta bort auth i handler")
assert response.status_code == 200, "change role successfully"
def test_get_user_projects(): def test_get_user_projects():
@ -275,6 +306,40 @@ def test_sign_report():
dprint(response.text) dprint(response.text)
gprint("test_sign_report successful") gprint("test_sign_report successful")
# Test function to get weekly reports for a user in a project
def test_get_weekly_reports_user():
# Log in as the user
token = login(username, "always_same").json()["token"]
# Get weekly reports for the user in the project
response = requests.get(
getWeeklyReportsUserPath,
headers={"Authorization": "Bearer " + token},
params={"username": username, "projectName": projectName},
)
dprint(response.text)
assert response.status_code == 200, "Get weekly reports for user failed"
gprint("test_get_weekly_reports_user successful")
# Test function to check if a user is a project manager
def test_check_if_project_manager():
# Log in as the user
token = login(username, "always_same").json()["token"]
# Check if the user is a project manager for the project
response = requests.get(
checkIfProjectManagerPath,
headers={"Authorization": "Bearer " + token},
params={"username": username, "projectName": projectName},
)
dprint(response.text)
assert response.status_code == 200, "Check if project manager failed"
gprint("test_check_if_project_manager successful")
if __name__ == "__main__": if __name__ == "__main__":
test_get_user_projects() test_get_user_projects()
@ -286,3 +351,6 @@ if __name__ == "__main__":
test_get_project() test_get_project()
test_sign_report() test_sign_report()
test_add_user_to_project() test_add_user_to_project()
test_get_weekly_reports_user()
test_check_if_project_manager()
test_ProjectRoleChange()