public IActionResult AddReservation([FromServices] IEmailService emailservice, DateTime StartTime, DateTime EndTime, string Description, int RoomID, bool Force = false)
        {
            if (StartTime == null || EndTime == null || Description == null)
            {
                return(BadRequest("Fields missing"));
            }
            if (StartTime > EndTime)
            {
                return(BadRequest("StartTime is before EndTime"));
            }
            var rooms = _context.Rooms.Where(x => x.Id == RoomID);

            if (!rooms.Any())
            {
                return(BadRequest("Room does not exist"));
            }
            var room  = rooms.First();
            var Owner = Models.User.FromClaims(User.Claims, _context);

            lock (_context.ReservationLock) //lock all intersection checking and reservation writing logic to prevent changes to the database during the checking phase
            {
                var intersections = FindIntersections(StartTime, EndTime, room);
                if (intersections.Count() == 0) //No intersections with other reservations, add it
                {
                    return(Ok(createreservation(StartTime, EndTime, Description, Owner, room).ToString()));
                }
                if (!intersections.All(x => x.IsMutable == true)) //intersection with an immutable reservation
                {
                    return(new ObjectResult("Conflict: Overlaps with an immutable reservation.")
                    {
                        StatusCode = 409
                    });
                }
                if (!Force)
                {
                    return(new ObjectResult("Conflict: There is overlap with existing reservations, please set 'Force' to true in your request if you wish to forcibly insert it.")
                    {
                        StatusCode = 409
                    });
                }
                if (Authorization.AIsBOrHigher(Owner.Role, Role.ServiceDesk)) //service desk or higher can always forcibly add reservations
                {
                    return(Ok(OverrideAddReservation(emailservice, intersections, StartTime, EndTime, Description, Owner, room).ToString()));
                }
                var _intersectionowners      = (from x in intersections select x.Participants).SelectMany(x => x).Where(x => x.IsOwner).Select(x => x.UserID);
                var _intersectionownerLevels = (from x in _intersectionowners select _context.Users.Where(z => z.Id == x).First().Role);
                if (!_intersectionownerLevels.All(x => Authorization.AIsHigherThanB(Owner.Role, x))) //intersections with reservation from people of higher or equal level
                {
                    return(new ObjectResult("Conflict: Overlaps with a reservation with owner of equal or higher level.")
                    {
                        StatusCode = 409
                    });
                }
                return(Ok(OverrideAddReservation(emailservice, intersections, StartTime, EndTime, Description, Owner, room).ToString())); //intersections with reservations from people with lower level
            }
        }
Пример #2
0
        public IActionResult ChangeReservation(int ReservationID, DateTime?StartTime, DateTime?EndTime, string Description, int?RoomID, bool?isactive, bool Force = false)
        {
            User actor = Models.User.FromClaims(User.Claims);
            Room room  = null;

            if (RoomID.HasValue)
            {
                room = _context.Rooms.Find(RoomID.Value);
                if (room == null)
                {
                    Response.StatusCode = 400;
                    return(Content("RoomID could not be found"));
                }
            }
            lock (ReservationLock)
            {
                var         _reservation = _context.Reservations.Where(x => x.Id == ReservationID).Include(x => x.Participants);
                Reservation reservation  = null;
                if (_reservation.Count() != 0)
                {
                    Response.StatusCode = 400;
                    return(Content("Reservation could not be found"));
                }
                reservation = _reservation.First();

                if (reservation.Participants.Where(x => x.IsOwner).Where(x => x.UserID == actor.Id).Count() != 1)
                {
                    if (!Authorization.AIsBOrHigher(actor.Role, Role.ServiceDesk))
                    {
                        Response.StatusCode = 401;
                        return(Content("You are not an owner of this reservation, nor are you a service desk employee or higher."));
                    }
                }

                var reservationchange = reservation.GenerateChangeCopy(actor);

                DateTime start;
                if (StartTime.HasValue)
                {
                    start = StartTime.Value;
                }
                else
                {
                    start = reservation.StartDate;
                }
                DateTime end;
                if (EndTime.HasValue)
                {
                    end = EndTime.Value;
                }
                else
                {
                    end = reservation.EndDate;
                }

                if (start > end)
                {
                    Response.StatusCode = 400;
                    return(Content("Startdate cannot come before end date"));
                }

                var intersections = FindIntersections(start, end);
                if (intersections.Count() <= 1)
                {
                    return(_ChangeReservation(isactive, reservation, start, end, room, Description, reservationchange));
                }
                else
                {
                    intersections = intersections.Where(x => x.Id != reservation.Id); //remove self
                    if (!Force)
                    {
                        Response.StatusCode = 400;
                        return(Content("There is overlap with existing reservations, please set 'Force' to true in your request if you wish to forcibly insert it."));
                    }
                    if (Authorization.AIsBOrHigher(actor.Role, Role.ServiceDesk)) //service desk or higher can always forcibly change reservations
                    {
                        return(_ForceChangeReservation(isactive, reservation, start, end, room, Description, reservationchange, actor, intersections));
                    }
                    var _intersectionowners      = (from x in intersections select x.Participants).SelectMany(x => x).Where(x => x.IsOwner).Select(x => x.UserID);
                    var _intersectionownerLevels = (from x in _intersectionowners select _context.Users.Find(x).Role);
                    if (!_intersectionownerLevels.All(x => Authorization.AIsHigherThanB(actor.Role, x))) //intersections with reservation from people of higher or equal level
                    {
                        Response.StatusCode = 400;
                        return(Content("Overlaps with a reservation with owner of equal or higher level."));
                    }
                    return(_ForceChangeReservation(isactive, reservation, start, end, room, Description, reservationchange, actor, intersections)); //intersections with reservations from people with lower level
                }
            }
        }
        public IActionResult ChangeReservation([FromServices] IEmailService emailservice, int ReservationID, DateTime?StartTime, DateTime?EndTime, string Description, int?RoomID, bool?isactive, bool Force = false)
        {
            User actor = Models.User.FromClaims(User.Claims, _context);
            Room room  = null;

            if (RoomID.HasValue)
            {
                var rooms = _context.Rooms.Where(x => x.Id == RoomID.Value);
                if (!rooms.Any())
                {
                    return(BadRequest("RoomID could not be found"));
                }
                room = rooms.First();
            }
            lock (_context.ReservationLock)
            {
                var         _reservation = _context.Reservations.Where(x => x.Id == ReservationID).Include(x => x.Participants).Include(x => x.Room);
                Reservation reservation  = null;
                if (_reservation.Count() == 0)
                {
                    return(BadRequest("Reservation could not be found"));
                }
                reservation = _reservation.First();
                if (room == null)
                {
                    room = reservation.Room;
                }

                if (reservation.Participants.Where(x => x.IsOwner).Where(x => x.UserID == actor.Id).Count() != 1)
                {
                    if (!Authorization.AIsBOrHigher(actor.Role, Role.ServiceDesk))
                    {
                        return(Unauthorized());
                    }
                }

                var reservationchange = reservation.GenerateChangeCopy(actor);

                DateTime start;
                if (StartTime.HasValue)
                {
                    start = StartTime.Value;
                }
                else
                {
                    start = reservation.StartDate;
                }
                DateTime end;
                if (EndTime.HasValue)
                {
                    end = EndTime.Value;
                }
                else
                {
                    end = reservation.EndDate;
                }

                if (start > end)
                {
                    return(BadRequest("Startdate cannot come before end date"));
                }

                var intersections = FindIntersections(start, end, room);
                if (intersections.Count() <= 0)
                {
                    return(_ChangeReservation(emailservice, actor, isactive, reservation, start, end, room, Description, reservationchange));
                }
                else if (intersections.Count() == 1 && intersections.First() == reservation)
                {
                    return(_ChangeReservation(emailservice, actor, isactive, reservation, start, end, room, Description, reservationchange));
                }
                else
                {
                    intersections = intersections.Where(x => x.Id != reservation.Id); //remove self
                    if (!Force)
                    {
                        return(new ObjectResult("Conflict: There is overlap with existing reservations, please set 'Force' to true in your request if you wish to forcibly insert it.")
                        {
                            StatusCode = 409
                        });
                    }
                    if (Authorization.AIsBOrHigher(actor.Role, Role.ServiceDesk)) //service desk or higher can always forcibly change reservations
                    {
                        return(_ForceChangeReservation(emailservice, isactive, reservation, start, end, room, Description, reservationchange, actor, intersections));
                    }
                    var isOwnerOfIntersections   = intersections.Select(x => x.Participants.Select(z => z.UserID).Contains(actor.Id)).All(x => x);
                    var _intersectionowners      = (from x in intersections select x.Participants).SelectMany(x => x).Where(x => x.IsOwner).Select(x => x.UserID);
                    var _intersectionownerLevels = (from x in _intersectionowners select _context.Users.Where(z => z.Id == x).First().Role);
                    if (isOwnerOfIntersections || _intersectionownerLevels.All(x => Authorization.AIsHigherThanB(actor.Role, x)))                                     //intersections with reservation from people of higher or equal level
                    {
                        return(_ForceChangeReservation(emailservice, isactive, reservation, start, end, room, Description, reservationchange, actor, intersections)); //intersections with reservations from people with lower level
                    }
                    return(Unauthorized());
                }
            }
        }