static string Message(APIException ex) { switch (ex.HResult) //SpecificCode) { case (int)ErrorCodes.SPECIFIC_CODES.API_UNABLE_TO_CONNECT_TO_SERVER: return("Unable to connect to server"); case (int)ErrorCodes.SPECIFIC_CODES.API_AUTHENTICATION_INVALID_CRYPTOUSER_CREDENTIALS: return("Wrong User ID"); case (int)ErrorCodes.SPECIFIC_CODES.INPUT_VALIDATION_USER_PIN_LENGTH_TOO_SHORT: case (int)ErrorCodes.SPECIFIC_CODES.INPUT_VALIDATION_NO_COMPLEXITY_NO_SPECIAL_CHAR: case (int)ErrorCodes.SPECIFIC_CODES.USER_AUTHENTICATION_WRONG_PIN: return("Wrong Password"); case (int)ErrorCodes.SPECIFIC_CODES.GENERAL_ERROR: //if (ex.ErrorExtendedInformation != "") // return ex.ErrorExtendedInformation; //else return("General Error"); default: return(ex.ToString()); } }
//private static string Substitute(string pathTemplate, params object[] substitutions) //{ // //StringBuilder sb = new StringBuilder(); // //int nextSubst = 0; // //var chars = pathTemplate; // //for (int i = 0; i < chars.Length; i++) // //{ // // char c = chars[i]; // // if (c == '{') // // { // // i = pathTemplate.IndexOf('}', i); // // sb.Append(substitutions[nextSubst++]); // // continue; // // } // // sb.Append(c); // //} // return string.Format(pathTemplate, substitutions); //} public static T Deserialize(ClientResponse response) { var responseBody = response.BodyAsString; if (response.StatusCode == HttpStatusCode.ServiceUnavailable) { throw new ServiceNotAvailableException(responseBody); } if (((int)response.StatusCode) / 100 != 2) { try { var error = JsonConvert.DeserializeObject <Error>(responseBody); if (error == null) { throw new APIException(response.StatusCode); } throw APIException.Map(response.StatusCode, error); } catch (JsonSerializationException) { throw new APIException(response.StatusCode, responseBody); } } return(JsonConvert.DeserializeObject <T>(responseBody)); }
} // End of GetNoticeBLL /// <summary> /// Business logic for processing Notice record addition /// </summary> /// <param name="notice"></param> /// <returns></returns> internal object AddNoticeBLL(NoticeDTO notice, ClaimsPrincipal userClaims) { // Get the StaffID of the currently logged in Staff member int loggedInStaffID = _context.Users.Where(x => x.Email == userClaims.FindFirst("Email").Value).Include(user => user.StaffData).Select(x => x.StaffData.StaffID).FirstOrDefault(); // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); Dictionary <string, bool> exceptionTests = new Dictionary <string, bool>() { { "cohortID must be valid", notice.CohortID != 0 && !_context.Cohorts.Any(x => x.CohortID == notice.CohortID) }, { "staffID must be valid", notice.StaffID != 0 && !_context.Staff.Any(x => x.StaffID == notice.StaffID) }, { "Notice text should not be null or empty", string.IsNullOrEmpty(notice.HTML.Trim()) || string.IsNullOrEmpty(notice.Markdown.Trim()) } }; foreach (KeyValuePair <string, bool> kvp in exceptionTests) { if (kvp.Value) { exceptionList.AddExMessage(kvp.Key); } } if (!exceptionList.HasExceptions) { notice.StaffID = loggedInStaffID; return(notice); } else { return(exceptionList); } } // End of AddNoticeBLL
public dynamic Set(NancyContext nancyContext, Negotiator negotiate, Exception exception) { APIException apiException; if (exception is BadRequestError) { apiException = (BadRequestError)exception; } else if (exception is GlobalError) { apiException = (GlobalError)exception; } else { apiException = new APIException(); apiException.ExceptionMapping = new ExceptionMapping(); apiException.ExceptionMapping.ErrorCode = System.Net.HttpStatusCode.BadRequest; apiException.ExceptionMapping.Error.ErrorName = "Unexpected Error"; apiException.ExceptionMapping.Error.ErrorMessage = "Sorry, something went wrong!<br>Our technical team will resolve the issue as soon as possible. Please try again later."; } return(negotiate.WithModel( new ExceptionMapping() { ErrorCode = apiException.ExceptionMapping.ErrorCode, Error = { ErrorName = apiException.ExceptionMapping.Error.ErrorName, ErrorMessage = apiException.ExceptionMapping.Error.ErrorMessage } } ).WithStatusCode((HttpStatusCode)apiException.ExceptionMapping.ErrorCode)); }
public void OnHouseholdDeviceDeleteComplete(bool success, Exception error) { if (error != null) { if (error is APIException) { APIException exception = error as APIException; if (exception.Code != APIException.DeviceNotInDomain) { Console.WriteLine("Failed to delete household device: " + error.Message); code = -1; openTasks = 0; return; } } else { Console.WriteLine("Failed to delete household device: " + error.Message); code = -1; openTasks = 0; return; } } HouseholdDevice newDevice = new HouseholdDevice(); newDevice.Name = MASTER_DEVICE; newDevice.Udid = MASTER_DEVICE; newDevice.BrandId = MASTER_DEVICE_BRAND; HouseholdDeviceService.Add(newDevice) .SetCompletion(new OnCompletedHandler <HouseholdDevice>(OnHouseholdDeviceAddComplete)) .Execute(client); }
} // End of AddTaskTypeBLL /// <summary> /// Business logic for processing TaskType description change. /// </summary> /// <param name="taskType"></param> /// <returns></returns> internal object ModifyTaskTypeBLL(TaskTypeDTO taskType) { // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); // Due to the number of checks, this approach is more appropriate Dictionary <string, bool> exceptionTests = new Dictionary <string, bool>() { { "Specified TypeID does not exist", !_context.TaskTypes.Any(x => x.TypeID == taskType.TypeID) }, { "description parameter cannot be empty", taskType.Description == null || taskType.Description.Trim() == string.Empty }, { "description must be unique", !string.IsNullOrEmpty(taskType.Description) && _context.TaskTypes.Any(x => x.Description.ToLower() == taskType.Description.Trim().ToLower() && x.TypeID != taskType.TypeID) } }; foreach (KeyValuePair <string, bool> kvp in exceptionTests) { if (kvp.Value) { exceptionList.AddExMessage(kvp.Key); } } if (!exceptionList.HasExceptions) { // Capitalise the first letter of the first word of the description string dbDescription = $"{taskType.Description.Trim().Substring(0, 1).ToUpper()}{taskType.Description.Trim().Substring(1)?.ToLower()}"; taskType.Description = dbDescription; return(taskType); } else { return(exceptionList); } } // End of ModifyTaskTypeBLL
public static async Task <T> ContentAsync <T>(this HttpResponseMessage responseMessage) { var responseString = await responseMessage.Content.ReadAsStringAsync(); if (responseMessage.StatusCode != HttpStatusCode.OK) { var exception = new APIException() { StatusCode = responseMessage.StatusCode, Url = responseMessage.RequestMessage.RequestUri.AbsoluteUri.ToString(), Content = responseString }; throw exception; } try { return(JsonConvert.DeserializeObject <T>(responseString)); } catch (Exception) { var exception = new APIException() { StatusCode = responseMessage.StatusCode, Url = responseMessage.RequestMessage.RequestUri.AbsoluteUri.ToString(), Content = responseString }; throw exception; } }
} // End of AddStaffBLL /// <summary> /// Business logic for modifying Staff records /// </summary> /// <param name="staff"></param> /// <returns></returns> internal object ModifyUserBLL(StaffDTO staff) { APIException exceptionList = new APIException(); Dictionary <string, bool> exceptionTests = new Dictionary <string, bool>() { { "Specified UserID does not exist", !_context.Users.Any(x => x.UserID == staff.UserID) }, { "Specified StaffID does not exist", !_context.Staff.Any(x => x.StaffID == staff.StaffID) } }; foreach (KeyValuePair <string, bool> kvp in exceptionTests) { if (kvp.Value) { exceptionList.AddExMessage(kvp.Key); } } if (!exceptionList.HasExceptions) { return(staff); } else { return(exceptionList); } } // End of ModifyStaff
/// <summary> /// Business logic for creating staff records in database /// </summary> /// <param name="userID"></param> /// <param name="superUser"</param> /// <returns>BLL result object</returns> internal object AddStaffBLL(int userID, bool superUser) { // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); Dictionary <string, bool> exceptionTests = new Dictionary <string, bool>() { { "Specified userID does not exist", !_context.Users.Any(x => x.UserID == userID) } }; foreach (KeyValuePair <string, bool> kvp in exceptionTests) { if (kvp.Value) { exceptionList.AddExMessage(kvp.Key); } } if (!exceptionList.HasExceptions) { StaffDTO newStaff = new StaffDTO { UserID = userID, SuperUser = superUser }; return(newStaff); } else { return(exceptionList); } } // End of AddStaffBLL
/// <summary> /// Business logic for processing TaskType record addition /// </summary> /// <param name="description"></param> /// <returns></returns> internal object AddTaskTypeBLL(string description) { // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); Dictionary <string, bool> exceptionTests = new Dictionary <string, bool>() { { "description parameter cannot be empty", description == null || description.Trim() == string.Empty }, { "description must be unique", !string.IsNullOrEmpty(description) && _context.TaskTypes.Any(x => x.Description.ToLower() == description.Trim().ToLower()) } }; foreach (KeyValuePair <string, bool> kvp in exceptionTests) { if (kvp.Value) { exceptionList.AddExMessage(kvp.Key); } } if (!exceptionList.HasExceptions) { // Capitalise the first letter of the first word of the description string dbDescription = $"{description.Trim().Substring(0, 1).ToUpper()}{description.Trim().Substring(1)?.ToLower()}"; TaskTypeDTO newDbObject = new TaskTypeDTO { Description = dbDescription }; return(newDbObject); } else { return(exceptionList); } } // End of AddTaskTypeBLL
} // End of AddAttendanceBLL /// <summary> /// Business Logic for modifying Attendances table records /// </summary> /// <param name="attendance">AttendanceModDTO object with properties to modify</param> /// <param name="userClaims">ClaimsPrincipal object containing User Identity</param> /// <returns>object Exception or AttendanceModDTO</returns> internal object ModifyAttendanceBLL(AttendanceModDTO attendance, ClaimsPrincipal userClaims) { // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); // Due to the number of checks, this approach is more appropriate Dictionary<string, bool> exceptionTests = new Dictionary<string, bool>() { { "Specified RecordID does not exist", !_context.AttendanceRecords.Any(x => x.RecordID == attendance.RecordID) }, { "Specified AttendanceStateID does not exist", !_context.AttendanceStates.Any(x => x.StateID == attendance.AttendanceStateID) } }; foreach (KeyValuePair<string, bool> kvp in exceptionTests) { if (kvp.Value) exceptionList.AddExMessage(kvp.Key); } if (!exceptionList.HasExceptions) { return attendance; } else { return exceptionList; } } // End of ModifyAttendanceBLL
/// <summary> /// Business logic for detailed Student records /// </summary> /// <param name="cohortID"></param> /// <returns></returns> internal object StudentDetailBLL(int cohortID) { // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); Dictionary <string, bool> exceptionTests = new Dictionary <string, bool>() { { "Specified CohortID does not exist", !(_context.Cohorts.Any(x => x.CohortID == cohortID) || cohortID == 0) }, { "Specified cohort is inactive.", cohortID != 0 && !_context.Cohorts.Any(x => x.CohortID == cohortID && DateTime.Now >= x.StartDate && DateTime.Now <= x.EndDate) } }; foreach (KeyValuePair <string, bool> kvp in exceptionTests) { if (kvp.Value) { exceptionList.AddExMessage(kvp.Key); } } if (!exceptionList.HasExceptions) { return(cohortID); } else { return(exceptionList); } } // End of StudentDetailBLL
public void OnHouseholdDeviceDeleteComplete(bool success, Exception error) { if (error != null) { if (error is APIException) { APIException exception = error as APIException; if (exception.Code != APIException.DeviceNotInDomain) { Console.WriteLine("Failed to delete household device: " + error.Message); code = -1; openTasks = 0; return; } } else { Console.WriteLine("Failed to delete household device: " + error.Message); code = -1; openTasks = 0; return; } } openTasks--; }
} // End of AddTaskBLL /// <summary> /// Business logic for processing modifications to the Task record /// </summary> /// <param name="task"></param> /// <returns></returns> internal object ModifyTaskBLL(TaskDTO task) { // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); Dictionary <string, bool> exceptionTests = new Dictionary <string, bool>() { { "title cannot be empty.", task.Title == null || task.Title.Trim() == string.Empty }, { "Specified UnitID does not exist", !_context.Units.Any(x => x.UnitID == task.UnitID) }, { "Specified CohortID does not exist", !_context.Cohorts.Any(x => x.CohortID == task.CohortID) }, { "Specified TypeID does not exist", !_context.TaskTypes.Any(x => x.TypeID == task.TypeID) }, { "Document URL must start with http:// or https://", !string.IsNullOrEmpty(task.DocURL) && !(task.DocURL.ToLower().StartsWith("http://") | task.DocURL.ToLower().StartsWith("https://")) }, { "Document URL must be valid", !string.IsNullOrEmpty(task.DocURL) && !Uri.IsWellFormedUriString(task.DocURL, UriKind.Absolute) }, { "Specified cohort is inactive.", !_context.Cohorts.Any(x => x.CohortID == task.CohortID && DateTime.Now >= x.StartDate && DateTime.Now <= x.EndDate) } }; foreach (KeyValuePair <string, bool> kvp in exceptionTests) { if (kvp.Value) { exceptionList.AddExMessage(kvp.Key); } } if (!exceptionList.HasExceptions) { return(task); } else { return(exceptionList); } } // End of ModifyTaskBLL
} // End of ModifyTimesheetRecordBLL /// <summary> /// Business Logic for deleting an existing record /// </summary> /// <param name="recordID"></param> /// <param name="userClaims"></param> /// <returns></returns> internal object DeleteTimesheetRecordBLL(int recordID, ClaimsPrincipal userClaims) { // Check if the current user is a staff member (or Super Admin) bool isUserStaff = userClaims.IsInRole("Staff") || userClaims.IsInRole("SuperAdmin"); // Get the StudentID of the currrent user (or 0) int currentStudentID = isUserStaff ? 0 : _context.Users.Where(x => x.Email == userClaims.FindFirstValue("email")).Include(users => users.StudentData).FirstOrDefault()?.StudentData.StudentID ?? 0; // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); Dictionary <string, bool> exceptionTests = new Dictionary <string, bool>() { { "StudentID in the record cannot differ from the StudentID of the authenticated user", !(_context.Timesheets.Where(x => x.RecordID == recordID).First().StudentID == currentStudentID) || isUserStaff } }; foreach (KeyValuePair <string, bool> kvp in exceptionTests) { if (kvp.Value) { exceptionList.AddExMessage(kvp.Key); } } if (!exceptionList.HasExceptions) { return(recordID); } else { return(exceptionList); } } // End of TimesheetDeleteBLL
private static APIException ThrowWebException(WebException ex) { using (var stream = ex.Response.GetResponseStream()) using (var reader = new StreamReader(stream)) { String error = reader.ReadToEnd(); APIException ex_new = new APIException(error, ex); return(ex_new); } }
} // End of AddCohort /// <summary> /// Business logic for modifying Cohort records /// </summary> /// <param name="cohort"></param> /// <returns></returns> internal object ModifyCohortBLL(CohortDTO cohort) { // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); // Check if the id matches a CohortID already in the database. if (!CohortExists(cohort.CohortID)) { exceptionList.AddExMessage($"Cohort does not exist with the ID {cohort.CohortID}"); } else { // Check if the supplied changes meet requirements as for addition if (cohort.Name == null || cohort.Name.Trim() == string.Empty) { exceptionList.AddExMessage("Name parameter cannot be empty."); } else { // Check if a cohort with the same name exists in the database (trim + case insensitive) // If it does, it has to have a different CohortID from the one supplied (i.e. ignore if they have the same ID) bool dbContainsName = _context.Cohorts.Any(x => (x.Name.ToLower() == cohort.Name.Trim().ToLower()) && (x.CohortID != cohort.CohortID)); if (dbContainsName) { exceptionList.AddExMessage("A cohort with the same name already exists in the database."); } // Check that the startDate is less than endDate bool datesConsistent = cohort.StartDate < cohort.EndDate; if (!datesConsistent) { exceptionList.AddExMessage("Start date must be before the end date, check for consistency."); } } } if (!exceptionList.HasExceptions) { // New database name will be trimmed and in Proper Case. string dbName = String.Join(" ", cohort.Name.Trim().Split(" ").Select(x => $"{x.Substring(0, 1).ToUpper()}{x.Substring(1)?.ToLower()}").ToArray()); // Create a new Cohort object Cohort newDbObject = new Cohort { CohortID = cohort.CohortID, Name = dbName, StartDate = cohort.StartDate, EndDate = cohort.EndDate }; // Return the Cohort object (conversion from CohortDTO for internal ops) return(newDbObject); } else { return(exceptionList); } } // End of ModifyCohort
} // End of StudentDetailBLL /// <summary> /// Business logic for adding Student records /// </summary> /// <param name="firstname"></param> /// <param name="lastname"></param> /// <param name="email"></param> /// <param name="active"></param> /// <param name="cohortID"></param> /// <param name="bearTracksID"></param> /// <param name="userIsSuperAdmin"></param> /// <returns></returns> internal object AddStudentBLL(string firstname, string lastname, string email, bool active, int cohortID, string bearTracksID, bool userIsSuperAdmin) { // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); // Email check regex in Dictionary below // Ref: https://stackoverflow.com/a/45177249/12802214 // Due to the number of checks, this approach is more appropriate Dictionary <string, bool> exceptionTests = new Dictionary <string, bool>() { { "firstname parameter cannot be empty.", firstname == null || firstname.Trim() == string.Empty }, { "lastname parameter cannot be empty", lastname == null || lastname.Trim() == string.Empty }, { "Email needs to be a valid email address", email == null || !Regex.IsMatch(email, @"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$") }, { "Email address needs to be unique in the database (student record already exists)", email != null && _context.Users.Any(x => x.Email == email) && _context.Students.Any(x => x.UserID == _context.Users.Where(y => y.Email == email).First().UserID) }, { "Email address domain not found in the list of valid domains", email != null && !APIConfig.Configuration.GetSection("ValidEmailDomains").GetChildren().ToArray().Select(x => x.Value).ToArray().Contains(email.Split("@")?[1] ?? "") }, { "Specified CohortID does not exist", !_context.Cohorts.Any(x => x.CohortID == cohortID) }, { "Specified cohort is inactive.", !(_context.Cohorts.Any(x => x.CohortID == cohortID && DateTime.Now >= x.StartDate && DateTime.Now <= x.EndDate) || userIsSuperAdmin) } }; foreach (KeyValuePair <string, bool> kvp in exceptionTests) { if (kvp.Value) { exceptionList.AddExMessage(kvp.Key); } } if (!exceptionList.HasExceptions) { // New database names will be trimmed and in Proper Case. string dbFirstname = String.Join(" ", firstname.Trim().Split(" ").Select(x => $"{x.Substring(0, 1).ToUpper()}{x.Substring(1)?.ToLower()}").ToArray()); string dbLastname = String.Join(" ", lastname.Trim().Split(" ").Select(x => $"{x.Substring(0, 1).ToUpper()}{x.Substring(1)?.ToLower()}").ToArray()); // Create a dictionary containing all data needed to create the user and pass back to API Target Dictionary <string, object> newDbObject = new Dictionary <string, object>() { { "Firstname", dbFirstname }, { "Lastname", dbLastname }, { "Email", email }, { "Active", active }, { "CohortID", cohortID }, { "BearTracksID", bearTracksID }, { "UserAlreadyInUsersTable", _context.Users.Any(x => x.Email == email) } }; return(newDbObject); } else { return(exceptionList); } } // End of AddStudent
/// <summary> /// Helper Method to Print Exception /// </summary> /// <param name="forMethod">Method the Exception was raised</param> /// <param name="exception"></param> private static void printException(string forMethod, APIException exception) { if (exception.HttpContext.Response.RawBody is MemoryStream memoryStream) { var body = Encoding.UTF8.GetString(memoryStream.ToArray()); Console.WriteLine($"{forMethod} - {body}"); } else { Console.WriteLine(exception); } }
private static Task HandleExceptionAsync(HttpContext context, APIException exception) { context.Response.ContentType = "application/json"; context.Response.StatusCode = (int)exception.StatusCode; var json = new { StatusCode = context.Response.StatusCode, Message = exception.Message }; return(context.Response.WriteAsync(JsonConvert.SerializeObject(json))); }
} // End of GetTimesheetRecordBLL /// <summary> /// Business logic for processing Timesheet record addition /// </summary> /// <param name="timesheetRecord"></param> /// <param name="userClaims"></param> /// <returns></returns> internal object AddTimesheetRecordBLL(TimesheetDTO timesheetRecord, ClaimsPrincipal userClaims) { // Check if the current user is a staff member (or Super Admin) bool isUserStaff = userClaims.IsInRole("Staff") || userClaims.IsInRole("SuperAdmin"); // Get the StudentID of the currrent user (or 0) int currentStudentID = isUserStaff ? 0 : _context.Users.Where(x => x.Email == userClaims.FindFirstValue("email")).Include(users => users.StudentData).FirstOrDefault()?.StudentData.StudentID ?? 0; if (timesheetRecord.StudentID == 0 && !isUserStaff) { timesheetRecord.StudentID = currentStudentID; } // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); Dictionary <string, bool> exceptionTests = new Dictionary <string, bool>() { { "Specified StudentID does not exist", !_context.Students.Any(x => x.StudentID == timesheetRecord.StudentID) }, { "StudentID cannot differ from the authenticated user", !(timesheetRecord.StudentID == currentStudentID || isUserStaff) }, { "Student account matching the StudentID must be active", !(_context.Students.Where(x => x.StudentID == timesheetRecord.StudentID).Include(student => student.UserData).FirstOrDefault().UserData.Active || isUserStaff) }, { "Specified AssignmentID does not exist", !_context.Tasks.Any(x => x.TaskID == timesheetRecord.AssignmentID) }, { "Specified date is older than 7 days", ((DateTime.Today - timesheetRecord.Date).Days > 7) && !isUserStaff }, { "Specified date cannot be in the future", !(timesheetRecord.Date <= DateTime.Today) }, { "TimeAllocation has to be a positive number, or zero", !(timesheetRecord.TimeAllocation >= 0) }, { "TimeAllocation has to be less than or equal to 18h", !(timesheetRecord.TimeAllocation <= 18) } // { "Only one record per AssignmentID per date is allowed", _context.Timesheets.Any(x => x.Date == timesheetRecord.Date && x.AssignmentID == timesheetRecord.AssignmentID && x.StudentID == timesheetRecord.StudentID) } }; foreach (KeyValuePair <string, bool> kvp in exceptionTests) { if (kvp.Value) { exceptionList.AddExMessage(kvp.Key); } } if (!exceptionList.HasExceptions) { // Round the TimeAlllocation to 15 min (0.25h) // Ref: https://stackoverflow.com/a/2826278/12802214 timesheetRecord.TimeAllocation = Math.Round(timesheetRecord.TimeAllocation * 4, MidpointRounding.AwayFromZero) / 4; return(timesheetRecord); } else { return(exceptionList); } } // End of AddTimesheetRecordBLL
}//end method /// <summary> /// 运行响应任务。 /// </summary> /// <param name="ar">异步结果对象。</param> protected internal void RunResponseTask(IAsyncResult ar) { try { //获取HTTP异步响应对象 this.HttpResponse = (HttpWebResponse)this.HttpRequest.EndGetResponse(ar); this.Result.StatusCode = this.HttpResponse.StatusCode; //接收json字符串 var json = this.ClientRequest.HttpUtility.GetResponseString(this.HttpResponse); //判断返回的是否是一个异常数据包 //如果是的,反序列化之,并引发一个异常 //反之正常反序列化 if (APIException.CheckStringIsAPIException(json)) { this.Result.APIError = JsonConvert.DeserializeObject <APIException>(APIException.CutJSONHeader(json)); throw this.Result.APIError.ToException(); }//end if if (typeof(T).Equals(typeof(string))) { this.Result.Body = (T)(object)json; } else { this.Result.Body = JsonConvert.DeserializeObject <T>(json); } }//end try catch (Exception ex) { this.Result.Error = ex; } if (this.Result.Error != null) { if (this.FailCallBack != null) { this.FailCallBack(this.Result); } } else { if (this.SuccessCallBack != null) { this.SuccessCallBack(this.Result); } } }//end method
} // End of ModifyAttendanceBLL /// <summary> /// Business Logic for processing Get requests for records in the attendance table /// </summary> /// <param name="studentID"></param> /// <param name="attendanceStateID"></param> /// <param name="startDate"></param> /// <param name="endDate"></param> /// <param name="userClaims"></param> /// <returns></returns> internal object GetAttendanceBLL(int studentID, int attendanceStateID, DateTime startDate, DateTime endDate, ClaimsPrincipal userClaims) { // Check if the current user is a staff member (or Super Admin) bool isUserStaff = userClaims.IsInRole("Staff") || userClaims.IsInRole("SuperAdmin"); // Get the StudentID of the currrent user (or null) int currentStudentID = isUserStaff? 0 : _context.Users.Where(x => x.Email == userClaims.FindFirstValue("email")).Include(users => users.StudentData).FirstOrDefault()?.StudentData.StudentID ?? 0; // Apply defaults if (startDate == DateTime.MinValue) startDate = DateTime.Today.AddDays(-7); if (endDate == DateTime.MinValue) endDate = DateTime.Today; if (studentID == 0) studentID = currentStudentID; // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); // Due to the number of checks, this approach is more appropriate Dictionary<string, bool> exceptionTests = new Dictionary<string, bool>() { { "StudentID has to match the current user StudentID", !(studentID == currentStudentID || isUserStaff) }, { "Start date cannot be after the end date", !(startDate <= endDate) }, { "Invalid attendanceStateID specified", !(_context.AttendanceStates.Any(x => x.StateID == attendanceStateID) || attendanceStateID == 0) } }; foreach (KeyValuePair<string, bool> kvp in exceptionTests) { if (kvp.Value) exceptionList.AddExMessage(kvp.Key); } if (!exceptionList.HasExceptions) { // Create a dictionary containing all data needed to create the user and pass back to API Target Dictionary<string, object> getParams = new Dictionary<string, object>() { { "StudentID", studentID }, { "AttendanceStateID", attendanceStateID}, { "StartDate", startDate}, { "EndDate", endDate} }; return getParams; } else { return exceptionList; } }// End of GetAttendanceBLL
public async Task ComputerSessionProcessor_ReadUserSessionsPrivileged_ComputerAccessDenied_ExceptionCaught() { var mockNativeMethods = new Mock <NativeMethods>(); //mockNativeMethods.Setup(x => x.CallSamConnect(ref It.Ref<NativeMethods.UNICODE_STRING>.IsAny, out It.Ref<IntPtr>.IsAny, It.IsAny<NativeMethods.SamAccessMasks>(), ref It.Ref<NativeMethods.OBJECT_ATTRIBUTES>.IsAny)).Returns(NativeMethods.NtStatus.StatusAccessDenied); var ex = new APIException { Status = NativeMethods.NERR.ERROR_ACCESS_DENIED.ToString() }; mockNativeMethods.Setup(x => x.CallNetWkstaUserEnum(It.IsAny <string>())).Throws(ex); var processor = new ComputerSessionProcessor(new MockLDAPUtils(), "dfm", mockNativeMethods.Object); var test = processor.ReadUserSessionsPrivileged("test", "test", "test"); Assert.False(test.Collected); Assert.Equal(NativeMethods.NERR.ERROR_ACCESS_DENIED.ToString(), test.FailureReason); }
/// <summary> /// Business logic for creating users in database /// </summary> /// <param name="firstname"></param> /// <param name="lastname"></param> /// <param name="email"></param> /// <param name="active"></param> /// <returns></returns> internal object AddUserBLL(string firstname, string lastname, string email, bool active) { // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); // Email check regex in Dictionary below // Ref: https://stackoverflow.com/a/45177249/12802214 Dictionary <string, bool> exceptionTests = new Dictionary <string, bool>() { { "firstname parameter cannot be empty.", firstname == null || firstname.Trim() == string.Empty }, { "lastname parameter cannot be empty", lastname == null || lastname.Trim() == string.Empty }, { "Email needs to be a valid email address", email == null || !Regex.IsMatch(email, @"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$") }, { "Email address needs to be unique in the database (user record already exists)", email != null && _context.Users.Any(x => x.Email == email) && _context.Students.Any(x => x.UserID == _context.Users.Where(y => y.Email == email).First().UserID) }, { "Email address domain not found in the list of valid domains", email != null && !APIConfig.Configuration.GetSection("ValidEmailDomains").GetChildren().ToArray().Select(x => x.Value).ToArray().Contains(email.Split("@")?[1] ?? "") } }; foreach (KeyValuePair <string, bool> kvp in exceptionTests) { if (kvp.Value) { exceptionList.AddExMessage(kvp.Key); } } if (!exceptionList.HasExceptions) { // New database names will be trimmed and in Proper Case. string dbFirstname = String.Join(" ", firstname.Trim().Split(" ").Select(x => $"{x.Substring(0, 1).ToUpper()}{x.Substring(1)?.ToLower()}").ToArray()); string dbLastname = String.Join(" ", lastname.Trim().Split(" ").Select(x => $"{x.Substring(0, 1).ToUpper()}{x.Substring(1)?.ToLower()}").ToArray()); UserDTO newUser = new UserDTO { Firstname = dbFirstname, Lastname = dbLastname, Email = email, Active = active }; return(newUser); } else { return(exceptionList); } } // End of AddUserBLL
/* * Wrapper for Spotify set volume */ public bool SetVolume(int volumeRequest) { int i = 0; do { try { var task = spotify.Player.SetVolume(new PlayerVolumeRequest(volumeRequest)); task.Wait(); return(task.Result); } catch (AggregateException ex) { if (ex.InnerException.GetType() == typeof(APIUnauthorizedException)) { GuaranteeLogin(); } else if (ex.InnerException.GetType() == typeof(APITooManyRequestsException)) { Logger.Log("Volume change failed: Too many requests. " + ex.InnerException.Message); i = -1; } else if (ex.InnerException.GetType() == typeof(APIException)) { APIException e = (APIException)ex.InnerException; if (e.Response.StatusCode == System.Net.HttpStatusCode.NotFound) { throw new NoActiveDeviceException("No Active Spotify Device Found."); } else { Logger.Log("Volume change failed: " + e.Response?.StatusCode + e.Message); i = -1; } } else { Logger.Log("Volume change failed: " + ex.InnerException.Message); i = -1; } } } while (i == 0); return(false); }
/// <summary> /// Business logic for retrieving Notice records /// </summary> /// <param name="noticeID"></param> /// <param name="cohortID"></param> /// <param name="staffID"></param> /// <param name="validFrom"></param> /// <param name="isUserStaff"></param> /// <returns></returns> internal object GetNoticeBLL(int noticeID, int cohortID, int staffID, DateTime validFrom, bool isUserStaff) { // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); Dictionary <string, bool> exceptionTests = new Dictionary <string, bool>() { { "noticeID must be valid", noticeID != 0 && !_context.Notices.Any(x => x.NoticeID == noticeID) }, { "cohortID must be valid", cohortID != 0 && !_context.Cohorts.Any(x => x.CohortID == cohortID) }, { "staffID must be valid", staffID != 0 && !_context.Staff.Any(x => x.StaffID == staffID) }, { "validFrom date cannot be in the future", !(validFrom <= DateTime.Today) && !isUserStaff } }; foreach (KeyValuePair <string, bool> kvp in exceptionTests) { if (kvp.Value) { exceptionList.AddExMessage(kvp.Key); } } if (!exceptionList.HasExceptions) { // Apply defaults if (validFrom == DateTime.MinValue) { validFrom = _context.Cohorts.Where(x => x.CohortID == cohortID).First().StartDate; } NoticeDTO getParams = new NoticeDTO { NoticeID = noticeID, CohortID = cohortID, StaffID = staffID, ValidFrom = validFrom }; return(getParams); } else { return(exceptionList); } } // End of GetNoticeBLL
} // End of AddStudent /// <summary> /// Business logic for modifying Student records /// </summary> /// <param name="student"></param> /// <param name="userIsSuperAdmin"></param> /// <returns></returns> internal object ModifyStudentBLL(StudentModDTO student, bool userIsSuperAdmin) { // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); // Email check regex in Dictionary below // Ref: https://stackoverflow.com/a/45177249/12802214 // Check is virtually identical to that of the AddStudent method, except for the e-mail address unique check Dictionary <string, bool> exceptionTests = new Dictionary <string, bool>() { { "firstname parameter cannot be empty.", student.Firstname == null || student.Firstname.Trim() == string.Empty }, { "lastname parameter cannot be empty", student.Lastname == null || student.Lastname.Trim() == string.Empty }, { "Email needs to be a valid email address", student.Email == null || !Regex.IsMatch(student.Email, @"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$") }, { "Email address needs to be unique in the database (student record with that email already exists)", student.Email != null && _context.Users.Where(x => x.Email == student.Email).Include(student => student.StudentData).Any(x => x.StudentData.StudentID != student.StudentID) }, { "Email address domain not found in the list of valid domains", student.Email != null && !APIConfig.Configuration.GetSection("ValidEmailDomains").GetChildren().ToArray().Select(x => x.Value).ToArray().Contains(student.Email.Split("@")?[1] ?? "") }, { "Specified CohortID does not exist", !_context.Cohorts.Any(x => x.CohortID == student.CohortID) }, { "Specified cohort is inactive.", !(_context.Cohorts.Any(x => x.CohortID == student.CohortID && DateTime.Now >= x.StartDate && DateTime.Now <= x.EndDate) || userIsSuperAdmin) } }; foreach (KeyValuePair <string, bool> kvp in exceptionTests) { if (kvp.Value) { exceptionList.AddExMessage(kvp.Key); } } if (!exceptionList.HasExceptions) { // New database names will be trimmed and in Proper Case. string dbFirstname = String.Join(" ", student.Firstname.Trim().Split(" ").Select(x => $"{x.Substring(0, 1).ToUpper()}{x.Substring(1)?.ToLower()}").ToArray()); string dbLastname = String.Join(" ", student.Lastname.Trim().Split(" ").Select(x => $"{x.Substring(0, 1).ToUpper()}{x.Substring(1)?.ToLower()}").ToArray()); // Create a dictionary containing all data needed to create the user and pass back to API Target. StudentModDTO modifiedDbObject = new StudentModDTO { StudentID = student.StudentID, Firstname = dbFirstname, Lastname = dbLastname, Email = student.Email, Active = student.Active, CohortID = student.CohortID, BearTracksID = student.BearTracksID }; return(modifiedDbObject); } else { return(exceptionList); } } // End of ModifyStudent
/// <summary> /// Business logic for adding Cohort records /// </summary> /// <param name="name"></param> /// <param name="startDate"></param> /// <param name="endDate"></param> /// <returns></returns> internal object AddCohortBLL(string name, DateTime startDate, DateTime endDate) { // Create a new APIException object to store possible exceptions as checks are performed. APIException exceptionList = new APIException(); // Check if the name has been supplied or if it's empty after trimming if (name == null || name.Trim() == string.Empty) { exceptionList.AddExMessage("Name parameter cannot be empty."); } else { // Check if a cohort with the same name exists in the database (trim + case insensitive) bool dbContainsName = _context.Cohorts.Where(x => x.Name.ToLower() == name.Trim().ToLower()).Count() > 0; if (dbContainsName) { exceptionList.AddExMessage("A cohort with the same name already exists in the database."); } // Check that the startDate is less than endDate bool datesConsistent = startDate < endDate; if (!datesConsistent) { exceptionList.AddExMessage("Start date must be before the end date, check for consistency."); } } if (!exceptionList.HasExceptions) { // New database name will be trimmed and in Proper Case. string dbName = String.Join(" ", name.Trim().Split(" ").Select(x => $"{x.Substring(0, 1).ToUpper()}{x.Substring(1)?.ToLower()}").ToArray()); Cohort newDbObject = new Cohort { Name = dbName, StartDate = startDate, EndDate = endDate }; return(newDbObject); } else { return(exceptionList); } } // End of AddCohort
public static async Task <string> ContentStringAsync(this HttpResponseMessage responseMessage) { var responseString = await responseMessage.Content.ReadAsStringAsync(); if (responseMessage.StatusCode == HttpStatusCode.OK) { return(responseString); } var exception = new APIException() { StatusCode = responseMessage.StatusCode, Url = responseMessage.RequestMessage.RequestUri.AbsoluteUri.ToString(), Content = responseString }; throw exception; }