diff --git a/api/admin/update_course.go b/api/admin/update_course.go index 358f78f2..5563d22d 100644 --- a/api/admin/update_course.go +++ b/api/admin/update_course.go @@ -23,7 +23,7 @@ func HandleUpdateCourse(request *UpdateCourseRequest) (*UpdateCourseResponse, *c if (request.Clear) { err := db.ClearCourse(request.Course); if (err != nil) { - return nil, core.NewInternalError("-701", &request.APIRequestCourseUserContext, + return nil, core.NewInternalError("-201", &request.APIRequestCourseUserContext, "Failed to clear course.").Err(err); } } @@ -31,7 +31,7 @@ func HandleUpdateCourse(request *UpdateCourseRequest) (*UpdateCourseResponse, *c if (request.Source != "") { spec, err := common.ParseFileSpec(request.Source); if (err != nil) { - return nil, core.NewBadCourseRequestError("-702", &request.APIRequestCourseUserContext, + return nil, core.NewBadCourseRequestError("-202", &request.APIRequestCourseUserContext, "Source FileSpec is not formatted properly.").Err(err); } @@ -39,14 +39,14 @@ func HandleUpdateCourse(request *UpdateCourseRequest) (*UpdateCourseResponse, *c err = db.SaveCourse(request.Course); if (err != nil) { - return nil, core.NewInternalError("-703", &request.APIRequestCourseUserContext, + return nil, core.NewInternalError("-203", &request.APIRequestCourseUserContext, "Failed to save course.").Err(err); } } updated, err := procedures.UpdateCourse(request.Course); if (err != nil) { - return nil, core.NewInternalError("-704", &request.APIRequestCourseUserContext, + return nil, core.NewInternalError("-204", &request.APIRequestCourseUserContext, "Failed to update course.").Err(err); } diff --git a/api/core/auth.go b/api/core/auth.go index 86d4b267..15a2762e 100644 --- a/api/core/auth.go +++ b/api/core/auth.go @@ -14,11 +14,11 @@ import ( func (this *APIRequestCourseUserContext) Auth() (*model.User, *APIError) { user, err := db.GetUser(this.Course, this.UserEmail); if (err != nil) { - return nil, NewAuthBadRequestError("-201", this, "Cannot Get User").Err(err); + return nil, NewAuthBadRequestError("-012", this, "Cannot Get User").Err(err); } if (user == nil) { - return nil, NewAuthBadRequestError("-202", this, "Unknown User"); + return nil, NewAuthBadRequestError("-013", this, "Unknown User"); } if (config.NO_AUTH.Get()) { @@ -27,7 +27,7 @@ func (this *APIRequestCourseUserContext) Auth() (*model.User, *APIError) { } if (!user.CheckPassword(this.UserPass)) { - return nil, NewAuthBadRequestError("-203", this, "Bad Password"); + return nil, NewAuthBadRequestError("-014", this, "Bad Password"); } return user, nil; diff --git a/api/core/auth_test.go b/api/core/auth_test.go index d8c517e5..9725ad7d 100644 --- a/api/core/auth_test.go +++ b/api/core/auth_test.go @@ -20,14 +20,14 @@ func TestAuth(test *testing.T) { {"student@test.com", "student", false, ""}, {"other@test.com", "other", false, ""}, - {"Z", "student", false, "-202"}, - {"Zstudent@test.com", "student", false, "-202"}, - {"student@test.comZ", "student", false, "-202"}, - {"student", "student", false, "-202"}, + {"Z", "student", false, "-013"}, + {"Zstudent@test.com", "student", false, "-013"}, + {"student@test.comZ", "student", false, "-013"}, + {"student", "student", false, "-013"}, - {"student@test.com", "", false, "-203"}, - {"student@test.com", "Zstudent", false, "-203"}, - {"student@test.com", "studentZ", false, "-203"}, + {"student@test.com", "", false, "-014"}, + {"student@test.com", "Zstudent", false, "-014"}, + {"student@test.com", "studentZ", false, "-014"}, {"owner@test.com", "owner", true, ""}, {"admin@test.com", "admin", true, ""}, @@ -35,10 +35,10 @@ func TestAuth(test *testing.T) { {"student@test.com", "student", true, ""}, {"other@test.com", "other", true, ""}, - {"Z", "student", true, "-202"}, - {"Zstudent@test.com", "student", true, "-202"}, - {"student@test.comZ", "student", true, "-202"}, - {"student", "student", true, "-202"}, + {"Z", "student", true, "-013"}, + {"Zstudent@test.com", "student", true, "-013"}, + {"student@test.comZ", "student", true, "-013"}, + {"student", "student", true, "-013"}, {"student@test.com", "", true, ""}, {"student@test.com", "Zstudent", true, ""}, diff --git a/api/core/request.go b/api/core/request.go index 6a0de2f1..dded6cc3 100644 --- a/api/core/request.go +++ b/api/core/request.go @@ -71,25 +71,25 @@ func (this *APIRequestCourseUserContext) Validate(request any, endpoint string) } if (this.CourseID == "") { - return NewBadRequestError("-301", &this.APIRequest, "No course ID specified."); + return NewBadRequestError("-015", &this.APIRequest, "No course ID specified."); } if (this.UserEmail == "") { - return NewBadRequestError("-302", &this.APIRequest, "No user email specified."); + return NewBadRequestError("-016", &this.APIRequest, "No user email specified."); } if (this.UserPass == "") { - return NewBadRequestError("-303", &this.APIRequest, "No user password specified."); + return NewBadRequestError("-017", &this.APIRequest, "No user password specified."); } var err error; this.Course, err = db.GetCourse(this.CourseID); if (err != nil) { - return NewInternalError("-318", this, "Unable to get course").Err(err); + return NewInternalError("-032", this, "Unable to get course").Err(err); } if (this.Course == nil) { - return NewBadRequestError("-304", &this.APIRequest, fmt.Sprintf("Could not find course: '%s'.", this.CourseID)). + return NewBadRequestError("-018", &this.APIRequest, fmt.Sprintf("Could not find course: '%s'.", this.CourseID)). Add("course-id", this.CourseID); } @@ -100,11 +100,11 @@ func (this *APIRequestCourseUserContext) Validate(request any, endpoint string) minRole, foundRole := getMaxRole(request); if (!foundRole) { - return NewInternalError("-305", this, "No role found for request. All request structs require a minimum role."); + return NewInternalError("-019", this, "No role found for request. All request structs require a minimum role."); } if (this.User.Role < minRole) { - return NewBadPermissionsError("-306", this, minRole, "Base API Request"); + return NewBadPermissionsError("-020", this, minRole, "Base API Request"); } return nil; @@ -118,12 +118,12 @@ func (this *APIRequestAssignmentContext) Validate(request any, endpoint string) } if (this.AssignmentID == "") { - return NewBadRequestError("-307", &this.APIRequest, "No assignment ID specified."); + return NewBadRequestError("-021", &this.APIRequest, "No assignment ID specified."); } this.Assignment = this.Course.GetAssignment(this.AssignmentID); if (this.Assignment == nil) { - return NewBadRequestError("-308", &this.APIRequest, fmt.Sprintf("Could not find assignment: '%s'.", this.AssignmentID)). + return NewBadRequestError("-022", &this.APIRequest, fmt.Sprintf("Could not find assignment: '%s'.", this.AssignmentID)). Add("course-id", this.CourseID).Add("assignment-id", this.AssignmentID); } @@ -135,7 +135,7 @@ func (this *APIRequestAssignmentContext) Validate(request any, endpoint string) func ValidateAPIRequest(request *http.Request, apiRequest any, endpoint string) *APIError { reflectPointer := reflect.ValueOf(apiRequest); if (reflectPointer.Kind() != reflect.Pointer) { - return NewBareInternalError("-309", endpoint, "ValidateAPIRequest() must be called with a pointer."). + return NewBareInternalError("-023", endpoint, "ValidateAPIRequest() must be called with a pointer."). Add("kind", reflectPointer.Kind().String()); } @@ -146,7 +146,7 @@ func ValidateAPIRequest(request *http.Request, apiRequest any, endpoint string) } if (!foundRequestStruct) { - return NewBareInternalError("-310", endpoint, "Request is not any kind of known API request."); + return NewBareInternalError("-024", endpoint, "Request is not any kind of known API request."); } // Check for any special field types that we know how to populate. @@ -185,7 +185,7 @@ func validateRequestStruct(request any, endpoint string) (bool, *APIError) { reflectValue := reflect.ValueOf(request).Elem(); if (reflectValue.Kind() != reflect.Struct) { - return false, NewBareInternalError("-317", endpoint, "Request's type must be a struct."). + return false, NewBareInternalError("-031", endpoint, "Request's type must be a struct."). Add("kind", reflectValue.Kind().String()); } diff --git a/api/core/request_fields.go b/api/core/request_fields.go index 704f220f..b6f2e6ab 100644 --- a/api/core/request_fields.go +++ b/api/core/request_fields.go @@ -131,7 +131,7 @@ func checkRequestTargetUser(endpoint string, apiRequest any, fieldIndex int) *AP jsonName := util.JSONFieldName(fieldType); if (field.Email == "") { - return NewBadRequestError("-320", &courseContext.APIRequest, + return NewBadRequestError("-034", &courseContext.APIRequest, fmt.Sprintf("Field '%s' requires a non-empty string, empty or null provided.", jsonName)). Add("struct-name", structName).Add("field-name", fieldType.Name).Add("json-name", jsonName); } @@ -173,7 +173,7 @@ func checkRequestTargetUserSelfOrRole(endpoint string, apiRequest any, fieldInde // Operations not on self require higher permissions. if ((field.Email != courseContext.User.Email) && (courseContext.User.Role < minRole)) { - return NewBadPermissionsError("-319", courseContext, minRole, "Non-Self Target User"); + return NewBadPermissionsError("-033", courseContext, minRole, "Non-Self Target User"); } user := users[field.Email]; @@ -198,19 +198,19 @@ func checkRequestPostFiles(request *http.Request, endpoint string, apiRequest an fieldType := reflectValue.Type().Field(fieldIndex); if (!fieldType.IsExported()) { - return NewBareInternalError("-314", endpoint, "A POSTFiles field must be exported."). + return NewBareInternalError("-028", endpoint, "A POSTFiles field must be exported."). Add("struct-name", structName).Add("field-name", fieldType.Name); } postFiles, err := storeRequestFiles(request); if (err != nil) { - return NewBareInternalError("-315", endpoint, "Failed to store files from POST.").Err(err). + return NewBareInternalError("-029", endpoint, "Failed to store files from POST.").Err(err). Add("struct-name", structName).Add("field-name", fieldType.Name); } if (postFiles == nil) { - return NewBareBadRequestError("-316", endpoint, "Endpoint requires files to be provided in POST body, no files found."). + return NewBareBadRequestError("-030", endpoint, "Endpoint requires files to be provided in POST body, no files found."). Add("struct-name", structName).Add("field-name", fieldType.Name); } @@ -230,7 +230,7 @@ func checkRequestNonEmptyString(endpoint string, apiRequest any, fieldIndex int) value := fieldValue.Interface().(NonEmptyString); if (value == "") { - return NewBareBadRequestError("-318", endpoint, + return NewBareBadRequestError("-032", endpoint, fmt.Sprintf("Field '%s' requires a non-empty string, empty or null provided.", jsonName)). Add("struct-name", structName).Add("field-name", fieldType.Name).Add("json-name", jsonName); } @@ -327,7 +327,7 @@ func baseCheckRequestUsersField(endpoint string, apiRequest any, fieldIndex int) courseContextValue := reflectValue.FieldByName("APIRequestCourseUserContext"); if (!courseContextValue.IsValid() || courseContextValue.IsZero()) { return nil, nil, - NewBareInternalError("-311", endpoint, "A request with type requiring users must embed APIRequestCourseUserContext"). + NewBareInternalError("-025", endpoint, "A request with type requiring users must embed APIRequestCourseUserContext"). Add("request", apiRequest). Add("struct-name", structName).Add("field-name", fieldType.Name).Add("field-type", fieldName); } @@ -335,14 +335,14 @@ func baseCheckRequestUsersField(endpoint string, apiRequest any, fieldIndex int) if (!fieldType.IsExported()) { return nil, nil, - NewInternalError("-312", &courseContext, "Field must be exported."). + NewInternalError("-026", &courseContext, "Field must be exported."). Add("struct-name", structName).Add("field-name", fieldType.Name).Add("field-type", fieldName); } users, err := db.GetUsers(courseContext.Course); if (err != nil) { return nil, nil, - NewInternalError("-313", &courseContext, "Failed to fetch embeded users.").Err(err). + NewInternalError("-027", &courseContext, "Failed to fetch embeded users.").Err(err). Add("struct-name", structName).Add("field-name", fieldType.Name).Add("field-type", fieldName); } diff --git a/api/core/request_fields_test.go b/api/core/request_fields_test.go index fb3aa66d..f029af46 100644 --- a/api/core/request_fields_test.go +++ b/api/core/request_fields_test.go @@ -31,8 +31,8 @@ func TestBadUsersFieldNoContext(test *testing.T) { i, testCase.request); } - if (apiErr.Locator != "-311") { - test.Fatalf("Case %d: Struct with no course context does not return an error with locator '-311', found '%s': '%+v.", + if (apiErr.Locator != "-025") { + test.Fatalf("Case %d: Struct with no course context does not return an error with locator '-025', found '%s': '%+v.", i, apiErr.Locator, testCase.request); } } @@ -78,8 +78,8 @@ func TestBadUsersFieldNotExported(test *testing.T) { i, testCase.request); } - if (apiErr.Locator != "-312") { - test.Fatalf("Case %d: Struct with non-exported field does not return an error with locator '-312', found '%s': '%v.", + if (apiErr.Locator != "-026") { + test.Fatalf("Case %d: Struct with non-exported field does not return an error with locator '-026', found '%s': '%v.", i, apiErr.Locator, apiErr); } } @@ -91,13 +91,13 @@ func TestNonEmptyStringField(test *testing.T) { {&struct{ APIRequest; Text NonEmptyString }{Text: "ZZZ"}, "", "Text"}, - {&struct{ APIRequest; Text NonEmptyString }{}, "-318", "Text"}, - {&struct{ APIRequest; Text NonEmptyString }{Text: ""}, "-318", "Text"}, + {&struct{ APIRequest; Text NonEmptyString }{}, "-032", "Text"}, + {&struct{ APIRequest; Text NonEmptyString }{Text: ""}, "-032", "Text"}, - {&struct{ APIRequest; Text NonEmptyString `json:"text"`}{}, "-318", "text"}, - {&struct{ APIRequest; Text NonEmptyString `json:"text,omitempty"`}{}, "-318", "text"}, - {&struct{ APIRequest; Text NonEmptyString `json:"foo-bar"`}{}, "-318", "foo-bar"}, - {&struct{ APIRequest; Text NonEmptyString `json:"foo-bar,omitempty"`}{}, "-318", "foo-bar"}, + {&struct{ APIRequest; Text NonEmptyString `json:"text"`}{}, "-032", "text"}, + {&struct{ APIRequest; Text NonEmptyString `json:"text,omitempty"`}{}, "-032", "text"}, + {&struct{ APIRequest; Text NonEmptyString `json:"foo-bar"`}{}, "-032", "foo-bar"}, + {&struct{ APIRequest; Text NonEmptyString `json:"foo-bar,omitempty"`}{}, "-032", "foo-bar"}, }; for i, testCase := range testCases { @@ -197,7 +197,7 @@ func TestBadPostFilesFieldNotExported(test *testing.T) { test.Fatalf("Struct with non-exported files does not return an error,"); } - expectedLocator := "-314"; + expectedLocator := "-028"; if (apiErr.Locator != expectedLocator) { test.Fatalf("Struct with non-exported files does not return an error with the correct locator. Expcted '%s', found '%s'.", expectedLocator, apiErr.Locator); @@ -227,7 +227,7 @@ func TestBadPostFilesNoFiles(test *testing.T) { test.Fatalf("Request did not generate an error: '%v'.", response); } - expectedLocator := "-316"; + expectedLocator := "-030"; if (response.Locator != expectedLocator) { test.Fatalf("Error does not have the correct locator. Expcted '%s', found '%s'.", expectedLocator, response.Locator); @@ -263,7 +263,7 @@ func TestBadPostFilesStoreFail(test *testing.T) { test.Fatalf("Request did not generate an error: '%v'.", response); } - expectedLocator := "-315"; + expectedLocator := "-029"; if (response.Locator != expectedLocator) { test.Fatalf("Error does not have the correct locator. Expcted '%s', found '%s'.", expectedLocator, response.Locator); @@ -453,7 +453,7 @@ func testTargetUser[T comparable, V userGetter](test *testing.T, apiErr := ValidateAPIRequest(nil, request, ""); if (apiErr != nil) { if (testCase.permError) { - expectedLocator := "-319"; + expectedLocator := "-033"; if (expectedLocator != apiErr.Locator) { test.Errorf("Case %d: Incorrect error returned on permissions error. Expcted '%s', found '%s'.", i, expectedLocator, apiErr.Locator); @@ -517,7 +517,7 @@ func TestTargetUser(test *testing.T) { apiErr := ValidateAPIRequest(nil, &request, ""); if (apiErr != nil) { if (testCase.target == "") { - expectedLocator := "-320"; + expectedLocator := "-034"; if (expectedLocator != apiErr.Locator) { test.Errorf("Case %d: Incorrect error returned on empty string. Expcted '%s', found '%s'.", i, expectedLocator, apiErr.Locator); diff --git a/api/core/routing.go b/api/core/routing.go index 36af6c58..ba13c88d 100644 --- a/api/core/routing.go +++ b/api/core/routing.go @@ -112,7 +112,7 @@ func NewAPIRoute(pattern string, apiHandler any) *Route { log.Error().Any("value", value).Str("endpoint", request.URL.Path). Msg("Recovered from a panic when handling an API endpoint."); - apiErr := NewBareInternalError("-101", request.URL.Path, "Recovered from a panic when handling an API endpoint."). + apiErr := NewBareInternalError("-001", request.URL.Path, "Recovered from a panic when handling an API endpoint."). Add("value", value); err = sendAPIResponse(nil, response, nil, apiErr, false); @@ -171,7 +171,7 @@ func sendAPIResponse(apiRequest ValidAPIRequest, response http.ResponseWriter, payload, err := util.ToJSON(apiResponse); if (err != nil) { - apiErr = NewBareInternalError("-102", "", "Could not serialize API response.").Err(err); + apiErr = NewBareInternalError("-002", "", "Could not serialize API response.").Err(err); apiResponse = apiErr.ToResponse(); if (hardFail) { @@ -210,7 +210,7 @@ func createAPIRequest(request *http.Request, apiHandler ValidAPIHandler) (ValidA if (strings.Contains(strings.Join(request.Header["Content-Type"], " "), "multipart/form-data")) { err := request.ParseMultipartForm(MAX_FORM_MEM_SIZE_BYTES); if (err != nil) { - return nil, NewBareBadRequestError("-103", endpoint, + return nil, NewBareBadRequestError("-003", endpoint, fmt.Sprintf("POST request is improperly formatted.")). Err(err); } @@ -219,14 +219,14 @@ func createAPIRequest(request *http.Request, apiHandler ValidAPIHandler) (ValidA // Get the text from the POST. textContent := request.PostFormValue(API_REQUEST_CONTENT_KEY); if (textContent == "") { - return nil, NewBareBadRequestError("-104", endpoint, + return nil, NewBareBadRequestError("-004", endpoint, fmt.Sprintf("JSON payload for POST form key '%s' is empty.", API_REQUEST_CONTENT_KEY)); } // Unmarshal the JSON. err := util.JSONFromString(textContent, apiRequest); if (err != nil) { - return nil, NewBareBadRequestError("-105", endpoint, + return nil, NewBareBadRequestError("-005", endpoint, fmt.Sprintf("JSON payload for POST form key '%s' is not valid JSON.", API_REQUEST_CONTENT_KEY)). Err(err); } @@ -267,39 +267,39 @@ func validateAPIHandler(endpoint string, apiHandler any) (ValidAPIHandler, *APIE reflectType := reflect.TypeOf(apiHandler); if (reflectValue.Kind() != reflect.Func) { - return nil, NewBareInternalError("-106", endpoint, "API handler is not a function."). + return nil, NewBareInternalError("-006", endpoint, "API handler is not a function."). Add("kind", reflectValue.Kind().String()); } funcInfo := getFuncInfo(apiHandler); if (reflectType.NumIn() != 1) { - return nil, NewBareInternalError("-107", endpoint, "API handler does not have exactly 1 argument."). + return nil, NewBareInternalError("-007", endpoint, "API handler does not have exactly 1 argument."). Add("num-in", reflectType.NumIn()). Add("function-info", funcInfo); } argumentType := reflectType.In(0); if (argumentType.Kind() != reflect.Pointer) { - return nil, NewBareInternalError("-108", endpoint, "API handler's argument is not a pointer."). + return nil, NewBareInternalError("-008", endpoint, "API handler's argument is not a pointer."). Add("kind", argumentType.Kind().String()). Add("function-info", funcInfo); } if (reflectType.NumOut() != 2) { - return nil, NewBareInternalError("-109", endpoint, "API handler does not return exactly 2 arguments."). + return nil, NewBareInternalError("-009", endpoint, "API handler does not return exactly 2 arguments."). Add("num-out", reflectType.NumOut()). Add("function-info", funcInfo); } if (reflectType.Out(0).Kind() != reflect.Pointer) { - return nil, NewBareInternalError("-110", endpoint, "API handler's first return value is not a pointer."). + return nil, NewBareInternalError("-010", endpoint, "API handler's first return value is not a pointer."). Add("kind", reflectType.Out(0).Kind().String()). Add("function-info", funcInfo); } if (reflectType.Out(1) != reflect.TypeOf((*APIError)(nil))) { - return nil, NewBareInternalError("-111", endpoint, "API handler's second return value is a *APIError."). + return nil, NewBareInternalError("-011", endpoint, "API handler's second return value is a *APIError."). Add("type", reflectType.Out(1).String()). Add("function-info", funcInfo); } diff --git a/api/core/routing_test.go b/api/core/routing_test.go index 96c7fdf5..4735983f 100644 --- a/api/core/routing_test.go +++ b/api/core/routing_test.go @@ -27,7 +27,7 @@ func TestAPIPanic(test *testing.T) { routes = append(routes, NewAPIRoute(endpoint, handler)); response := SendTestAPIRequest(test, endpoint, nil); - if (response.Locator != "-101") { + if (response.Locator != "-001") { test.Fatalf("Response does not have panic locator of '-501', actual locator: '%s'.", response.Locator); } } @@ -37,20 +37,20 @@ func TestAPIPanic(test *testing.T) { func TestMalformedHandlers(test *testing.T) { // Define all the handlers. testCases := []struct{handler any; locator string}{ - {"", "-106"}, - {nil, "-106"}, - {0, "-106"}, - {func() (*any, *APIError) { return nil, nil }, "-107"}, - {func(request *BaseTestRequest, testarg int) (*any, *APIError) { return nil, nil }, "-107"}, - {func(request BaseTestRequest) (*any, *APIError) { return nil, nil }, "-108"}, - {func(request int) (*any, *APIError) { return nil, nil }, "-108"}, - {func(request *BaseTestRequest) (*any) { return nil }, "-109"}, - {func(request *BaseTestRequest) (int, *any, *APIError) { return 0, nil, nil }, "-109"}, - {func(request *BaseTestRequest) (any, *APIError) { return nil, nil }, "-110"}, - {func(request *BaseTestRequest) (int, *APIError) { return 0, nil }, "-110"}, - {func(request *BaseTestRequest) (*any, APIError) { return nil, APIError{} }, "-111"}, - {func(request *BaseTestRequest) (*any, any) { return nil, nil }, "-111"}, - {func(request *BaseTestRequest) (*any, int) { return nil, 0}, "-111"}, + {"", "-006"}, + {nil, "-006"}, + {0, "-006"}, + {func() (*any, *APIError) { return nil, nil }, "-007"}, + {func(request *BaseTestRequest, testarg int) (*any, *APIError) { return nil, nil }, "-007"}, + {func(request BaseTestRequest) (*any, *APIError) { return nil, nil }, "-008"}, + {func(request int) (*any, *APIError) { return nil, nil }, "-008"}, + {func(request *BaseTestRequest) (*any) { return nil }, "-009"}, + {func(request *BaseTestRequest) (int, *any, *APIError) { return 0, nil, nil }, "-009"}, + {func(request *BaseTestRequest) (any, *APIError) { return nil, nil }, "-010"}, + {func(request *BaseTestRequest) (int, *APIError) { return 0, nil }, "-010"}, + {func(request *BaseTestRequest) (*any, APIError) { return nil, APIError{} }, "-011"}, + {func(request *BaseTestRequest) (*any, any) { return nil, nil }, "-011"}, + {func(request *BaseTestRequest) (*any, int) { return nil, 0}, "-011"}, }; for i, testCase := range testCases { @@ -69,11 +69,11 @@ func TestMalformedHandlers(test *testing.T) { func TestBadRequestEmptyContent(test *testing.T) { // Define all the content that will go in the post form. testCases := []struct{form map[string]string; locator string}{ - {map[string]string{}, "-104"}, - {map[string]string{API_REQUEST_CONTENT_KEY: ``}, "-104"}, - {map[string]string{API_REQUEST_CONTENT_KEY: `Z`}, "-105"}, - {map[string]string{API_REQUEST_CONTENT_KEY: `1`}, "-105"}, - {map[string]string{API_REQUEST_CONTENT_KEY: `[]`}, "-105"}, + {map[string]string{}, "-004"}, + {map[string]string{API_REQUEST_CONTENT_KEY: ``}, "-004"}, + {map[string]string{API_REQUEST_CONTENT_KEY: `Z`}, "-005"}, + {map[string]string{API_REQUEST_CONTENT_KEY: `1`}, "-005"}, + {map[string]string{API_REQUEST_CONTENT_KEY: `[]`}, "-005"}, }; endpoint := `/test/api/bad-request/empty-content`; @@ -121,7 +121,7 @@ func TestNonMarshalableResponse(test *testing.T) { routes = append(routes, NewAPIRoute(endpoint, handler)); response := SendTestAPIRequest(test, endpoint, nil); - if (response.Locator != "-102") { + if (response.Locator != "-002") { test.Fatalf("Response does not locator of '-531', actual locator: '%s'.", response.Locator); } } diff --git a/api/lms/sync_users.go b/api/lms/sync_users.go index a3894acf..90b96cda 100644 --- a/api/lms/sync_users.go +++ b/api/lms/sync_users.go @@ -19,13 +19,13 @@ type SyncUsersResponse struct { func HandleSyncUsers(request *SyncUsersRequest) (*SyncUsersResponse, *core.APIError) { if (request.Course.GetLMSAdapter() == nil) { - return nil, core.NewBadRequestError("-503", &request.APIRequest, "Course is not linked to an LMS."). + return nil, core.NewBadRequestError("-403", &request.APIRequest, "Course is not linked to an LMS."). Add("course", request.Course.GetID()); } result, err := procedures.SyncAllLMSUsers(request.Course, request.DryRun, !request.SkipEmails); if (err != nil) { - return nil, core.NewInternalError("-504", &request.APIRequestCourseUserContext, + return nil, core.NewInternalError("-404", &request.APIRequestCourseUserContext, "Failed to sync LMS users.").Err(err); } diff --git a/api/lms/sync_users_test.go b/api/lms/sync_users_test.go index 79616591..a312cf61 100644 --- a/api/lms/sync_users_test.go +++ b/api/lms/sync_users_test.go @@ -31,7 +31,7 @@ func TestAPISyncUsers(test *testing.T) { response := core.SendTestAPIRequestFull(test, core.NewEndpoint(`lms/sync/users`), fields, nil, testCase.role); if (!response.Success) { if (testCase.permError) { - expectedLocator := "-306"; + expectedLocator := "-020"; if (response.Locator != expectedLocator) { test.Errorf("Case %d: Incorrect error returned on permissions error. Expcted '%s', found '%s'.", i, expectedLocator, response.Locator); diff --git a/api/lms/upload_scores.go b/api/lms/upload_scores.go index bfe5e01a..0d4b9d72 100644 --- a/api/lms/upload_scores.go +++ b/api/lms/upload_scores.go @@ -35,7 +35,7 @@ type RowEntry struct { func HandleUploadScores(request *UploadScoresRequest) (*UploadScoresResponse, *core.APIError) { if (request.Course.GetLMSAdapter() == nil) { - return nil, core.NewBadRequestError("-505", &request.APIRequest, "Course is not linked to an LMS."). + return nil, core.NewBadRequestError("-405", &request.APIRequest, "Course is not linked to an LMS."). Add("course", request.Course.GetID()); } @@ -48,7 +48,7 @@ func HandleUploadScores(request *UploadScoresRequest) (*UploadScoresResponse, *c err := lms.UpdateAssignmentScores(request.Course, string(request.AssignmentLMSID), scores); if (err != nil) { - return nil, core.NewInternalError("-506", &request.APIRequestCourseUserContext, + return nil, core.NewInternalError("-406", &request.APIRequestCourseUserContext, "Failed to upload LMS scores.").Err(err); } diff --git a/api/lms/upload_scores_test.go b/api/lms/upload_scores_test.go index 8183e292..32cf3cc9 100644 --- a/api/lms/upload_scores_test.go +++ b/api/lms/upload_scores_test.go @@ -128,9 +128,9 @@ func TestUploadScores(test *testing.T) { if (!response.Success) { expectedLocator := ""; if (testCase.permError) { - expectedLocator = "-306"; + expectedLocator = "-020"; } else if (testCase.failUpdate) { - expectedLocator = "-506"; + expectedLocator = "-406"; } if (expectedLocator == "") { diff --git a/api/lms/user_get.go b/api/lms/user_get.go index 6478dd69..4bf92860 100644 --- a/api/lms/user_get.go +++ b/api/lms/user_get.go @@ -20,7 +20,7 @@ type UserGetResponse struct { func HandleUserGet(request *UserGetRequest) (*UserGetResponse, *core.APIError) { if (request.Course.GetLMSAdapter() == nil) { - return nil, core.NewBadRequestError("-501", &request.APIRequest, "Course is not linked to an LMS."). + return nil, core.NewBadRequestError("-401", &request.APIRequest, "Course is not linked to an LMS."). Add("course", request.Course.GetID()); } @@ -35,7 +35,7 @@ func HandleUserGet(request *UserGetRequest) (*UserGetResponse, *core.APIError) { lmsUser, err := lms.FetchUser(request.Course, string(request.TargetUser.Email)); if (err != nil) { - return nil, core.NewInternalError("-502", &request.APIRequestCourseUserContext, + return nil, core.NewInternalError("-402", &request.APIRequestCourseUserContext, "Failed to fetch LMS user.").Err(err).Add("email", string(request.TargetUser.Email)); } diff --git a/api/lms/user_get_test.go b/api/lms/user_get_test.go index a0c267f0..19312bff 100644 --- a/api/lms/user_get_test.go +++ b/api/lms/user_get_test.go @@ -33,9 +33,9 @@ func TestUserGet(test *testing.T) { if (!response.Success) { expectedLocator := ""; if (testCase.permError) { - expectedLocator = "-306"; + expectedLocator = "-020"; } else if (testCase.target == "") { - expectedLocator = "-320"; + expectedLocator = "-034"; } if (expectedLocator == "") { diff --git a/api/submission/fetch_scores.go b/api/submission/fetch_scores.go index c758f33f..8c595a9b 100644 --- a/api/submission/fetch_scores.go +++ b/api/submission/fetch_scores.go @@ -21,7 +21,7 @@ type FetchScoresResponse struct { func HandleFetchScores(request *FetchScoresRequest) (*FetchScoresResponse, *core.APIError) { submissionInfos, err := db.GetRecentSubmissionSurvey(request.Assignment, request.FilterRole); if (err != nil) { - return nil, core.NewInternalError("-404", &request.APIRequestCourseUserContext, "Failed to get submission summaries.").Err(err); + return nil, core.NewInternalError("-602", &request.APIRequestCourseUserContext, "Failed to get submission summaries.").Err(err); } return &FetchScoresResponse{submissionInfos}, nil; diff --git a/api/submission/fetch_scores_test.go b/api/submission/fetch_scores_test.go index 5ff47470..b8b9d58d 100644 --- a/api/submission/fetch_scores_test.go +++ b/api/submission/fetch_scores_test.go @@ -45,7 +45,7 @@ func TestFetchScores(test *testing.T) { response := core.SendTestAPIRequestFull(test, core.NewEndpoint(`submission/fetch/scores`), fields, nil, testCase.role); if (!response.Success) { if (testCase.permError) { - expectedLocator := "-306"; + expectedLocator := "-020"; if (response.Locator != expectedLocator) { test.Errorf("Case %d: Incorrect error returned on permissions error. Expcted '%s', found '%s'.", i, expectedLocator, response.Locator); diff --git a/api/submission/fetch_submission.go b/api/submission/fetch_submission.go index a10f2cb5..bbd0cfc3 100644 --- a/api/submission/fetch_submission.go +++ b/api/submission/fetch_submission.go @@ -31,7 +31,7 @@ func HandleFetchSubmission(request *FetchSubmissionRequest) (*FetchSubmissionRes gradingResult, err := db.GetSubmissionContents(request.Assignment, request.TargetUser.Email, request.TargetSubmission); if (err != nil) { - return nil, core.NewInternalError("-409", &request.APIRequestCourseUserContext, "Failed to get submission contents."). + return nil, core.NewInternalError("-604", &request.APIRequestCourseUserContext, "Failed to get submission contents."). Err(err).Add("email", request.TargetUser.Email).Add("submission", request.TargetSubmission); } diff --git a/api/submission/fetch_submission_test.go b/api/submission/fetch_submission_test.go index b0593b6d..e3ddab8a 100644 --- a/api/submission/fetch_submission_test.go +++ b/api/submission/fetch_submission_test.go @@ -79,7 +79,7 @@ func TestFetchSubmission(test *testing.T) { response := core.SendTestAPIRequestFull(test, core.NewEndpoint(`submission/fetch/submission`), fields, nil, testCase.role); if (!response.Success) { if (testCase.permError) { - expectedLocator := "-319"; + expectedLocator := "-033"; if (response.Locator != expectedLocator) { test.Errorf("Case %d: Incorrect error returned on permissions error. Expcted '%s', found '%s'.", i, expectedLocator, response.Locator); diff --git a/api/submission/fetch_submissions.go b/api/submission/fetch_submissions.go index 5a8f24a2..e7ecbe10 100644 --- a/api/submission/fetch_submissions.go +++ b/api/submission/fetch_submissions.go @@ -20,7 +20,7 @@ type FetchSubmissionsResponse struct { func HandleFetchSubmissions(request *FetchSubmissionsRequest) (*FetchSubmissionsResponse, *core.APIError) { results, err := db.GetRecentSubmissionContents(request.Assignment, request.FilterRole); if (err != nil) { - return nil, core.NewInternalError("-412", &request.APIRequestCourseUserContext, "Failed to get submissions."). + return nil, core.NewInternalError("-605", &request.APIRequestCourseUserContext, "Failed to get submissions."). Err(err); } diff --git a/api/submission/fetch_submissions_test.go b/api/submission/fetch_submissions_test.go index a74e0835..e0a16323 100644 --- a/api/submission/fetch_submissions_test.go +++ b/api/submission/fetch_submissions_test.go @@ -33,7 +33,7 @@ func TestFetchSubmissions(test *testing.T) { response := core.SendTestAPIRequestFull(test, core.NewEndpoint(`submission/fetch/submissions`), nil, nil, testCase.role); if (!response.Success) { if (testCase.permError) { - expectedLocator := "-306"; + expectedLocator := "-020"; if (response.Locator != expectedLocator) { test.Errorf("Case %d: Incorrect error returned on permissions error. Expcted '%s', found '%s'.", i, expectedLocator, response.Locator); diff --git a/api/submission/history.go b/api/submission/history.go index 34a65418..bbc48396 100644 --- a/api/submission/history.go +++ b/api/submission/history.go @@ -32,7 +32,7 @@ func HandleHistory(request *HistoryRequest) (*HistoryResponse, *core.APIError) { history, err := db.GetSubmissionHistory(request.Assignment, request.TargetUser.Email); if (err != nil) { - return nil, core.NewInternalError("-407", &request.APIRequestCourseUserContext, "Failed to get submission history."). + return nil, core.NewInternalError("-603", &request.APIRequestCourseUserContext, "Failed to get submission history."). Err(err).Add("user", request.TargetUser.Email); } diff --git a/api/submission/history_test.go b/api/submission/history_test.go index 9731b7d5..cfd1ade3 100644 --- a/api/submission/history_test.go +++ b/api/submission/history_test.go @@ -33,7 +33,7 @@ func TestHistory(test *testing.T) { response := core.SendTestAPIRequestFull(test, core.NewEndpoint(`submission/history`), fields, nil, testCase.role); if (!response.Success) { if (testCase.permError) { - expectedLocator := "-319"; + expectedLocator := "-033"; if (response.Locator != expectedLocator) { test.Errorf("Case %d: Incorrect error returned on permissions error. Expcted '%s', found '%s'.", i, expectedLocator, response.Locator); diff --git a/api/submission/peek.go b/api/submission/peek.go index 6fc8e97f..0d4518fc 100644 --- a/api/submission/peek.go +++ b/api/submission/peek.go @@ -31,7 +31,7 @@ func HandlePeek(request *PeekRequest) (*PeekResponse, *core.APIError) { submissionResult, err := db.GetSubmissionResult(request.Assignment, request.TargetUser.Email, request.TargetSubmission); if (err != nil) { - return nil, core.NewInternalError("-402", &request.APIRequestCourseUserContext, "Failed to get submission result."). + return nil, core.NewInternalError("-601", &request.APIRequestCourseUserContext, "Failed to get submission result."). Err(err).Add("user", request.TargetUser.Email).Add("submission", request.TargetSubmission); } diff --git a/api/submission/peek_test.go b/api/submission/peek_test.go index 420a4518..718e95eb 100644 --- a/api/submission/peek_test.go +++ b/api/submission/peek_test.go @@ -62,7 +62,7 @@ func TestPeek(test *testing.T) { response := core.SendTestAPIRequestFull(test, core.NewEndpoint(`submission/peek`), fields, nil, testCase.role); if (!response.Success) { if (testCase.permError) { - expectedLocator := "-319"; + expectedLocator := "-033"; if (response.Locator != expectedLocator) { test.Errorf("Case %d: Incorrect error returned on permissions error. Expcted '%s', found '%s'.", i, expectedLocator, response.Locator); diff --git a/api/submission/remove_submission.go b/api/submission/remove_submission.go index aeacde3e..1eec5ecc 100644 --- a/api/submission/remove_submission.go +++ b/api/submission/remove_submission.go @@ -29,7 +29,7 @@ func HandleRemoveSubmission(request *RemoveSubmissionRequest) (*RemoveSubmission doesExist, err := db.RemoveSubmission(request.Assignment, request.TargetUser.Email, request.TargetSubmission); if (err != nil) { - return nil, core.NewInternalError("-418", &request.APIRequestCourseUserContext, "Failed to remove the submission."). + return nil, core.NewInternalError("-606", &request.APIRequestCourseUserContext, "Failed to remove the submission."). Err(err).Add("user", request.TargetUser.Email).Add("submission", request.TargetSubmission); } diff --git a/api/submission/remove_submission_test.go b/api/submission/remove_submission_test.go index 644338a4..84551771 100644 --- a/api/submission/remove_submission_test.go +++ b/api/submission/remove_submission_test.go @@ -63,7 +63,7 @@ func TestRemoveSubmission(test *testing.T) { if (!response.Success) { if (testCase.permError) { - expectedLocator := "-306"; + expectedLocator := "-020"; if (response.Locator != expectedLocator) { test.Errorf("Case %d: Incorrect error returned on permissions error. Expected '%s', found '%s'.", i, expectedLocator, response.Locator); diff --git a/api/user/add.go b/api/user/add.go index ca5afcdf..8a45ce85 100644 --- a/api/user/add.go +++ b/api/user/add.go @@ -71,7 +71,7 @@ func HandleAdd(request *AddRequest) (*AddResponse, *core.APIError) { result, err := db.SyncUsers(request.Course, newUsers, request.Force, request.DryRun, !request.SkipEmails); if (err != nil) { - return nil, core.NewInternalError("-603", &request.APIRequestCourseUserContext, + return nil, core.NewInternalError("-803", &request.APIRequestCourseUserContext, "Failed to sync new users.").Err(err); } @@ -87,7 +87,7 @@ func HandleAdd(request *AddRequest) (*AddResponse, *core.APIError) { users, err := db.GetUsers(request.Course); if (err != nil) { - return nil, core.NewInternalError("-604", &request.APIRequestCourseUserContext, + return nil, core.NewInternalError("-804", &request.APIRequestCourseUserContext, "Failed to fetch users").Err(err); } diff --git a/api/user/add_test.go b/api/user/add_test.go index eba2246e..cf30d265 100644 --- a/api/user/add_test.go +++ b/api/user/add_test.go @@ -140,7 +140,7 @@ func TestUserAdd(test *testing.T) { response := core.SendTestAPIRequestFull(test, core.NewEndpoint(`user/add`), fields, nil, testCase.role); if (!response.Success) { if (testCase.permError) { - expectedLocator := "-306"; + expectedLocator := "-020"; if (response.Locator != expectedLocator) { test.Errorf("Case %d: Incorrect error returned. Expcted '%s', found '%s'.", i, expectedLocator, response.Locator); diff --git a/api/user/change_password.go b/api/user/change_password.go index 4037595c..d6512180 100644 --- a/api/user/change_password.go +++ b/api/user/change_password.go @@ -28,7 +28,7 @@ func HandleChangePassword(request *ChangePasswordRequest) (*ChangePasswordRespon response.FoundUser = true; if (request.TargetUser.User.Role > request.User.Role) { - return nil, core.NewBadPermissionsError("-605", &request.APIRequestCourseUserContext, request.TargetUser.User.Role, + return nil, core.NewBadPermissionsError("-805", &request.APIRequestCourseUserContext, request.TargetUser.User.Role, "Cannot modify a user with a higher role.").Add("target-user", request.TargetUser.User.Email); } @@ -42,20 +42,20 @@ func HandleChangePassword(request *ChangePasswordRequest) (*ChangePasswordRespon } if (err != nil) { - return nil, core.NewInternalError("-606", &request.APIRequestCourseUserContext, + return nil, core.NewInternalError("-806", &request.APIRequestCourseUserContext, "Failed to set password.").Err(err).Add("email", request.TargetUser.Email); } err = db.SaveUser(request.Course, request.TargetUser.User); if (err != nil) { - return nil, core.NewInternalError("-607", &request.APIRequestCourseUserContext, + return nil, core.NewInternalError("-807", &request.APIRequestCourseUserContext, "Failed to save user.").Err(err).Add("email", request.TargetUser.Email); } if (pass != "") { err = model.SendUserAddEmail(request.TargetUser.User, pass, true, true, false, false); if (err != nil) { - return nil, core.NewInternalError("-608", &request.APIRequestCourseUserContext, + return nil, core.NewInternalError("-808", &request.APIRequestCourseUserContext, "Failed to send user email.").Err(err).Add("email", request.TargetUser.Email); } } diff --git a/api/user/change_password_test.go b/api/user/change_password_test.go index f0642c78..391165a3 100644 --- a/api/user/change_password_test.go +++ b/api/user/change_password_test.go @@ -70,9 +70,9 @@ func TestChangePassword(test *testing.T) { if (!response.Success) { expectedLocator := ""; if (testCase.permError) { - expectedLocator = "-319"; + expectedLocator = "-033"; } else if (testCase.advPermError) { - expectedLocator = "-605"; + expectedLocator = "-805"; } if (expectedLocator == "") { diff --git a/api/user/get_test.go b/api/user/get_test.go index 873bf458..2e143b6d 100644 --- a/api/user/get_test.go +++ b/api/user/get_test.go @@ -33,9 +33,9 @@ func TestUserGet(test *testing.T) { if (!response.Success) { expectedLocator := ""; if (testCase.permError) { - expectedLocator = "-306"; + expectedLocator = "-020"; } else if (testCase.target == "") { - expectedLocator = "-320"; + expectedLocator = "-034"; } if (expectedLocator == "") { diff --git a/api/user/remove.go b/api/user/remove.go index cc6254c3..22aa3207 100644 --- a/api/user/remove.go +++ b/api/user/remove.go @@ -26,13 +26,13 @@ func HandleRemove(request *RemoveRequest) (*RemoveResponse, *core.APIError) { response.FoundUser = true; if (request.TargetUser.User.Role > request.User.Role) { - return nil, core.NewBadPermissionsError("-601", &request.APIRequestCourseUserContext, request.TargetUser.User.Role, + return nil, core.NewBadPermissionsError("-801", &request.APIRequestCourseUserContext, request.TargetUser.User.Role, "Cannot remove a user with a higher role.").Add("target-user", request.TargetUser.User.Email); } _, err := db.RemoveUser(request.Course, request.TargetUser.Email); if (err != nil) { - return nil, core.NewInternalError("-602", &request.APIRequestCourseUserContext, + return nil, core.NewInternalError("-802", &request.APIRequestCourseUserContext, "Failed to remove user.").Err(err).Add("email", request.TargetUser.Email); } diff --git a/api/user/remove_test.go b/api/user/remove_test.go index a1712431..a737957e 100644 --- a/api/user/remove_test.go +++ b/api/user/remove_test.go @@ -45,9 +45,9 @@ func TestUserRemove(test *testing.T) { if (!response.Success) { expectedLocator := ""; if (testCase.basicPermError) { - expectedLocator = "-306"; + expectedLocator = "-020"; } else if (testCase.advPermError) { - expectedLocator = "-601"; + expectedLocator = "-801"; } if (expectedLocator == "") {