diff --git a/occupi-backend/pkg/database/database.go b/occupi-backend/pkg/database/database.go index 3c48ecd1..b99730cb 100644 --- a/occupi-backend/pkg/database/database.go +++ b/occupi-backend/pkg/database/database.go @@ -128,10 +128,11 @@ func ConfirmCheckIn(ctx *gin.Context, db *mongo.Client, checkIn models.CheckIn) // Save the check-in to the database collection := db.Database("Occupi").Collection("RoomBooking") - // Find the booking by bookingId, roomId, and check if the email is in the emails object + // Find the booking by bookingId, roomId, and creator filter := bson.M{ - "_id": checkIn.BookingID, - "roomId": checkIn.RoomID, + "_id": checkIn.BookingID, + "roomId": checkIn.RoomID, + "creator": checkIn.Creator, } // Find the booking @@ -145,15 +146,6 @@ func ConfirmCheckIn(ctx *gin.Context, db *mongo.Client, checkIn models.CheckIn) logrus.Error("Failed to find booking:", err) return false, err } - emailToCheck := checkIn.Email - for _, email := range booking.Emails { - if email == emailToCheck { - break - } - // If we finish the loop without finding the email - logrus.Error("Email not associated with the room") - return false, errors.New("email not associated with the room") - } update := bson.M{ "$set": bson.M{"checkedIn": true}, diff --git a/occupi-backend/pkg/handlers/api_handlers.go b/occupi-backend/pkg/handlers/api_handlers.go index c6b60493..9d687be7 100644 --- a/occupi-backend/pkg/handlers/api_handlers.go +++ b/occupi-backend/pkg/handlers/api_handlers.go @@ -8,6 +8,7 @@ import ( "github.com/COS301-SE-2024/occupi/occupi-backend/pkg/constants" "github.com/COS301-SE-2024/occupi/occupi-backend/pkg/database" "github.com/COS301-SE-2024/occupi/occupi-backend/pkg/models" + "github.com/go-playground/validator/v10" "go.mongodb.org/mongo-driver/bson/primitive" "github.com/COS301-SE-2024/occupi/occupi-backend/pkg/mail" @@ -53,13 +54,24 @@ func FetchResourceAuth(ctx *gin.Context, appsession *models.AppSession) { func BookRoom(ctx *gin.Context, appsession *models.AppSession) { // consider structuring api responses to match that as outlined in our coding standards documentation //link: https://cos301-se-2024.github.io/occupi/coding-standards/go-coding-standards#response-and-error-handling - var booking models.Booking if err := ctx.ShouldBindJSON(&booking); err != nil { ctx.JSON(http.StatusBadRequest, utils.ErrorResponse(http.StatusBadRequest, "Invalid request payload", constants.InvalidRequestPayloadCode, "Expected RoomID,Slot,Emails[],Creator,FloorNo ", nil)) return } - + // Initialize the validator + validate := validator.New() + + // Validate the booking struct + if err := validate.Struct(booking); err != nil { + validationErrors := err.(validator.ValidationErrors) + errorDetails := make(gin.H) + for _, validationError := range validationErrors { + errorDetails[validationError.Field()] = validationError.Tag() + } + ctx.JSON(http.StatusBadRequest, utils.ErrorResponse(http.StatusBadRequest, "Validation failed", constants.InvalidRequestPayloadCode, "Validation errors occurred", errorDetails)) + return + } // Generate a unique ID for the booking booking.ID = primitive.NewObjectID().Hex() booking.OccupiID = utils.GenerateBookingID() @@ -148,7 +160,7 @@ func CheckIn(ctx *gin.Context, appsession *models.AppSession) { var checkIn models.CheckIn if err := ctx.ShouldBindJSON(&checkIn); err != nil { - ctx.JSON(http.StatusBadRequest, utils.ErrorResponse(http.StatusBadRequest, "Invalid request payload", constants.InvalidRequestPayloadCode, "Expected Booking ID, Room ID, and Email Address", nil)) + ctx.JSON(http.StatusBadRequest, utils.ErrorResponse(http.StatusBadRequest, "Invalid request payload", constants.InvalidRequestPayloadCode, "Expected Booking ID, Room ID, and Creator Email Address", nil)) return } diff --git a/occupi-backend/pkg/models/database.go b/occupi-backend/pkg/models/database.go index 0f028712..58803367 100644 --- a/occupi-backend/pkg/models/database.go +++ b/occupi-backend/pkg/models/database.go @@ -18,13 +18,13 @@ type User struct { type Booking struct { ID string `json:"_id" bson:"_id,omitempty"` OccupiID string `json:"occupiId" bson:"occupiId,omitempty"` - RoomID string `json:"roomId" bson:"roomId"` - RoomName string `json:"roomName" bson:"roomName,omitempty"` - Slot int `json:"slot" bson:"slot"` - Emails []string `json:"emails" bson:"emails"` - CheckedIn bool `json:"checkedIn" bson:"checkedIn,omitempty"` - Creator string `json:"creator" bson:"creator"` - FloorNo int `json:"floorNo" bson:"floorNo"` + RoomID string `json:"roomId" bson:"roomId" validate:"required"` + RoomName string `json:"roomName" bson:"roomName" validate:"required"` + Slot int `json:"slot" bson:"slot" validate:"required,min=1"` + Emails []string `json:"emails" bson:"emails" validate:"required,dive,email"` + CheckedIn bool `json:"checkedIn" bson:"checkedIn"` + Creator string `json:"creator" bson:"creator" validate:"required,email"` + FloorNo int `json:"floorNo" bson:"floorNo" validate:"required"` Date time.Time `json:"date" bson:"date,omitempty"` Start time.Time `json:"start" bson:"start,omitempty"` End time.Time `json:"end" bson:"end,omitempty"` @@ -33,7 +33,7 @@ type Booking struct { // structure of CheckIn type CheckIn struct { BookingID string `json:"bookingId" bson:"bookingId"` - Email string `json:"email" bson:"email"` + Creator string `json:"creator" bson:"creator"` RoomID string `json:"roomId" bson:"roomId"` }