use of teammates.common.exception.JoinCourseException in project teammates by TEAMMATES.
the class AccountsLogic method verifyStudentJoinCourseRequest.
private void verifyStudentJoinCourseRequest(String encryptedKey, String googleId) throws JoinCourseException {
StudentAttributes studentRole = studentsLogic.getStudentForRegistrationKey(encryptedKey);
if (studentRole == null) {
throw new JoinCourseException(Const.StatusCodes.INVALID_KEY, "You have used an invalid join link: %s");
} else if (studentRole.isRegistered()) {
if (studentRole.googleId.equals(googleId)) {
throw new JoinCourseException(Const.StatusCodes.ALREADY_JOINED, "You (" + googleId + ") have already joined this course");
}
throw new JoinCourseException(Const.StatusCodes.KEY_BELONGS_TO_DIFFERENT_USER, String.format(Const.StatusMessages.JOIN_COURSE_KEY_BELONGS_TO_DIFFERENT_USER, StringHelper.obscure(studentRole.googleId)));
}
StudentAttributes existingStudent = studentsLogic.getStudentForCourseIdAndGoogleId(studentRole.course, googleId);
if (existingStudent != null) {
throw new JoinCourseException(String.format(Const.StatusMessages.JOIN_COURSE_GOOGLE_ID_BELONGS_TO_DIFFERENT_USER, googleId));
}
}
use of teammates.common.exception.JoinCourseException in project teammates by TEAMMATES.
the class AccountsLogicTest method testJoinCourseForStudent.
@Test
public void testJoinCourseForStudent() throws Exception {
String correctStudentId = "correctStudentId";
String courseId = "idOfTypicalCourse1";
String originalEmail = "original@email.com";
// Create correct student with original@email.com
StudentAttributes studentData = StudentAttributes.builder(courseId, "name", originalEmail).withSection("sectionName").withTeam("teamName").withComments("").build();
studentsLogic.createStudentCascadeWithoutDocument(studentData);
studentData = StudentsLogic.inst().getStudentForEmail(courseId, originalEmail);
verifyPresentInDatastore(studentData);
______TS("failure: wrong key");
try {
accountsLogic.joinCourseForStudent(StringHelper.encrypt("wrongkey"), correctStudentId);
signalFailureToDetectException();
} catch (JoinCourseException e) {
assertEquals("You have used an invalid join link: %s", e.getMessage());
}
______TS("failure: invalid parameters");
try {
accountsLogic.joinCourseForStudent(StringHelper.encrypt(studentData.key), "wrong student");
signalFailureToDetectException();
} catch (InvalidParametersException e) {
AssertHelper.assertContains(FieldValidator.REASON_INCORRECT_FORMAT, e.getMessage());
}
______TS("failure: googleID belongs to an existing student in the course");
String existingId = "AccLogicT.existing.studentId";
StudentAttributes existingStudent = StudentAttributes.builder(courseId, "name", "differentEmail@email.com").withSection("sectionName").withTeam("teamName").withComments("").withGoogleId(existingId).build();
studentsLogic.createStudentCascadeWithoutDocument(existingStudent);
try {
accountsLogic.joinCourseForStudent(StringHelper.encrypt(studentData.key), existingId);
signalFailureToDetectException();
} catch (JoinCourseException e) {
assertEquals(String.format(Const.StatusMessages.JOIN_COURSE_GOOGLE_ID_BELONGS_TO_DIFFERENT_USER, existingId), e.getMessage());
}
______TS("success: without encryption and account already exists");
StudentProfileAttributes spa = StudentProfileAttributes.builder(correctStudentId).withInstitute("TEAMMATES Test Institute 1").build();
AccountAttributes accountData = AccountAttributes.builder().withGoogleId(correctStudentId).withName("nameABC").withEmail("real@gmail.com").withInstitute("TEAMMATES Test Institute 1").withIsInstructor(true).withStudentProfileAttributes(spa).build();
accountsLogic.createAccount(accountData);
accountsLogic.joinCourseForStudent(StringHelper.encrypt(studentData.key), correctStudentId);
studentData.googleId = accountData.googleId;
verifyPresentInDatastore(studentData);
assertEquals(correctStudentId, logic.getStudentForEmail(studentData.course, studentData.email).googleId);
______TS("failure: already joined");
try {
accountsLogic.joinCourseForStudent(StringHelper.encrypt(studentData.key), correctStudentId);
signalFailureToDetectException();
} catch (JoinCourseException e) {
assertEquals("You (" + correctStudentId + ") have already joined this course", e.getMessage());
}
______TS("failure: valid key belongs to a different user");
try {
accountsLogic.joinCourseForStudent(StringHelper.encrypt(studentData.key), "wrongstudent");
signalFailureToDetectException();
} catch (JoinCourseException e) {
assertEquals("The join link used belongs to a different user whose " + "Google ID is corre..dentId (only part of the Google ID is " + "shown to protect privacy). If that Google ID is owned by you, " + "please logout and re-login using that Google account. " + "If it doesn’t belong to you, please " + "<a href=\"mailto:" + Config.SUPPORT_EMAIL + "?" + "body=Your name:%0AYour course:%0AYour university:\">" + "contact us</a> so that we can investigate.", e.getMessage());
}
______TS("success: with encryption and new account to be created");
logic.deleteAccount(correctStudentId);
originalEmail = "email2@gmail.com";
studentData = StudentAttributes.builder(courseId, "name", originalEmail).withSection("sectionName").withTeam("teamName").withComments("").build();
studentsLogic.createStudentCascadeWithoutDocument(studentData);
studentData = StudentsLogic.inst().getStudentForEmail(courseId, originalEmail);
String encryptedKey = StringHelper.encrypt(studentData.key);
accountsLogic.joinCourseForStudent(encryptedKey, correctStudentId);
studentData.googleId = correctStudentId;
verifyPresentInDatastore(studentData);
assertEquals(correctStudentId, logic.getStudentForEmail(studentData.course, studentData.email).googleId);
// check that we have the corresponding new account created.
accountData.googleId = correctStudentId;
accountData.email = originalEmail;
accountData.name = "name";
accountData.isInstructor = false;
verifyPresentInDatastore(accountData);
______TS("success: join course as student does not revoke instructor status");
// promote account to instructor
accountsLogic.makeAccountInstructor(correctStudentId);
// make the student 'unregistered' again
studentData.googleId = "";
studentsLogic.updateStudentCascadeWithoutDocument(studentData.email, studentData);
assertEquals("", logic.getStudentForEmail(studentData.course, studentData.email).googleId);
// rejoin
logic.joinCourseForStudent(encryptedKey, correctStudentId);
assertEquals(correctStudentId, logic.getStudentForEmail(studentData.course, studentData.email).googleId);
// check if still instructor
assertTrue(logic.isInstructor(correctStudentId));
accountsLogic.deleteAccountCascade(correctStudentId);
accountsLogic.deleteAccountCascade(existingId);
}
use of teammates.common.exception.JoinCourseException in project teammates by TEAMMATES.
the class AccountsLogicTest method testJoinCourseForInstructor.
@SuppressWarnings("deprecation")
@Test
public void testJoinCourseForInstructor() throws Exception {
InstructorAttributes instructor = dataBundle.instructors.get("instructorNotYetJoinCourse");
String loggedInGoogleId = "AccLogicT.instr.id";
String encryptedKey = instructorsLogic.getEncryptedKeyForInstructor(instructor.courseId, instructor.email);
______TS("failure: googleID belongs to an existing instructor in the course");
try {
accountsLogic.joinCourseForInstructor(encryptedKey, "idOfInstructorWithOnlyOneSampleCourse");
signalFailureToDetectException();
} catch (JoinCourseException e) {
assertEquals(String.format(Const.StatusMessages.JOIN_COURSE_GOOGLE_ID_BELONGS_TO_DIFFERENT_USER, "idOfInstructorWithOnlyOneSampleCourse"), e.getMessage());
}
______TS("success: instructor joined and new account be created");
accountsLogic.joinCourseForInstructor(encryptedKey, loggedInGoogleId);
InstructorAttributes joinedInstructor = instructorsLogic.getInstructorForEmail(instructor.courseId, instructor.email);
assertEquals(loggedInGoogleId, joinedInstructor.googleId);
AccountAttributes accountCreated = accountsLogic.getAccount(loggedInGoogleId);
assertNotNull(accountCreated);
______TS("success: instructor joined but Account object creation goes wrong");
// Delete account to simulate Account object creation goes wrong
AccountsDb accountsDb = new AccountsDb();
accountsDb.deleteAccount(loggedInGoogleId);
// Try to join course again, Account object should be recreated
accountsLogic.joinCourseForInstructor(encryptedKey, loggedInGoogleId);
joinedInstructor = instructorsLogic.getInstructorForEmail(instructor.courseId, instructor.email);
assertEquals(loggedInGoogleId, joinedInstructor.googleId);
accountCreated = accountsLogic.getAccount(loggedInGoogleId);
assertNotNull(accountCreated);
accountsLogic.deleteAccountCascade(loggedInGoogleId);
______TS("success: instructor joined but account already exists");
AccountAttributes nonInstrAccount = dataBundle.accounts.get("student1InCourse1");
InstructorAttributes newIns = InstructorAttributes.builder(null, instructor.courseId, nonInstrAccount.name, nonInstrAccount.email).build();
instructorsLogic.createInstructor(newIns);
encryptedKey = instructorsLogic.getEncryptedKeyForInstructor(instructor.courseId, nonInstrAccount.email);
assertFalse(accountsLogic.getAccount(nonInstrAccount.googleId).isInstructor);
accountsLogic.joinCourseForInstructor(encryptedKey, nonInstrAccount.googleId);
joinedInstructor = instructorsLogic.getInstructorForEmail(instructor.courseId, nonInstrAccount.email);
assertEquals(nonInstrAccount.googleId, joinedInstructor.googleId);
assertTrue(accountsLogic.getAccount(nonInstrAccount.googleId).isInstructor);
instructorsLogic.verifyInstructorExists(nonInstrAccount.googleId);
______TS("success: instructor join and assigned institute when some instructors have not joined course");
instructor = dataBundle.instructors.get("instructor4");
newIns = InstructorAttributes.builder(null, instructor.courseId, "anInstructorWithoutGoogleId", "anInstructorWithoutGoogleId@gmail.com").build();
instructorsLogic.createInstructor(newIns);
nonInstrAccount = dataBundle.accounts.get("student2InCourse1");
nonInstrAccount.email = "newInstructor@gmail.com";
nonInstrAccount.name = " newInstructor";
nonInstrAccount.googleId = "newInstructorGoogleId";
newIns = InstructorAttributes.builder(null, instructor.courseId, nonInstrAccount.name, nonInstrAccount.email).build();
instructorsLogic.createInstructor(newIns);
encryptedKey = instructorsLogic.getEncryptedKeyForInstructor(instructor.courseId, nonInstrAccount.email);
accountsLogic.joinCourseForInstructor(encryptedKey, nonInstrAccount.googleId);
joinedInstructor = instructorsLogic.getInstructorForEmail(instructor.courseId, nonInstrAccount.email);
assertEquals(nonInstrAccount.googleId, joinedInstructor.googleId);
instructorsLogic.verifyInstructorExists(nonInstrAccount.googleId);
AccountAttributes instructorAccount = accountsLogic.getAccount(nonInstrAccount.googleId);
assertEquals("TEAMMATES Test Institute 1", instructorAccount.institute);
accountsLogic.deleteAccountCascade(nonInstrAccount.googleId);
______TS("failure: instructor already joined");
nonInstrAccount = dataBundle.accounts.get("student1InCourse1");
instructor = dataBundle.instructors.get("instructorNotYetJoinCourse");
encryptedKey = instructorsLogic.getEncryptedKeyForInstructor(instructor.courseId, nonInstrAccount.email);
joinedInstructor = instructorsLogic.getInstructorForEmail(instructor.courseId, nonInstrAccount.email);
try {
accountsLogic.joinCourseForInstructor(encryptedKey, joinedInstructor.googleId);
signalFailureToDetectException();
} catch (JoinCourseException e) {
assertEquals(joinedInstructor.googleId + " has already joined this course", e.getMessage());
}
______TS("failure: key belongs to a different user");
try {
accountsLogic.joinCourseForInstructor(encryptedKey, "otherUserId");
signalFailureToDetectException();
} catch (JoinCourseException e) {
assertEquals("The join link used belongs to a different user whose " + "Google ID is stude..ourse1 (only part of the Google ID is " + "shown to protect privacy). If that Google ID is owned by you, " + "please logout and re-login using that Google account. " + "If it doesn’t belong to you, please " + "<a href=\"mailto:" + Config.SUPPORT_EMAIL + "?" + "body=Your name:%0AYour course:%0AYour university:\">" + "contact us</a> so that we can investigate.", e.getMessage());
}
______TS("failure: invalid key");
String invalidKey = StringHelper.encrypt("invalidKey");
try {
accountsLogic.joinCourseForInstructor(invalidKey, loggedInGoogleId);
signalFailureToDetectException();
} catch (JoinCourseException e) {
assertEquals("You have used an invalid join link: " + "/page/instructorCourseJoin?key=" + invalidKey, e.getMessage());
}
}
use of teammates.common.exception.JoinCourseException in project teammates by TEAMMATES.
the class InstructorCourseJoinAuthenticatedAction method execute.
@Override
protected ActionResult execute() throws EntityDoesNotExistException {
Assumption.assertNotNull(regkey);
String institute = getRequestParamValue(Const.ParamsNames.INSTRUCTOR_INSTITUTION);
gateKeeper.verifyLoggedInUserPrivileges();
/* Process authentication for the instructor to join course */
try {
if (institute == null) {
logic.joinCourseForInstructor(regkey, account.googleId);
} else {
logic.joinCourseForInstructor(regkey, account.googleId, institute);
}
} catch (JoinCourseException | InvalidParametersException e) {
// Does not sanitize for html to allow insertion of mailto link
setStatusForException(e, e.getMessage());
log.info(e.getMessage());
}
/* Set status to be shown to admin */
StringBuffer joinedCourseMsg = new StringBuffer(100);
joinedCourseMsg.append("Action Instructor Joins Course<br>Google ID: ").append(account.googleId);
try {
joinedCourseMsg.append("<br>Key : ").append(StringHelper.decrypt(regkey));
} catch (InvalidParametersException e) {
joinedCourseMsg.append("<br>Key could not be decrypted.");
// no need to do setStatusForException and logging, as this case is already caught above
}
if (statusToAdmin == null) {
statusToAdmin = joinedCourseMsg.toString();
} else {
statusToAdmin += "<br><br>" + joinedCourseMsg.toString();
}
/* Create redirection to instructor's homepage */
RedirectResult response = createRedirectResult(Const.ActionURIs.INSTRUCTOR_HOME_PAGE);
InstructorAttributes instructor = logic.getInstructorForRegistrationKey(regkey);
if (instructor != null) {
response.addResponseParam(Const.ParamsNames.CHECK_PERSISTENCE_COURSE, instructor.courseId);
sendCourseRegisteredEmail(instructor.name, instructor.email, true, instructor.courseId);
}
return response;
}
Aggregations