public override void OnAuthorization(HttpActionContext actionContext)
        {
            base.OnAuthorization(actionContext);

              var authResult = AuthorizationActions.Authorize(actionContext.Request, this.DefaultAuthRoles);
              ApiResponse response = new ApiResponse(actionContext.Request);
              if (authResult != AuthorizationResult.Success)
              {
            if (authResult == AuthorizationResult.MismatchedUser || authResult == AuthorizationResult.ExpiredToken ||
            authResult == AuthorizationResult.InvalidRequest || authResult == AuthorizationResult.InvalidToken)
            {
              response.errors.Add(new InvalidToken());
            }
            else if (authResult == AuthorizationResult.Unauthorized)
            {
              response.errors.Add(new NoAccess());
            }

            //return invalid token
            actionContext.Response = response.GenerateResponse(HttpStatusCode.Forbidden, new Dictionary<string, string>
            {
            { "authToken", "-1" }
            });
              }

              base.OnAuthorization(actionContext);
        }
        public HttpResponseMessage CheckIn(PatronViewModel checkIn)
        {
            ApiResponse response = new ApiResponse(Request);
            if (checkIn == null)
            {
                response.errors.Add(new NullRequest());
                return response.GenerateResponse(HttpStatusCode.BadRequest);
            }
            try
            {
                using (var database = new Database())
                {
                    var volunteerName = Request.Headers.GetHeaderValue("username");
                    var volunteer = database.Volunteers.FirstOrDefault(v => v.Username == volunteerName);
                    var serviceType = database.ServiceTypes.FirstOrDefault(st => st.ID == checkIn.ServiceSelection);
                    Patron patron;
                    if (checkIn.ID > -1)
                    {
                        patron = database.Patrons
                            .Include(p => p.Gender)
                            .Include(p => p.Addresses)
                            .Include(p => p.EmergencyContacts)
                            .Include(p => p.Ethnicity)
                            .Include(p => p.MaritalStatus)
                            .Include(p => p.PhoneNumbers)
                            .Include(p => p.ResidenceStatus)
                            .First(p => p.ID == checkIn.ID);
                        patron.Addresses = checkIn.Addresses;
                        patron.EmergencyContacts = checkIn.EmergencyContacts;
                        patron.PhoneNumbers = checkIn.PhoneNumbers;
                    }
                    else
                    {
                        patron = JsonConvert.DeserializeObject<Patron>(JsonConvert.SerializeObject(checkIn)); //You can move values up an inheritance chain!
                    }
                    patron.Ethnicity = database.Ethnicities.FirstOrDefault(et => et.ID == (int)checkIn.ethnicityID);
                    patron.Gender = database.Genders.FirstOrDefault(gt => gt.ID == (int)checkIn.genderID);
                    patron.ResidenceStatus = database.ResidenceStatuses.FirstOrDefault(rt => rt.ID == (int)checkIn.residenceStatusID);
                    patron.MaritalStatus = database.MaritalStatuses.FirstOrDefault(mt => mt.ID == (int)checkIn.maritalStatusID);

                    database.Patrons.AddOrUpdate(patron);
                    database.SaveChanges();
                    Visit visit = new Visit
                    {
                        CreateVolunteer = volunteer,
                        Service = serviceType,
                        Patron = patron
                    };
                    database.Visits.Add(visit);
                    database.SaveChanges();
                    return response.GenerateResponse(HttpStatusCode.Created);
                }
            }
            catch(Exception e)
            {
                response.errors.Add(new InvalidCheckIn { source = e });
                return response.GenerateResponse(HttpStatusCode.BadRequest);
            }
        }
        public HttpResponseMessage GetRoles()
        {
            var response = new ApiResponse(Request)
            {
                data = new {roles = Enum.GetValues(typeof (RoleID)).ToList().Select(EnumViewModel.ParseEnum)}
            };

            return response.GenerateResponse(HttpStatusCode.OK);
        }
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            var isAuthorized = AuthorizationActions.Authorize(actionContext.Request, this.DefaultAuthRoles);
            if(!isAuthorized)
            {
                ApiResponse response = new ApiResponse(actionContext.Request);
                response.errors.Add(new NoAccess());
                actionContext.Response = response.GenerateResponse(HttpStatusCode.Forbidden);
            }

            base.OnAuthorization(actionContext);
        }
 public HttpResponseMessage GetEnums()
 {
     ApiResponse response = new ApiResponse(Request)
     {
         data = new
         {
             Services = Enum.GetValues(typeof(ServiceTypeID)).ToList().Select(EnumViewModel.ParseEnum),
             Ethnicities = Enum.GetValues(typeof(EthnicityID)).ToList().Select(EnumViewModel.ParseEnum),
             Genders = Enum.GetValues(typeof(GenderID)).ToList().Select(EnumViewModel.ParseEnum),
             MaritalStatuses = Enum.GetValues(typeof(MaritalStatusID)).ToList().Select(EnumViewModel.ParseEnum),
             ResidenceStatuses = Enum.GetValues(typeof(ResidenceStatusID)).ToList().Select(EnumViewModel.ParseEnum),
             roles = Enum.GetValues(typeof(RoleID)).ToList().Select(EnumViewModel.ParseEnum)
         }
     };
     return response.GenerateResponse(HttpStatusCode.OK);
 }
        public HttpResponseMessage Create(Patron patron)
        {
            ApiResponse response = new ApiResponse(Request);
            try
            {
                var patronContext = new Database();
                patronContext.Patrons.Add(patron);
                patronContext.SaveChanges();

                response.data = response.DefaultSuccessResponse;
                return response.GenerateResponse(HttpStatusCode.Created);
            }
            catch(Exception e)
            {
                response.errors.Add(new InvalidPatron { source = e });
                return response.GenerateResponse(HttpStatusCode.BadRequest);
            }
        }
        public HttpResponseMessage CreateVolunteer([FromBody] Volunteer volunteer)
        {
            ApiResponse response = new ApiResponse(Request);

            try
            {
                volunteer.SecurePassword();
                var volunteerContext = new Database();
                volunteerContext.Volunteers.Add(volunteer);
                volunteerContext.SaveChanges();

                response.data = response.DefaultSuccessResponse;
                return response.GenerateResponse(HttpStatusCode.Created);
            }
            catch (Exception e)
            {
                response.errors.Add(new InvalidVolunteer { source = e });
                return response.GenerateResponse(HttpStatusCode.BadRequest);
            }
        }
        public HttpResponseMessage Login([FromBody] Volunteer volunteer)
        {
            ApiResponse response = new ApiResponse(Request);
            var volunteerContext = new Database();
            var foundVolunteer = volunteerContext.Volunteers.Find(volunteer.Username);

            if (foundVolunteer == null)
            {
                response.errors.Add(new InvalidUsernameOrPassword());
                return response.GenerateResponse(HttpStatusCode.BadRequest);
            }

            var passwordResult = foundVolunteer.VerifyPassword(volunteer.Password);
            if(passwordResult == PasswordVerificationResult.SuccessRehashNeeded)
            {
                foundVolunteer.Password = PasswordHasher.EncryptPassword(volunteer.Password);
                passwordResult = PasswordVerificationResult.Success;
            }
            if (passwordResult == PasswordVerificationResult.Success)
            {
                var authTokenID = Guid.NewGuid();
                var authToken = new AuthenticationToken
                {
                    Token = authTokenID,
                    AssociatedVolunteer = foundVolunteer
                };
                var authTokenContext = volunteerContext;
                authTokenContext.AuthenticationTokens.Add(authToken);
                authTokenContext.SaveChanges();

                return response.GenerateResponse(HttpStatusCode.OK, new Dictionary<string, string>
                {
                    {"authToken", authTokenID.ToString()}
                });
            }
            else
            {
                response.errors.Add(new InvalidUsernameOrPassword());
                return response.GenerateResponse(HttpStatusCode.BadRequest);
            }
        }
        public HttpResponseMessage GetPatronData(ReportingPatronViewModel reportingParams)
        {
            using (var db = new Database())
              {
            var response = new ApiResponse(Request);
            try
            {
              var servicesWanted = reportingParams.ServiceTypeSelections.Select(st => st.ID).ToArray();
              var services = db.Visits
            .Include(v => v.Patron)
            .Include(v => v.Service.ID)
            .Where(v => v.Patron.ID == reportingParams.ID && servicesWanted.Contains(v.Service.ID))
            .ToList();

              response.data = services;
              return response.GenerateResponse(HttpStatusCode.OK);
            }
            catch (Exception e)
            {
              response.errors.Add(new DatabaseFailure(e));
              return response.GenerateResponse(HttpStatusCode.InternalServerError);
            }
              }
        }
        public HttpResponseMessage FindPatron(dynamic data)
        {
            DateTime PatronDoB = DateTime.MinValue;
            try
            {
                DateTime.TryParse(data.dateOfBirth, out PatronDoB);
            }
            catch(Exception e) { }
            Patron searchData = new Patron
            {
                FirstName = data.firstName,
                MiddleName = data.middleName,
                LastName = data.lastName,
                DateOfBirth = PatronDoB
            };
            ApiResponse response = new ApiResponse(Request);
            try
            {
                using (var patronContext = new Database())
                {
                    var patrons = patronContext.Patrons.Where(
                        p =>
                            p.FirstName.ToLower().Contains(searchData.FirstName.ToLower()) ||
                            p.MiddleName.ToLower().Contains(searchData.MiddleName.ToLower()) ||
                            p.LastName.ToLower().Contains(searchData.LastName.ToLower()) ||
                            p.DateOfBirth.ToString().Contains(searchData.DateOfBirth.ToString()))
                        .Include(p => p.MaritalStatus)
                        .Include(p => p.Ethnicity)
                        .Include(p => p.Gender)
                        .Include(p => p.ResidenceStatus)
                        .Include(p => p.EmergencyContacts)
                        .Include(p => p.PhoneNumbers)
                        .Include(p => p.Addresses)
                        .Include(p => p.Visits.Select(v => v.Service))
                    .ToList();

                    response.data = patrons;

                    return response.GenerateResponse(HttpStatusCode.OK);
                }
            }
            catch (Exception e)
            {
                response.errors.Add(new InvalidPatron { source = e });
                return response.GenerateResponse(HttpStatusCode.BadRequest);
            }
        }
        public HttpResponseMessage GetServiceData(ReportingServiceViewModel reportingParams)
        {
            ApiResponse response = new ApiResponse(Request);
              using (var db = new Database())
              {
            if (reportingParams.TimePeriod == "Today")
            {
              reportingParams.StartDate = DateTime.UtcNow.AbsoluteStart();
              reportingParams.EndDate = DateTime.UtcNow.AbsoluteEnd();
            }
            else if (reportingParams.TimePeriod == "Specific Date")
            {
              reportingParams.StartDate = reportingParams.StartDate.ToUniversalTime().AbsoluteStart();
              reportingParams.EndDate = reportingParams.StartDate.ToUniversalTime().AbsoluteEnd();
            }
            else if (reportingParams.TimePeriod == "Date Range")
            {
              reportingParams.StartDate = reportingParams.StartDate.ToUniversalTime().AbsoluteStart();
              reportingParams.EndDate = reportingParams.EndDate.ToUniversalTime().AbsoluteEnd();
            }
            else if (reportingParams.TimePeriod == "All Time")
            {
              reportingParams.StartDate = DateTime.MinValue;
              reportingParams.EndDate = DateTime.MaxValue;
            }
            else
            {
              response.errors.Add(new InvalidTimePeroid());
              return response.GenerateResponse(HttpStatusCode.BadRequest);
            }

            var serviceTypeIDs = reportingParams.ServiceTypeSelections.Select(st => st.ID).ToList();

            var report = db.Visits
            .Include(v => v.Service)
            .Include(v => v.Patron)
            .Include(v => v.Patron.ResidenceStatus)
            .Include(v => v.Patron.MaritalStatus)
            .Include(v => v.Patron.Gender)
            .Include(v => v.Patron.Ethnicity)
            .Include(v => v.Patron.Addresses)
            .Include(v => v.CreateVolunteer)
            .Where(v =>
              v.CreateDate >= reportingParams.StartDate && v.CreateDate <= reportingParams.EndDate &&
              !string.IsNullOrEmpty(reportingParams.ZipCode) ? v.Patron.Addresses.Count(a => a.Zip.Contains(reportingParams.ZipCode) || reportingParams.ZipCode.Contains(a.Zip)) > 0 : true &&
              serviceTypeIDs.Contains(v.Service.ID)
            ).ToList()
            .Select(v => new
            {
              VisitDate = v.CreateDate,
              VolunteerLastName = v.CreateVolunteer.FirstName,
              VolunteerFirstName = v.CreateVolunteer.LastName,
              PatronFirstName = v.Patron.FirstName,
              PatronMiddleName = v.Patron.MiddleName,
              PatronLastName = v.Patron.LastName,
              Service = v.Service.ServiceName,
              MaritalStatus = v.Patron.MaritalStatus.Name,
              Gender = v.Patron.Gender.Name,
              Ethnicity = v.Patron.Ethnicity.Name,
              Addresses =  string.Join(" | ", v.Patron.Addresses.Select(a => $"{a.StreetAddress} {a.City} {a.State} {a.Zip}"))
            });

            response.data = report;

            return response.GenerateResponse(HttpStatusCode.OK);
              }
        }