Files
school-management-api/controllers/update/adminController.go
T
2023-01-07 17:14:00 -08:00

462 lines
11 KiB
Go

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["sid"] == "" {
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{"schooldata.sid": data["sid"]},
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["tid"] == "" {
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{"schooldata.tid": data["tid"]},
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,
})
}