package update import ( "context" "time" . "github.com/SowinskiBraeden/school-management-api/controllers" "github.com/SowinskiBraeden/school-management-api/models" "github.com/gofiber/fiber/v2" "github.com/golang-jwt/jwt" "go.mongodb.org/mongo-driver/bson" ) /* Several of these functions aren't directly for updating admin information, but for admins only to update information of other object types such as lockers, enabling user accounts after being disbaled, etc. */ func UpdateLockerCombo(c *fiber.Ctx) error { var data map[string]string ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) if err := c.BodyParser(&data); err != nil { cancel() return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": "Failed to parse body", "error": err, }) } // Ensure Authenticated admin sent request if verified, _ := AuthenticateUser(c, 3); !verified { cancel() return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "success": false, "message": "Unauthorized: only an admin can perform this action", }) } // Check locker number is included if data["lockernumber"] == "" || data["newlockercombo"] == "" { cancel() return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "missing required fields", }) } update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339)) update := bson.M{ "$set": bson.M{ "lockercombo": data["newlockercombo"], "updated_at": update_time, }, } _, updateErr := LockerCollection.UpdateOne( ctx, bson.M{"lockernumber": data["lockernumber"]}, update, ) if updateErr != nil { cancel() return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": "the locker could not be updated", "error": updateErr, }) } defer cancel() return c.Status(fiber.StatusOK).JSON(fiber.Map{ "success": true, "message": "successfully updated locker", }) } func UpdateAdminName(c *fiber.Ctx) error { var data map[string]string ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) if err := c.BodyParser(&data); err != nil { cancel() return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": "Failed to parse body", "error": err, }) } cookie := c.Cookies("jwt") token, err := jwt.ParseWithClaims(cookie, &jwt.StandardClaims{}, func(token *jwt.Token) (interface{}, error) { return []byte(SecretKey), nil }) if err != nil { cancel() return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "success": false, "message": "not authorized", }) } claims := token.Claims.(*jwt.StandardClaims) var admin models.Admin findErr := AdminCollection.FindOne(ctx, bson.M{"aid": claims.Issuer}).Decode(&admin) if findErr != nil { cancel() return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "admin not found", }) } // Check required fields are included if data["firstname"] == "" || data["lastname"] == "" { cancel() return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "missing required fields", }) } update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339)) update := bson.M{ "$set": bson.M{ "firstname": data["firstname"], "lastname": data["lastname"], "updated_at": update_time, }, } _, updateErr := TeacherCollection.UpdateOne( ctx, bson.M{"aid": claims.Issuer}, update, ) if updateErr != nil { cancel() return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": "the admin could not be updated", "error": updateErr, }) } defer cancel() return c.Status(fiber.StatusOK).JSON(fiber.Map{ "success": true, "message": "successfully updated admin", }) } func UpdateAdminEmail(c *fiber.Ctx) error { var data map[string]string ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) if err := c.BodyParser(&data); err != nil { cancel() return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": "Failed to parse body", "error": err, }) } cookie := c.Cookies("jwt") token, err := jwt.ParseWithClaims(cookie, &jwt.StandardClaims{}, func(token *jwt.Token) (interface{}, error) { return []byte(SecretKey), nil }) if err != nil { cancel() return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "success": false, "message": "not authorized", }) } claims := token.Claims.(*jwt.StandardClaims) var admin models.Admin findErr := AdminCollection.FindOne(ctx, bson.M{"aid": claims.Issuer}).Decode(&admin) if findErr != nil { cancel() return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "admin not found", }) } // Check required fields are included if data["email"] == "" { cancel() return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "missing required fields", }) } update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339)) update := bson.M{ "$set": bson.M{ "email": data["email"], "updated_at": update_time, }, } _, updateErr := TeacherCollection.UpdateOne( ctx, bson.M{"aid": claims.Issuer}, update, ) if updateErr != nil { cancel() return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": "the admin could not be updated", "error": updateErr, }) } defer cancel() return c.Status(fiber.StatusOK).JSON(fiber.Map{ "success": true, "message": "successfully updated admin", }) } func UpdateAdminPassword(c *fiber.Ctx) error { var data map[string]string ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) if err := c.BodyParser(&data); err != nil { cancel() return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": "Failed to parse body", "error": err, }) } cookie := c.Cookies("jwt") token, err := jwt.ParseWithClaims(cookie, &jwt.StandardClaims{}, func(token *jwt.Token) (interface{}, error) { return []byte(SecretKey), nil }) if err != nil { cancel() return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "success": false, "message": "not authorized", }) } claims := token.Claims.(*jwt.StandardClaims) var admin models.Admin findErr := AdminCollection.FindOne(ctx, bson.M{"aid": claims.Issuer}).Decode(&admin) if findErr != nil { cancel() return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "admin not found", }) } // Check required fields are included if data["password"] == "" || data["newpassword1"] == "" || data["newpassword2"] == "" { cancel() return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "missing required fields", }) } if !admin.ComparePasswords(data["password"]) { cancel() return c.Status(fiber.StatusOK).JSON(fiber.Map{ "success": false, "message": "Your password is incorrect", }) } if data["newpassword1"] != data["newpassword2"] { cancel() return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "Your new passwords must match", }) } update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339)) update := bson.M{ "$set": bson.M{ "password": admin.HashPassword(data["newpassword1"]), "temppassword": false, // If it were a temp password, its not now "updated_at": update_time, }, } _, updateErr := TeacherCollection.UpdateOne( ctx, bson.M{"aid": claims.Issuer}, update, ) if updateErr != nil { cancel() return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": "the admin password could not be updated", "error": updateErr, }) } defer cancel() subject := "Password Changed" receiver := admin.Email r := NewRequest([]string{receiver}, subject) if sent := r.Send("./templates/selfPasswordChanged.html", map[string]string{"username": admin.FirstName}); !sent { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": "Could not send password to admins email", }) } return c.Status(fiber.StatusOK).JSON(fiber.Map{ "success": true, "message": "successfully updated admin password", }) } func RemoveStudentsDisabled(c *fiber.Ctx) error { var data map[string]string ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) if err := c.BodyParser(&data); err != nil { cancel() return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": "Failed to parse body", "error": err, }) } // Ensure Authorized admin sent request if verified, _ := AuthenticateUser(c, 3); !verified { cancel() return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "success": false, "message": "Unauthorized: only an admin can perform this action", }) } // Check required fields are included if data["uid"] == "" { cancel() return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "missing required fields", }) } update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339)) update := bson.M{ "$set": bson.M{ "Account.accountdisabled": false, "Account.alerted": false, "Account.attempts": 0, "updated_at": update_time, }, } result, updateErr := StudentCollection.UpdateOne( ctx, bson.M{"school.sid": data["uid"]}, update, ) if updateErr != nil { cancel() return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": "the student account could not be enabled", "error": updateErr, }) } defer cancel() return c.Status(fiber.StatusOK).JSON(fiber.Map{ "success": true, "message": "successfully enabled student account", "result": result, }) } func RemoveTeachersDisabled(c *fiber.Ctx) error { var data map[string]string ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) if err := c.BodyParser(&data); err != nil { cancel() return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": "Failed to parse body", "error": err, }) } // Ensure Authorized admin sent request if verified, _ := AuthenticateUser(c, 3); !verified { cancel() return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "success": false, "message": "Unauthorized: only an admin can perform this action", }) } // Check required fields are included if data["uid"] == "" { cancel() return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "message": "missing required fields", }) } update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339)) update := bson.M{ "$set": bson.M{ "Account.accountdisabled": false, "Account.attempts": 0, "updated_at": update_time, }, } result, updateErr := TeacherCollection.UpdateOne( ctx, bson.M{"school.tid": data["uid"]}, update, ) if updateErr != nil { cancel() return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "message": "the teacher account could not be enabled", "error": updateErr, }) } defer cancel() return c.Status(fiber.StatusOK).JSON(fiber.Map{ "success": true, "message": "successfully enabled teacher account", "result": result, }) }