Search in sources :

Example 1 with JoinCourseException

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));
    }
}
Also used : JoinCourseException(teammates.common.exception.JoinCourseException) StudentAttributes(teammates.common.datatransfer.attributes.StudentAttributes)

Example 2 with JoinCourseException

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);
}
Also used : AccountAttributes(teammates.common.datatransfer.attributes.AccountAttributes) InvalidParametersException(teammates.common.exception.InvalidParametersException) JoinCourseException(teammates.common.exception.JoinCourseException) StudentProfileAttributes(teammates.common.datatransfer.attributes.StudentProfileAttributes) StudentAttributes(teammates.common.datatransfer.attributes.StudentAttributes) Test(org.testng.annotations.Test)

Example 3 with JoinCourseException

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());
    }
}
Also used : AccountAttributes(teammates.common.datatransfer.attributes.AccountAttributes) AccountsDb(teammates.storage.api.AccountsDb) JoinCourseException(teammates.common.exception.JoinCourseException) InstructorAttributes(teammates.common.datatransfer.attributes.InstructorAttributes) Test(org.testng.annotations.Test)

Example 4 with JoinCourseException

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;
}
Also used : InvalidParametersException(teammates.common.exception.InvalidParametersException) JoinCourseException(teammates.common.exception.JoinCourseException) InstructorAttributes(teammates.common.datatransfer.attributes.InstructorAttributes)

Aggregations

JoinCourseException (teammates.common.exception.JoinCourseException)4 Test (org.testng.annotations.Test)2 AccountAttributes (teammates.common.datatransfer.attributes.AccountAttributes)2 InstructorAttributes (teammates.common.datatransfer.attributes.InstructorAttributes)2 StudentAttributes (teammates.common.datatransfer.attributes.StudentAttributes)2 InvalidParametersException (teammates.common.exception.InvalidParametersException)2 StudentProfileAttributes (teammates.common.datatransfer.attributes.StudentProfileAttributes)1 AccountsDb (teammates.storage.api.AccountsDb)1