transfer update controllers to own files

This commit is contained in:
SowinskiBraeden committed 2022-08-14 11:49:01 -07:00
1 parent 1b643c0bc2
commit d7d19ffb2d
11 files changed
+2708 -2651

No files matched your search

+211 -26
View File
@@ -21,10 +21,21 @@ import (
"go.mongodb.org/mongo-driver/mongo"
)
var teacherCollection *mongo.Collection = database.OpenCollection(database.Client, "teachers")
var studentCollection *mongo.Collection = database.OpenCollection(database.Client, "students")
var contactCollection *mongo.Collection = database.OpenCollection(database.Client, "contacts")
var adminCollection *mongo.Collection = database.OpenCollection(database.Client, "admins")
/*
The auth controller handles the following:
- default admin settings
- creating new users
- authenticating users
- retreiving users
- removeing users
*/
var TeacherCollection *mongo.Collection = database.OpenCollection(database.Client, "teachers")
var StudentCollection *mongo.Collection = database.OpenCollection(database.Client, "students")
var ContactCollection *mongo.Collection = database.OpenCollection(database.Client, "contacts")
var AdminCollection *mongo.Collection = database.OpenCollection(database.Client, "admins")
var ImageCollection *mongo.Collection = database.OpenCollection(database.Client, "images")
var LockerCollection *mongo.Collection = database.OpenCollection(database.Client, "lockers")
func confirm(s string) bool {
r := bufio.NewReader(os.Stdin)
@@ -86,7 +97,7 @@ func CreateDefaultAdmin() models.Admin {
}
func NewSystem() {
count, err := adminCollection.CountDocuments(context.Background(), bson.D{})
count, err := AdminCollection.CountDocuments(context.Background(), bson.D{})
if err != nil {
fmt.Println("Unable to detect new system")
}
@@ -98,7 +109,7 @@ func NewSystem() {
defaultAdmin := CreateDefaultAdmin()
if confirm("Are the above credentials correct?") {
_, insertErr := adminCollection.InsertOne(context.Background(), defaultAdmin)
_, insertErr := AdminCollection.InsertOne(context.Background(), defaultAdmin)
if insertErr != nil {
log.Printf("Failed to create an admin\n")
}
@@ -130,7 +141,7 @@ func AuthenticateUser(c *fiber.Ctx, userType int) (bool, string) {
claims := token.Claims.(*jwt.StandardClaims)
var userID models.Id
findErr := idCollection.FindOne(context.TODO(), bson.M{"cid": claims.Issuer}).Decode(&userID)
findErr := IdCollection.FindOne(context.TODO(), bson.M{"cid": claims.Issuer}).Decode(&userID)
if findErr != nil {
return false, ""
}
@@ -268,7 +279,7 @@ func Enroll(c *fiber.Ctx) error {
student.Updated_at, _ = time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
student.ID = primitive.NewObjectID()
_, insertErr := studentCollection.InsertOne(ctx, student)
_, insertErr := StudentCollection.InsertOne(ctx, student)
if insertErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
@@ -278,7 +289,7 @@ func Enroll(c *fiber.Ctx) error {
})
}
_, insertErr = imageCollection.InsertOne(ctx, photo)
_, insertErr = ImageCollection.InsertOne(ctx, photo)
if insertErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
@@ -406,7 +417,7 @@ func RegisterTeacher(c *fiber.Ctx) error {
teacher.Updated_at, _ = time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
teacher.ID = primitive.NewObjectID()
_, insertErr := teacherCollection.InsertOne(ctx, teacher)
_, insertErr := TeacherCollection.InsertOne(ctx, teacher)
if insertErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
@@ -503,7 +514,7 @@ func CreateAdmin(c *fiber.Ctx) error {
admin.Updated_at, _ = time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
admin.ID = primitive.NewObjectID()
_, insertErr := adminCollection.InsertOne(ctx, admin)
_, insertErr := AdminCollection.InsertOne(ctx, admin)
if insertErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
@@ -543,7 +554,7 @@ func StudentLogin(c *fiber.Ctx) error {
}
var student models.Student
err := studentCollection.FindOne(ctx, bson.M{"schooldata.sid": data["sid"]}).Decode(&student)
err := StudentCollection.FindOne(ctx, bson.M{"schooldata.sid": data["sid"]}).Decode(&student)
if err != nil {
cancel()
@@ -574,7 +585,7 @@ func StudentLogin(c *fiber.Ctx) error {
},
}
_, updateErr := studentCollection.UpdateOne(
_, updateErr := StudentCollection.UpdateOne(
ctx,
bson.M{"schooldata.sid": data["sid"]},
update,
@@ -623,7 +634,7 @@ func StudentLogin(c *fiber.Ctx) error {
},
}
_, updateErr := studentCollection.UpdateOne(
_, updateErr := StudentCollection.UpdateOne(
ctx,
bson.M{"schooldata.sid": data["sid"]},
update,
@@ -650,7 +661,7 @@ func StudentLogin(c *fiber.Ctx) error {
},
}
_, updateErr := studentCollection.UpdateOne(
_, updateErr := StudentCollection.UpdateOne(
ctx,
bson.M{"schooldata.sid": data["sid"]},
update,
@@ -715,7 +726,7 @@ func TeacherLogin(c *fiber.Ctx) error {
}
var teacher models.Teacher
err := teacherCollection.FindOne(ctx, bson.M{"schooldata.tid": data["tid"]}).Decode(&teacher)
err := TeacherCollection.FindOne(ctx, bson.M{"schooldata.tid": data["tid"]}).Decode(&teacher)
defer cancel()
if err != nil {
@@ -785,7 +796,7 @@ func AdminLogin(c *fiber.Ctx) error {
}
var admin models.Admin
err := adminCollection.FindOne(ctx, bson.M{"aid": data["aid"]}).Decode(&admin)
err := AdminCollection.FindOne(ctx, bson.M{"aid": data["aid"]}).Decode(&admin)
defer cancel()
if err != nil {
@@ -878,7 +889,7 @@ func Student(c *fiber.Ctx) error {
responseData["photo"] = nil
var student models.Student
findErr := studentCollection.FindOne(context.TODO(), bson.M{"schooldata.sid": sid}).Decode(&student)
findErr := StudentCollection.FindOne(context.TODO(), bson.M{"schooldata.sid": sid}).Decode(&student)
if findErr != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
@@ -897,14 +908,14 @@ func Student(c *fiber.Ctx) error {
var locker models.Locker
if student.SchoolData.Locker != "" {
lockerCollection.FindOne(context.TODO(), bson.M{"ID": student.SchoolData.Locker}).Decode(&locker)
LockerCollection.FindOne(context.TODO(), bson.M{"ID": student.SchoolData.Locker}).Decode(&locker)
responseData["locker"] = locker
}
var contacts []models.Contact
var contact models.Contact
for i := range student.PersonalData.Contacts {
findErr := contactCollection.FindOne(context.TODO(), bson.M{"_id": student.PersonalData.Contacts[i]}).Decode(&contact)
findErr := ContactCollection.FindOne(context.TODO(), bson.M{"_id": student.PersonalData.Contacts[i]}).Decode(&contact)
if findErr != nil {
responseData["error"] = "Error! There was an error finding some contacts"
}
@@ -915,7 +926,7 @@ func Student(c *fiber.Ctx) error {
}
var photo models.Photo
findErr = imageCollection.FindOne(context.TODO(), bson.M{"name": student.SchoolData.PhotoName}).Decode(&photo)
findErr = ImageCollection.FindOne(context.TODO(), bson.M{"name": student.SchoolData.PhotoName}).Decode(&photo)
if findErr != nil {
responseData["error"] = "Error! There was an error finding the student photo"
}
@@ -943,7 +954,7 @@ func Teacher(c *fiber.Ctx) error {
claims := token.Claims.(*jwt.StandardClaims)
var teacher models.Teacher
findErr := teacherCollection.FindOne(context.TODO(), bson.M{"schooldata.tid": claims.Issuer}).Decode(&teacher)
findErr := TeacherCollection.FindOne(context.TODO(), bson.M{"schooldata.tid": claims.Issuer}).Decode(&teacher)
if findErr != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
@@ -974,7 +985,7 @@ func Admin(c *fiber.Ctx) error {
claims := token.Claims.(*jwt.StandardClaims)
var admin models.Admin
findErr := adminCollection.FindOne(context.TODO(), bson.M{"aid": claims.Issuer}).Decode(&admin)
findErr := AdminCollection.FindOne(context.TODO(), bson.M{"aid": claims.Issuer}).Decode(&admin)
if findErr != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
@@ -1054,7 +1065,7 @@ func CreateContact(c *fiber.Ctx) error {
contact.Updated_at, _ = time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
contact.ID = primitive.NewObjectID()
_, insertErr := contactCollection.InsertOne(ctx, contact)
_, insertErr := ContactCollection.InsertOne(ctx, contact)
if insertErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
@@ -1069,7 +1080,7 @@ func CreateContact(c *fiber.Ctx) error {
"contacts": contact.ID,
},
}
_, updateErr := studentCollection.UpdateOne(
_, updateErr := StudentCollection.UpdateOne(
ctx,
bson.M{"sid": data["sid"]},
update,
@@ -1121,7 +1132,7 @@ func DeleteContact(c *fiber.Ctx) error {
})
}
_, err := contactCollection.DeleteOne(ctx, bson.M{"_id": data["_id"]})
_, err := ContactCollection.DeleteOne(ctx, bson.M{"_id": data["_id"]})
if err != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
@@ -1137,3 +1148,177 @@ func DeleteContact(c *fiber.Ctx) error {
"message": "Successfully deleted contact",
})
}
func RemoveStudent(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 student id is included
if data["sid"] == "" {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
}
_, deleteErr := IdCollection.DeleteOne(ctx, bson.M{"cid": data["sid"]})
if deleteErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the identification number could not be deleted",
"error": deleteErr,
})
}
_, deleteErr = StudentCollection.DeleteOne(ctx, bson.M{"schooldata.sid": data["sid"]})
if deleteErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the student could not be deleted",
"error": deleteErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully deleted student",
})
}
func RemoveTeacher(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 student id is included
if data["tid"] == "" {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
}
_, deleteErr := IdCollection.DeleteOne(ctx, bson.M{"cid": data["tid"]})
if deleteErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the identification number could not be deleted",
"error": deleteErr,
})
}
_, deleteErr = TeacherCollection.DeleteOne(ctx, bson.M{"schooldata.tid": data["tid"]})
if deleteErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the teacher could not be deleted",
"error": deleteErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully deleted teacher",
})
}
func RemoveAdmin(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 student id is included
if data["aid"] == "" {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
}
_, deleteErr := IdCollection.DeleteOne(ctx, bson.M{"cid": data["aid"]})
if deleteErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the identification number could not be deleted",
"error": deleteErr,
})
}
_, deleteErr = AdminCollection.DeleteOne(ctx, bson.M{"aid": data["aid"]})
if deleteErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the admin could not be deleted",
"error": deleteErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully deleted admin",
})
}
+4 -4
View File
@@ -14,21 +14,21 @@ import (
"go.mongodb.org/mongo-driver/mongo"
)
var idCollection *mongo.Collection = database.OpenCollection(database.Client, "cids")
var IdCollection *mongo.Collection = database.OpenCollection(database.Client, "cids")
var table = [...]byte{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}
func ValidateID(id string, userType int) bool { // true: valid id, false: id already in use
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
var foundID models.Id
err := idCollection.FindOne(ctx, bson.M{"cid": id}).Decode(&foundID)
err := IdCollection.FindOne(ctx, bson.M{"cid": id}).Decode(&foundID)
cancel()
if err != nil { // If there is no id found create new ID object to be stored and return true (unless insert error then try again)
var newID models.Id
newID.CID = id
newID.ParentType = userType
newID.ID = primitive.NewObjectID()
_, insertErr := idCollection.InsertOne(context.Background(), newID)
_, insertErr := IdCollection.InsertOne(context.Background(), newID)
return insertErr == nil
}
return false
@@ -37,7 +37,7 @@ func ValidateID(id string, userType int) bool { // true: valid id, false: id alr
func ValidatePEN(pen string) bool { // true: valid pen, false: pen already in use
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
var foundID models.Id
err := studentCollection.FindOne(ctx, bson.M{"schooldata.pen": pen}).Decode(&foundID)
err := StudentCollection.FindOne(ctx, bson.M{"schooldata.pen": pen}).Decode(&foundID)
cancel()
return err != nil
}
+461
View File
@@ -0,0 +1,461 @@
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{
"accountdata.accountdisabled": false,
"accountdata.alerted": false,
"accountdata.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{
"accountdata.accountdisabled": false,
"accountdata.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,
})
}
+392
View File
@@ -0,0 +1,392 @@
package update
import (
"context"
"time"
. "github.com/SowinskiBraeden/school-management-api/controllers"
"github.com/gofiber/fiber/v2"
"go.mongodb.org/mongo-driver/bson"
)
func UpdateContactName(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 required fields are included
if data["_id"] == "" || data["firstname"] == "" || data["lastname"] == "" {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
}
var middlename string = ""
if data["middlename"] != "" {
middlename = data["middlename"]
}
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
update := bson.M{
"$set": bson.M{
"firstname": data["firstname"],
"middlename": middlename,
"lastname": data["lastname"],
"updated_at": update_time,
},
}
_, updateErr := ContactCollection.UpdateOne(
ctx,
bson.M{"_id": data["_id"]},
update,
)
if updateErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the contact could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated contact",
})
}
func UpdateContactAddress(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 required fields are included
if data["_id"] == "" || data["address"] == "" || data["city"] == "" || data["province"] == "" || data["postal"] == "" {
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{
"address": data["address"],
"city": data["city"],
"province": data["province"],
"postal": data["postal"],
"updated_at": update_time,
},
}
_, updateErr := ContactCollection.UpdateOne(
ctx,
bson.M{"_id": data["_id"]},
update,
)
if updateErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the contact could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated contact",
})
}
func UpdateContactHomePhone(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 id of contact and new priority number is included
if data["_id"] == "" || data["newnumber"] == "" {
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{
"homephone": data["newnumber"],
"updated_at": update_time,
},
}
_, updateErr := ContactCollection.UpdateOne(
ctx,
bson.M{"_id": data["_id"]},
update,
)
if updateErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "contact could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated contact",
})
}
func UpdateContactWorkPhone(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 id of contact and new priority number is included
if data["_id"] == "" || data["newnumber"] == "" {
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{
"workphone": data["newnumber"],
"updated_at": update_time,
},
}
_, updateErr := ContactCollection.UpdateOne(
ctx,
bson.M{"_id": data["_id"]},
update,
)
if updateErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "contact could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated contact",
})
}
func UpdateContactEmail(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 id of contact and new priority number is included
if data["_id"] == "" || 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 := ContactCollection.UpdateOne(
ctx,
bson.M{"_id": data["_id"]},
update,
)
if updateErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "contact could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated contact",
})
}
func UpdateContactPriority(c *fiber.Ctx) error {
var data map[string]interface{}
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 id of contact and new priority number is included
if data["_id"] == nil || data["priority"] == nil {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
}
var priority int = data["priority"].(int)
if priority > 10 || priority < 1 {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "invalid priority",
})
}
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
update := bson.M{
"$set": bson.M{
"priority": priority,
"updated_at": update_time,
},
}
_, updateErr := ContactCollection.UpdateOne(
ctx,
bson.M{"_id": data["_id"]},
update,
)
if updateErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "contact could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated contact",
})
}
+980
View File
@@ -0,0 +1,980 @@
package update
import (
"context"
"encoding/base64"
"fmt"
"io/ioutil"
"os"
"strings"
"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"
"github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson"
)
func toBase64(b []byte) string {
return base64.StdEncoding.EncodeToString(b)
}
func UpdateStudentName(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 id and names are included
// Middle name is optional
if data["sid"] == "" || data["firstname"] == "" || data["lastname"] == "" {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
}
var updateMiddle bool = false
if data["middlename"] != "" {
updateMiddle = true
}
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
var update bson.M
if updateMiddle {
update = bson.M{
"$set": bson.M{
"personaldata.firstname": data["firstname"],
"personaldata.middlename": data["middlename"],
"personaldata.lastname": data["lastname"],
"updated_at": update_time,
},
}
} else {
update = bson.M{
"$set": bson.M{
"personaldata.firstname": data["firstname"],
"personaldata.lastname": data["lastname"],
"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 could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated student",
"result": result,
})
}
func UpdateStudentGradeLevel(c *fiber.Ctx) error {
var data map[string]interface{}
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"] == nil || data["gradelevel"] == nil {
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{
"schooldata.gradelevel": data["gradelevel"].(float64),
"updated_at": update_time,
},
}
_, updateErr := StudentCollection.UpdateOne(
ctx,
bson.M{"schooldata.sid": data["sid"].(string)},
update,
)
if updateErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the student could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated student",
})
}
/*
Far later on this function is going to be completely automated.
Instead of an admin sending a request to update the homeroom of
a student or teacher, the system will take the room number of
the teacher's or student's Block 2 class from their schedule.
Though this function would remain for students only, for example
a student requests a course change, if its their block 2 the
admin would have to alter their homeroom to be the new class
number.
*/
func UpdateStudentHomeroom(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 required fields are included
if data["sid"] == "" || data["homeroom"] == "" {
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{
"schooldata.homeroom": data["homeroom"],
"updated_at": update_time,
},
}
_, 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 could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated student",
})
}
func UpdateStudentPassword(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 student models.Student
findErr := StudentCollection.FindOne(ctx, bson.M{"schooldata.sid": claims.Issuer}).Decode(&student)
if findErr != nil {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "student 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 !student.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 password must match",
})
}
if student.UsedPassword(data["newpassword1"]) {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "Your new password cannot be the same as a previous password",
})
}
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
update := bson.M{
"$set": bson.M{
"accountdata.password": student.HashPassword(data["newpassword1"]),
"accountdata.temppassword": false, // If it were a temp password, its not now
"updated_at": update_time,
},
"$push": bson.M{
"accountdata.hashhistory": student.HashPassword(data["newpassword1"]),
},
}
_, updateErr := StudentCollection.UpdateOne(
ctx,
bson.M{"schooldata.sid": claims.Issuer},
update,
)
if updateErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the student password could not be updated",
"error": updateErr,
})
}
defer cancel()
// Alert email the password has changed
subject := "Password Changed"
receiver := student.PersonalData.Email
r := NewRequest([]string{receiver}, subject)
if sent := r.Send("./templates/selfPasswordChanged.html", map[string]string{"username": student.PersonalData.FirstName}); !sent {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "failed to send email to student",
})
}
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated student password",
})
}
// This is for students to reset their password if they are unable to login
func ResetStudentPassword(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,
})
}
// Check required fields are included (email must be personal email)
if data["sid"] == "" || data["email"] == "" {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
}
var student models.Student
findErr := StudentCollection.FindOne(context.TODO(), bson.M{"schooldata.sid": data["sid"]}).Decode(&student)
if findErr != nil {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "student not found",
})
}
if student.PersonalData.Email != data["email"] {
cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": false,
"message": "Your personal email is incorrect",
})
}
tempPass := student.GeneratePassword(12, 1, 1, 1)
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
update := bson.M{
"$set": bson.M{
"accountdata.password": student.HashPassword(tempPass),
"accountdata.temppassword": true,
"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 password could not be updated",
"error": updateErr,
})
}
defer cancel()
// Send student personal email temp password
subject := "Password Changed"
receiver := student.PersonalData.Email
r := NewRequest([]string{receiver}, subject)
if sent := r.Send("./templates/passwordChanged.html", map[string]string{"username": student.PersonalData.FirstName, "password": tempPass}); !sent {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "Could not send password to students email",
})
}
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated student password",
"result": result,
})
}
func UpdateStudentLocker(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 id and locker are included
if data["sid"] == "" || data["lockernumber"] == "" {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
}
var locker models.Locker
err := LockerCollection.FindOne(ctx, bson.M{"lockernumber": data["lockernumber"]}).Decode(&locker)
if err != nil {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "locker not found",
"error": err,
})
}
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
update := bson.M{
"$set": bson.M{
"schooldata.locker": locker.ID,
"updated_at": update_time,
},
}
_, 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 could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated student",
})
}
func UpdateStudentAddress(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 required fields are included
if data["sid"] == "" || data["address"] == "" || data["city"] == "" || data["province"] == "" || data["postal"] == "" {
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{
"personaldata.address": data["address"],
"personaldata.city": data["city"],
"personaldata.province": data["province"],
"personaldata.postal": data["postal"],
"updated_at": update_time,
},
}
_, updateErr := StudentCollection.UpdateOne(
ctx,
bson.M{"sid": data["sid"]},
update,
)
if updateErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the student could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated student",
})
}
// In the case a student gets held back a grade, we need to update their YOG (Year of Graduation)
func UpdateStudentYOG(c *fiber.Ctx) error {
var data map[string]interface{}
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 required fields are included
if data["sid"] == "" || data["yog"] == nil {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
}
var student models.Student
findErr := StudentCollection.FindOne(context.TODO(), bson.M{"schooldata.sid": data["sid"].(string)}).Decode(&student)
if findErr != nil {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "student not found",
})
}
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
update := bson.M{
"$set": bson.M{
"schooldata.yog": data["yog"].(int),
"updated_at": update_time,
},
}
result, updateErr := StudentCollection.UpdateOne(
ctx,
bson.M{"schooldata.sid": data["sid"].(string)},
update,
)
if updateErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the student could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated student",
"result": result,
})
}
func RemoveStudentContact(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 id and contact id are included
if data["sid"] == "" || data["contactid"] == "" {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
}
var contact models.Contact
err := ContactCollection.FindOne(ctx, bson.M{"_id": data["contactid"]}).Decode(&contact)
if err != nil {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "contact not found",
"error": err,
})
}
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
update := bson.M{
"$set": bson.M{
"updated_at": update_time,
},
"$pull": bson.M{
"personaldata.contacts": contact.ID,
},
}
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 contact could not be added",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully added contact",
"result": result,
})
}
func AddStudentContact(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 id and contact id are included
if data["sid"] == "" || data["contactid"] == "" {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
}
var contact models.Contact
err := ContactCollection.FindOne(ctx, bson.M{"_id": data["contactid"]}).Decode(&contact)
if err != nil {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "contact not found",
"error": err,
})
}
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
update := bson.M{
"$set": bson.M{
"updated_at": update_time,
},
"$push": bson.M{
"personaldata.contacts": contact.ID,
},
}
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 contact could not be added",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully added contact",
"result": result,
})
}
func UpdateStudentPhoto(c *fiber.Ctx) error {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
//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",
})
}
sid := c.FormValue("sid")
if sid == "" {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
}
// Get student
var student models.Student
findErr := StudentCollection.FindOne(context.TODO(), bson.M{"schooldata.sid": sid}).Decode(&student)
if findErr != nil {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "the student could not be found",
"error": findErr,
})
}
// Collect image
file, err := c.FormFile("image")
if err != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the image could not be retrieved",
"error": err,
})
}
// Get student photo
var photo models.Photo
findErr = ImageCollection.FindOne(context.TODO(), bson.M{"name": student.SchoolData.PhotoName}).Decode(&photo)
if findErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the student image could not be found",
"error": findErr,
})
}
// Save image to local
uniqueId := uuid.New()
filename := strings.Replace(uniqueId.String(), "-", "", -1)
fileExt := strings.Split(file.Filename, ".")[1]
image := fmt.Sprintf("%s.%s", filename, fileExt)
err = c.SaveFile(file, fmt.Sprintf("./database/images/%s", image))
if err != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the image could not be saved",
"error": err,
})
}
// Read the entire file into a byte slice
bytes, err := ioutil.ReadFile(fmt.Sprintf("./database/images/%s", image))
if err != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the image could not be read",
"error": err,
})
}
var base64Encoding string = toBase64(bytes)
// Update image name and base64 data
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
update := bson.M{
"$set": bson.M{
"base64": base64Encoding,
"updated_at": update_time,
},
}
_, updateErr := ImageCollection.UpdateOne(
ctx,
bson.M{"_id": photo.ID},
update,
)
if updateErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the image could not be updated",
"error": updateErr,
})
}
defer cancel()
// Remove local image
os.Remove(fmt.Sprintf("./database/images/%s", image))
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated student photo",
})
}
func UpdateStudentEmail(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,
})
}
var sid string
var verifiedStudent bool
verifiedAdmin, _ := AuthenticateUser(c, 3)
verifiedStudent, sid = AuthenticateUser(c, 1)
// Ensure Authenticated admin sent request
if !verifiedAdmin && !verifiedStudent {
cancel()
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"success": false,
"message": "Unauthorized: only an admin or teacher can perform this action",
})
}
if verifiedAdmin && data["sid"] == "" {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
} else if verifiedAdmin {
sid = data["sid"]
}
// 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{
"personaldata.email": data["email"],
"updated_at": update_time,
},
}
result, updateErr := StudentCollection.UpdateOne(
ctx,
bson.M{"schooldata.sid": sid},
update,
)
if updateErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the student could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated student",
"result": result,
})
}
+622
View File
@@ -0,0 +1,622 @@
package update
import (
"context"
"fmt"
"io/ioutil"
"os"
"strings"
"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"
"github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson"
)
/*
Far later on this function is going to be completely automated.
Instead of an admin sending a request to update the homeroom of
a student or teacher, the system will take the room number of
the teacher's or student's Block 2 class from their schedule.
Though this function would remain for students only, for example
a student requests a course change, if its their block 2 the
admin would have to alter their homeroom to be the new class
number.
*/
func UpdateTeacherHomeroom(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 required fields are included
if data["tid"] == "" || data["homeroom"] == "" {
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{
"schooldata.homeroom": data["homeroom"],
"updated_at": update_time,
},
}
_, 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 could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated teacher",
})
}
func UpdateTeacherPassword(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 teacher models.Teacher
findErr := TeacherCollection.FindOne(ctx, bson.M{"schooldata.tid": claims.Issuer}).Decode(&teacher)
if findErr != nil {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "teacher 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 !teacher.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",
})
}
if teacher.UsedPassword(data["newpassword1"]) {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "Your new password cannot be the same as a previous password",
})
}
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
update := bson.M{
"$set": bson.M{
"accountdata.password": teacher.HashPassword(data["newpassword1"]),
"accountdata.temppassword": false, // If it were a temp password, its not now
"updated_at": update_time,
},
"$push": bson.M{
"accountdata.hashhistory": teacher.HashPassword(data["newpassword1"]),
},
}
_, updateErr := TeacherCollection.UpdateOne(
ctx,
bson.M{"schooldata.tid": claims.Issuer},
update,
)
if updateErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the teacher password could not be updated",
"error": updateErr,
})
}
defer cancel()
subject := "Password Changed"
receiver := teacher.PersonalData.Email
r := NewRequest([]string{receiver}, subject)
if sent := r.Send("./templates/selfPasswordChanged.html", map[string]string{"username": teacher.PersonalData.FirstName}); !sent {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "Could not send password to teachers email",
})
}
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated teacher password",
})
}
func ResetTeacherPassword(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,
})
}
// Check required fields are included (email must be personal email)
if data["tid"] == "" || data["email"] == "" {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
}
var teacher models.Teacher
findErr := TeacherCollection.FindOne(context.TODO(), bson.M{"schooldata.tid": data["tid"]}).Decode(&teacher)
if findErr != nil {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "teacher not found",
})
}
if teacher.PersonalData.Email != data["email"] {
cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": false,
"message": "Your personal email is incorrect",
})
}
tempPass := teacher.GeneratePassword(12, 1, 1, 1)
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
update := bson.M{
"$set": bson.M{
"accountdata.password": teacher.HashPassword(tempPass),
"accountdata.temppassword": true,
"updated_at": update_time,
},
}
result, updateErr := StudentCollection.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 password could not be updated",
"error": updateErr,
})
}
defer cancel()
// Send teacher personal email temp password
subject := "Password Changed"
receiver := teacher.PersonalData.Email
r := NewRequest([]string{receiver}, subject)
if sent := r.Send("./templates/passwordChanged.html", map[string]string{"username": teacher.PersonalData.FirstName, "password": tempPass}); !sent {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "Could not send password to teachers email",
})
}
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated teacher password",
"result": result,
})
}
func UpdateTeacherAddress(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 required fields are included
if data["tid"] == "" || data["address"] == "" || data["city"] == "" || data["province"] == "" || data["postal"] == "" {
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{
"personaldata.address": data["address"],
"personaldata.city": data["city"],
"personaldata.province": data["province"],
"personaldata.postal": data["postal"],
"updated_at": update_time,
},
}
_, 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 could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated teacher",
})
}
func UpdateTeacherPhoto(c *fiber.Ctx) error {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
//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",
})
}
tid := c.FormValue("tid")
if tid == "" {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
}
// Get teacher
var teacher models.Teacher
findErr := TeacherCollection.FindOne(context.TODO(), bson.M{"schooldata.tid": tid}).Decode(&teacher)
if findErr != nil {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "the teacher could not be found",
"error": findErr,
})
}
// Collect image
file, err := c.FormFile("image")
if err != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the image could not be retrieved",
"error": err,
})
}
// Get student photo
var photo models.Photo
findErr = ImageCollection.FindOne(context.TODO(), bson.M{"name": teacher.SchoolData.PhotoName}).Decode(&photo)
if findErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the student image could not be found",
"error": findErr,
})
}
// Save image to local
uniqueId := uuid.New()
filename := strings.Replace(uniqueId.String(), "-", "", -1)
fileExt := strings.Split(file.Filename, ".")[1]
image := fmt.Sprintf("%s.%s", filename, fileExt)
err = c.SaveFile(file, fmt.Sprintf("./database/images/%s", image))
if err != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the image could not be saved",
"error": err,
})
}
// Read the entire file into a byte slice
bytes, err := ioutil.ReadFile(fmt.Sprintf("./database/images/%s", image))
if err != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the image could not be read",
"error": err,
})
}
var base64Encoding string = toBase64(bytes)
// Update image name and base64 data
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
update := bson.M{
"$set": bson.M{
"base64": base64Encoding,
"updated_at": update_time,
},
}
_, updateErr := ImageCollection.UpdateOne(
ctx,
bson.M{"_id": photo.ID},
update,
)
if updateErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the image could not be updated",
"error": updateErr,
})
}
defer cancel()
// Remove local image
os.Remove(fmt.Sprintf("./database/images/%s", image))
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated teacher photo",
})
}
func UpdateTeacherEmail(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,
})
}
var tid string
var verifiedTeacher bool
verifiedAdmin, _ := AuthenticateUser(c, 3)
verifiedTeacher, tid = AuthenticateUser(c, 2)
// Ensure Authenticated admin sent request
if !verifiedAdmin && !verifiedTeacher {
cancel()
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"success": false,
"message": "Unauthorized: only an admin or teacher can perform this action",
})
}
if verifiedAdmin && data["tid"] == "" {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
} else if verifiedAdmin {
tid = data["tid"]
}
// 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{
"personaldata.email": data["email"],
"updated_at": update_time,
},
}
_, updateErr := TeacherCollection.UpdateOne(
ctx,
bson.M{"schooldata.tid": tid},
update,
)
if updateErr != nil {
cancel()
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"success": false,
"message": "the teacher could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated teacher",
})
}
func UpdateTeacherName(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 id and names are included
if data["tid"] == "" || data["firstname"] == "" || data["lastname"] == "" {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "missing required fields",
})
}
// Get teacher
var teacher models.Teacher
findErr := TeacherCollection.FindOne(ctx, bson.M{"schooldata.tid": data["tid"]}).Decode(&teacher)
if findErr != nil {
cancel()
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"success": false,
"message": "the teacher could not be found",
"error": findErr,
})
}
var middlename string = ""
if data["middlename"] != "" {
middlename = data["middlename"]
}
update_time, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
update := bson.M{
"$set": bson.M{
"personaldata.firstname": data["firstname"],
"personaldata.middlename": middlename,
"personaldata.lastname": data["lastname"],
"updated_at": update_time,
},
}
_, 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 could not be updated",
"error": updateErr,
})
}
defer cancel()
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"success": true,
"message": "successfully updated teacher",
})
}
File diff suppressed because it is too large. Load diff
+3 -3
View File
@@ -18,8 +18,8 @@ import (
"go.mongodb.org/mongo-driver/mongo"
)
var lockerCollection *mongo.Collection = database.OpenCollection(database.Client, "lockers")
var studentCollection *mongo.Collection = database.OpenCollection(database.Client, "students")
var LockerCollection *mongo.Collection = database.OpenCollection(database.Client, "lockers")
var StudentCollection *mongo.Collection = database.OpenCollection(database.Client, "students")
type Student struct {
ID primitive.ObjectID `bson:"_id"`
@@ -75,7 +75,7 @@ func (s *Student) HashPassword(password string) string {
func (s *Student) EmailExists(email string) bool {
var student Student
findErr := studentCollection.FindOne(context.TODO(), bson.M{"accountdata.schoolemail": email}).Decode(&student)
findErr := StudentCollection.FindOne(context.TODO(), bson.M{"accountdata.schoolemail": email}).Decode(&student)
if findErr != nil {
return false
}
+2 -2
View File
@@ -24,7 +24,7 @@ var (
allCharSet = lowerCharSet + upperCharSet + specialCharSet + numberSet
)
var teacherCollection *mongo.Collection = database.OpenCollection(database.Client, "teachers")
var TeacherCollection *mongo.Collection = database.OpenCollection(database.Client, "teachers")
type Teacher struct {
ID primitive.ObjectID `bson:"_id"`
@@ -73,7 +73,7 @@ func (t *Teacher) HashPassword(password string) string {
func (t *Teacher) EmailExists(email string) bool {
var teacher Teacher
findErr := teacherCollection.FindOne(context.TODO(), bson.M{"accountdata.schoolemail": email}).Decode(&teacher)
findErr := TeacherCollection.FindOne(context.TODO(), bson.M{"accountdata.schoolemail": email}).Decode(&teacher)
if findErr != nil {
return false
}
+32 -31
View File
@@ -2,6 +2,7 @@ package routes
import (
"github.com/SowinskiBraeden/school-management-api/controllers"
"github.com/SowinskiBraeden/school-management-api/controllers/update"
"github.com/gofiber/fiber/v2"
)
@@ -27,27 +28,27 @@ func Setup(app *fiber.App) {
app.Post(routerPrefix+"/student/login", controllers.StudentLogin)
// Update Student Handler
app.Post(routerPrefix+"/student/updateName", controllers.UpdateStudentName)
app.Post(routerPrefix+"/student/updateGradeLevel", controllers.UpdateStudentGradeLevel)
app.Post(routerPrefix+"/student/updateHomeroom", controllers.UpdateStudentHomeroom)
app.Post(routerPrefix+"/student/updateLocker", controllers.UpdateStudentLocker)
app.Post(routerPrefix+"/studnet/updateYOG", controllers.UpdateStudentYOG)
app.Post(routerPrefix+"/studnet/addContact", controllers.AddStudentContact)
app.Post(routerPrefix+"/student/removeContact", controllers.RemoveStudentContact)
app.Post(routerPrefix+"/student/updatePassword", controllers.UpdateStudentPassword)
app.Post(routerPrefix+"/student/resetPassword", controllers.ResetStudentPassword)
app.Post(routerPrefix+"/student/updateAddress", controllers.UpdateStudentAddress)
app.Post(routerPrefix+"/student/updatePhoto", controllers.UpdateStudentPhoto)
app.Post(routerPrefix+"/student/updateEmail", controllers.UpdateStudentEmail)
app.Post(routerPrefix+"/student/updateName", update.UpdateStudentName)
app.Post(routerPrefix+"/student/updateGradeLevel", update.UpdateStudentGradeLevel)
app.Post(routerPrefix+"/student/updateHomeroom", update.UpdateStudentHomeroom)
app.Post(routerPrefix+"/student/updateLocker", update.UpdateStudentLocker)
app.Post(routerPrefix+"/studnet/updateYOG", update.UpdateStudentYOG)
app.Post(routerPrefix+"/studnet/addContact", update.AddStudentContact)
app.Post(routerPrefix+"/student/removeContact", update.RemoveStudentContact)
app.Post(routerPrefix+"/student/updatePassword", update.UpdateStudentPassword)
app.Post(routerPrefix+"/student/resetPassword", update.ResetStudentPassword)
app.Post(routerPrefix+"/student/updateAddress", update.UpdateStudentAddress)
app.Post(routerPrefix+"/student/updatePhoto", update.UpdateStudentPhoto)
app.Post(routerPrefix+"/student/updateEmail", update.UpdateStudentEmail)
// Student Contact Handler
app.Post(routerPrefix+"/contact/createContact", controllers.CreateContact)
app.Post(routerPrefix+"/contact/updateName", controllers.UpdateContactName)
app.Post(routerPrefix+"/contact/updateAddress", controllers.UpdateContactAddress)
app.Post(routerPrefix+"/contact/updateHomePhone", controllers.UpdateContactHomePhone)
app.Post(routerPrefix+"/contact/updateWorkPhone", controllers.UpdateContactWorkPhone)
app.Post(routerPrefix+"/contact/updateEmail", controllers.UpdateContactEmail)
app.Post(routerPrefix+"/contact/updatePriority", controllers.UpdateContactPriority)
app.Post(routerPrefix+"/contact/updateName", update.UpdateContactName)
app.Post(routerPrefix+"/contact/updateAddress", update.UpdateContactAddress)
app.Post(routerPrefix+"/contact/updateHomePhone", update.UpdateContactHomePhone)
app.Post(routerPrefix+"/contact/updateWorkPhone", update.UpdateContactWorkPhone)
app.Post(routerPrefix+"/contact/updateEmail", update.UpdateContactEmail)
app.Post(routerPrefix+"/contact/updatePriority", update.UpdateContactPriority)
app.Post(routerPrefix+"/contact/deleteContact", controllers.DeleteContact)
// Teacher Authentication Handler
@@ -56,13 +57,13 @@ func Setup(app *fiber.App) {
app.Post(routerPrefix+"/teacher/login", controllers.TeacherLogin)
// Teacher Update Handler
app.Post(routerPrefix+"/teacher/updatePassword", controllers.UpdateTeacherPassword)
app.Post(routerPrefix+"/teacher/updateAddress", controllers.UpdateTeacherAddress)
app.Post(routerPrefix+"/teacher/updatePhoto", controllers.UpdateTeacherPhoto)
app.Post(routerPrefix+"/teacher/updateName", controllers.UpdateTeacherName)
app.Post(routerPrefix+"/teacher/updateHomeroom", controllers.UpdateTeacherHomeroom)
app.Post(routerPrefix+"/teacher/updateEmail", controllers.UpdateTeacherEmail)
app.Post(routerPrefix+"/teacher/resetPassword", controllers.ResetTeacherPassword)
app.Post(routerPrefix+"/teacher/updatePassword", update.UpdateTeacherPassword)
app.Post(routerPrefix+"/teacher/updateAddress", update.UpdateTeacherAddress)
app.Post(routerPrefix+"/teacher/updatePhoto", update.UpdateTeacherPhoto)
app.Post(routerPrefix+"/teacher/updateName", update.UpdateTeacherName)
app.Post(routerPrefix+"/teacher/updateHomeroom", update.UpdateTeacherHomeroom)
app.Post(routerPrefix+"/teacher/updateEmail", update.UpdateTeacherEmail)
app.Post(routerPrefix+"/teacher/resetPassword", update.ResetTeacherPassword)
// General Routes
app.Post(routerPrefix+"/logout", controllers.Logout)
@@ -73,14 +74,14 @@ func Setup(app *fiber.App) {
app.Post(routerPrefix+"/admin/login", controllers.AdminLogin)
// Admin Update Handler
app.Post(routerPrefix+"/admin/updateName", controllers.UpdateAdminName)
app.Post(routerPrefix+"/admin/updateEmail", controllers.UpdateAdminEmail)
app.Post(routerPrefix+"/admin/updatePassword", controllers.UpdateAdminPassword)
app.Post(routerPrefix+"/admin/updateName", update.UpdateAdminName)
app.Post(routerPrefix+"/admin/updateEmail", update.UpdateAdminEmail)
app.Post(routerPrefix+"/admin/updatePassword", update.UpdateAdminPassword)
// General Command Handling
app.Post(routerPrefix+"/admin/updateLockerCombo", controllers.UpdateLockerCombo)
app.Post(routerPrefix+"/admin/enableStudent", controllers.RemoveStudentsDisabled)
app.Post(routerPrefix+"/admin/enableTeacher", controllers.RemoveTeachersDisabled)
app.Post(routerPrefix+"/admin/updateLockerCombo", update.UpdateLockerCombo)
app.Post(routerPrefix+"/admin/enableStudent", update.RemoveStudentsDisabled)
app.Post(routerPrefix+"/admin/enableTeacher", update.RemoveTeachersDisabled)
// Delete Handler
app.Post(routerPrefix+"/remove/student", controllers.RemoveStudent)
+1
View File
@@ -0,0 +1 @@
dot_import_whitelist = ["github.com/SowinskiBraeden/school-management-api/controllers"]