Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,19 @@
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.acls.model.Permission;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
Expand All @@ -32,13 +27,8 @@
import org.wise.portal.domain.group.Group;
import org.wise.portal.domain.run.Run;
import org.wise.portal.domain.user.User;
import org.wise.portal.domain.usertag.UserTag;
import org.wise.portal.presentation.web.controllers.ControllerUtil;
import org.wise.portal.presentation.web.controllers.user.UserAPIController;
import org.wise.portal.presentation.web.exception.InvalidNameException;
import org.wise.portal.presentation.web.response.ResponseEntityGenerator;
import org.wise.portal.presentation.web.response.SimpleResponse;
import org.wise.portal.service.authentication.DuplicateUsernameException;
import org.wise.portal.service.authentication.UserDetailsService;
import org.wise.portal.service.usertags.UserTagsService;

Expand Down Expand Up @@ -129,105 +119,6 @@ List<String> getAllTeacherUsernames() {
return userDetailsService.retrieveAllTeacherUsernames();
}

@PostMapping("/register")
@Secured({ "ROLE_ANONYMOUS" })
ResponseEntity<Map<String, Object>> createTeacherAccount(
@RequestBody Map<String, String> teacherFields, HttpServletRequest request)
throws DuplicateUsernameException, InvalidNameException {
if (ControllerUtil.isReCaptchaEnabled()) {
String token = teacherFields.get("token");
if (!ControllerUtil.isReCaptchaResponseValid(token)) {
return ResponseEntityGenerator.createError("recaptchaResponseInvalid");
}
}
TeacherUserDetails tud = new TeacherUserDetails();
String firstName = teacherFields.get("firstName");
String lastName = teacherFields.get("lastName");
if (!isFirstNameAndLastNameValid(firstName, lastName)) {
String messageCode = this.getInvalidNameMessageCode(firstName, lastName);
throw new InvalidNameException(messageCode);
}
tud.setFirstname(firstName);
tud.setLastname(lastName);
String email = teacherFields.get("email");
tud.setEmailAddress(email);
tud.setCity(teacherFields.get("city"));
tud.setState(teacherFields.get("state"));
tud.setCountry(teacherFields.get("country"));
String googleUserId = teacherFields.get("googleUserId");
String microsoftUserId = teacherFields.get("microsoftUserId");
if (isSet(googleUserId)) {
tud.setGoogleUserId(googleUserId);
tud.setPassword(RandomStringUtils.random(10, true, true));
} else if (isSet(microsoftUserId)) {
tud.setMicrosoftUserId(microsoftUserId);
tud.setPassword(RandomStringUtils.random(10, true, true));
} else {
String password = teacherFields.get("password");
if (!passwordService.isValid(password)) {
return ResponseEntityGenerator.createError(passwordService.getErrors(password));
} else {
tud.setPassword(password);
}
}
String displayName = firstName + " " + lastName;
tud.setDisplayname(displayName);
tud.setEmailValid(true);
tud.setSchoollevel(Schoollevel.valueOf(teacherFields.get("schoolLevel")));
tud.setSchoolname(teacherFields.get("schoolName"));
tud.setHowDidYouHearAboutUs(teacherFields.get("howDidYouHearAboutUs"));
Locale locale = request.getLocale();
tud.setLanguage(locale.getLanguage());
User createdUser = this.userService.createUser(tud);
String username = createdUser.getUserDetails().getUsername();
String sendEmailEnabledStr = appProperties.getProperty("send_email_enabled", "false");
Boolean iSendEmailEnabled = Boolean.valueOf(sendEmailEnabledStr);
boolean socialAccount = this.isSet(googleUserId) || this.isSet(microsoftUserId);
if (iSendEmailEnabled) {
sendCreateTeacherAccountEmail(email, displayName, username, socialAccount, locale, request);
}
return createRegisterSuccessResponse(username);
}

private void sendCreateTeacherAccountEmail(String email, String displayName, String username,
boolean socialAccount, Locale locale, HttpServletRequest request) {
String fromEmail = appProperties.getProperty("portalemailaddress");
String[] recipients = { email };
String defaultSubject = messageSource.getMessage(
"presentation.web.controllers.teacher.registerTeacherController.welcomeTeacherEmailSubject",
null, Locale.US);
String subject = messageSource.getMessage(
"presentation.web.controllers.teacher.registerTeacherController.welcomeTeacherEmailSubject",
null, defaultSubject, locale);
String defaultBody = messageSource.getMessage(
"presentation.web.controllers.teacher.registerTeacherController.welcomeTeacherEmailBody",
new Object[] { username }, Locale.US);
String gettingStartedUrl = getGettingStartedUrl(request);
String message;
if (socialAccount) {
message = messageSource.getMessage(
"presentation.web.controllers.teacher.registerTeacherController.welcomeTeacherEmailBodyNoUsername",
new Object[] { displayName, gettingStartedUrl }, defaultBody, locale);
} else {
message = messageSource.getMessage(
"presentation.web.controllers.teacher.registerTeacherController.welcomeTeacherEmailBody",
new Object[] { displayName, username, gettingStartedUrl }, defaultBody, locale);
}
try {
mailService.postMail(recipients, subject, message, fromEmail);
} catch (MessagingException e) {
e.printStackTrace();
}
}

private String getGettingStartedUrl(HttpServletRequest request) {
return ControllerUtil.getPortalUrlString(request) + "/help/getting-started";
}

private boolean isSet(String value) {
return value != null && !value.isEmpty();
}

private List<HashMap<String, Object>> getRunSharedOwnersList(Run run) {
List<HashMap<String, Object>> sharedOwners = new ArrayList<HashMap<String, Object>>();
for (User sharedOwner : run.getSharedowners()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package org.wise.portal.presentation.web.controllers.teacher;

import java.util.Locale;
import java.util.Map;

import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.wise.portal.domain.authentication.Schoollevel;
import org.wise.portal.domain.authentication.impl.TeacherUserDetails;
import org.wise.portal.domain.user.User;
import org.wise.portal.presentation.web.controllers.ControllerUtil;
import org.wise.portal.presentation.web.exception.InvalidNameException;
import org.wise.portal.presentation.web.exception.InvalidPasswordException;
import org.wise.portal.presentation.web.exception.RecaptchaVerificationException;
import org.wise.portal.presentation.web.response.ResponseEntityGenerator;
import org.wise.portal.service.authentication.DuplicateUsernameException;

@RestController
@RequestMapping("/api/teacher/register")
public class TeacherRegistrationAPIController extends TeacherAPIController {

private final String emailCodePrefix =
"presentation.web.controllers.teacher.registerTeacherController.welcomeTeacherEmail";
private final String welcomeBodyCode = this.emailCodePrefix + "Body";
private final String welcomeSocialAccountBodyCode = this.emailCodePrefix + "BodyNoUsername";
private final String welcomeSubjectCode = this.emailCodePrefix + "Subject";

@PostMapping()
@Secured({ "ROLE_ANONYMOUS" })
ResponseEntity<Map<String, Object>> createTeacherAccount(
@RequestBody Map<String, String> teacherFields, HttpServletRequest request)
throws DuplicateUsernameException, InvalidNameException {
try {
validateTeacherFields(teacherFields);
} catch (RecaptchaVerificationException e) {
return ResponseEntityGenerator.createError("recaptchaResponseInvalid");
} catch (InvalidPasswordException e) {
return ResponseEntityGenerator.createError(
passwordService.getErrors(teacherFields.get("password")));
}
Locale locale = request.getLocale();
TeacherUserDetails tud = createTeacherUserDetails(teacherFields, locale);
User createdUser = this.userService.createUser(tud);
String username = createdUser.getUserDetails().getUsername();
if (isSendEmailEnabled()) {
sendWelcomeTeacherEmail(tud.getEmailAddress(), tud.getDisplayname(), username,
isSocialAccount(tud), locale, request);
}
return createRegisterSuccessResponse(username);
}

private boolean isSendEmailEnabled() {
String sendEmailEnabledStr = appProperties.getProperty("send_email_enabled", "false");
return Boolean.valueOf(sendEmailEnabledStr);
}

private boolean isSocialAccount(TeacherUserDetails tud) {
return isSet(tud.getGoogleUserId()) || isSet(tud.getMicrosoftUserId());
}

private void sendWelcomeTeacherEmail(String email, String displayName, String username,
boolean socialAccount, Locale locale,
HttpServletRequest request) {
String subject = getEmailMessage(this.welcomeSubjectCode, this.welcomeSubjectCode, null, locale);
String body = getWelcomeTeacherBody(displayName, username, socialAccount, locale, request);
this.sendEmail(email, subject, body);
}

private String getEmailMessage(String defaultCode, String code, Object[] args, Locale locale) {
String defaultMessage = messageSource.getMessage(defaultCode, args, Locale.US);
return messageSource.getMessage(code, args, defaultMessage, locale);
}

private String getWelcomeTeacherBody(String displayName, String username, boolean socialAccount,
Locale locale, HttpServletRequest request) {
String gettingStartedUrl = getGettingStartedUrl(request);
String code = socialAccount ? this.welcomeSocialAccountBodyCode : this.welcomeBodyCode;
Object[] args = socialAccount
? new Object[] { displayName, gettingStartedUrl }
: new Object[] { displayName, username, gettingStartedUrl };
return getEmailMessage(this.welcomeBodyCode, code, args, locale);
}

private String getGettingStartedUrl(HttpServletRequest request) {
return ControllerUtil.getPortalUrlString(request) + "/help/getting-started";
}

private void sendEmail(String email, String subject, String body) {
String fromEmail = appProperties.getProperty("portalemailaddress");
String[] recipients = { email };
try {
mailService.postMail(recipients, subject, body, fromEmail);
} catch (MessagingException e) {
e.printStackTrace();
}
}

private void validateTeacherFields(Map<String, String> teacherFields)
throws RecaptchaVerificationException, InvalidNameException, InvalidPasswordException {
validateReCaptcha(teacherFields.get("token"));
validateFirstAndLastName(teacherFields.get("firstName"), teacherFields.get("lastName"));
validatePassword(teacherFields.get("password"));
}

private void validateReCaptcha(String token) throws RecaptchaVerificationException {
if (ControllerUtil.isReCaptchaEnabled()) {
if (!ControllerUtil.isReCaptchaResponseValid(token)) {
throw new RecaptchaVerificationException("Invalid ReCaptcha Response");
}
}
}

private void validateFirstAndLastName(String firstName, String lastName)
throws InvalidNameException {
if (!isFirstNameAndLastNameValid(firstName, lastName)) {
String messageCode = this.getInvalidNameMessageCode(firstName, lastName);
throw new InvalidNameException(messageCode);
}
}

private void validatePassword(String password) throws InvalidPasswordException {
if (password != null && !passwordService.isValid(password)) {
throw new InvalidPasswordException();
}
}

private TeacherUserDetails createTeacherUserDetails(Map<String, String> teacherFields,
Locale locale) {
TeacherUserDetails tud = new TeacherUserDetails();
tud.setFirstname(teacherFields.get("firstName"));
tud.setLastname(teacherFields.get("lastName"));
tud.setEmailAddress(teacherFields.get("email"));
tud.setCity(teacherFields.get("city"));
tud.setState(teacherFields.get("state"));
tud.setCountry(teacherFields.get("country"));
tud.setDisplayname(tud.getFirstname() + " " + tud.getLastname());
tud.setSchoollevel(Schoollevel.valueOf(teacherFields.get("schoolLevel")));
tud.setSchoolname(teacherFields.get("schoolName"));
tud.setHowDidYouHearAboutUs(teacherFields.get("howDidYouHearAboutUs"));
tud.setLanguage(locale.getLanguage());
setPassword(teacherFields, tud);
tud.setEmailValid(true);
return tud;
}

private void setPassword(Map<String, String> teacherFields, TeacherUserDetails tud) {
String googleUserId = teacherFields.get("googleUserId");
String microsoftUserId = teacherFields.get("microsoftUserId");
if (isSet(googleUserId)) {
tud.setGoogleUserId(googleUserId);
setRandomPassword(tud);
} else if (isSet(microsoftUserId)) {
tud.setMicrosoftUserId(microsoftUserId);
setRandomPassword(tud);
} else {
tud.setPassword(teacherFields.get("password"));
}
}

private boolean isSet(String value) {
return value != null && !value.isEmpty();
}

private void setRandomPassword(TeacherUserDetails tud) {
tud.setPassword(RandomStringUtils.random(10, true, true));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.easymock.EasyMockExtension;
Expand All @@ -25,8 +24,6 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.util.ReflectionTestUtils;
import org.wise.portal.dao.ObjectNotFoundException;
import org.wise.portal.domain.PeriodNotFoundException;
Expand All @@ -35,9 +32,7 @@
import org.wise.portal.domain.run.Run;
import org.wise.portal.domain.user.User;
import org.wise.portal.presentation.web.controllers.APIControllerTest;
import org.wise.portal.presentation.web.exception.InvalidNameException;
import org.wise.portal.presentation.web.response.SimpleResponse;
import org.wise.portal.service.authentication.DuplicateUsernameException;
import org.wise.portal.service.authentication.UserDetailsService;
import org.wise.portal.service.password.impl.PasswordServiceImpl;
import org.wise.portal.service.usertags.UserTagsService;
Expand Down Expand Up @@ -375,33 +370,6 @@ public void createRun_ThreePeriods_CreateRun() throws Exception {
verify(runService);
}

@Test
public void createTeacherAccount_InvalidPassword_ReturnError()
throws DuplicateUsernameException, InvalidNameException {
HashMap<String, String> teacherFields = createDefaultTeacherFields();
teacherFields.put("password", PasswordServiceImpl.INVALID_PASSWORD_TOO_SHORT);
ResponseEntity<Map<String, Object>> response = teacherAPIController
.createTeacherAccount(teacherFields, request);
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
assertEquals("invalidPassword", response.getBody().get("messageCode"));
}

@Test
public void createTeacherAccount_WithGoogleUserId_CreateUser()
throws DuplicateUsernameException, InvalidNameException {
HashMap<String, String> teacherFields = createDefaultTeacherFields();
teacherFields.put("googleUserId", "123456789");
expect(request.getLocale()).andReturn(Locale.US);
replay(request);
expect(userService.createUser(isA(TeacherUserDetails.class))).andReturn(teacher1);
replay(userService);
ResponseEntity<Map<String, Object>> response = teacherAPIController
.createTeacherAccount(teacherFields, request);
assertEquals(TEACHER_USERNAME, response.getBody().get("username"));
verify(request);
verify(userService);
}

@Test
public void editRunEndTime_WithNullEndTime_ChangeEndTime() throws ObjectNotFoundException {
expect(userService.retrieveUserByUsername(teacherAuth.getName())).andReturn(teacher1);
Expand Down Expand Up @@ -456,17 +424,6 @@ public void editRunIsLockedAfterEndDate_WithFalse_ChangeValue() throws ObjectNot
verify(runService);
}

private HashMap<String, String> createDefaultTeacherFields() {
HashMap<String, String> fields = new HashMap<String, String>();
fields.put("firstName", TEACHER_FIRSTNAME);
fields.put("lastName", TEACHER_LASTNAME);
fields.put("schoolLevel", "COLLEGE");
fields.put("birthMonth", "1");
fields.put("birthDay", "1");
fields.put("gender", "MALE");
return fields;
}

private void expectGetRunMapToBeCalled() {
expect(projectService.getProjectPath(isA(Project.class))).andReturn("/1/project.json");
expect(projectService.getProjectSharedOwnersList(isA(Project.class)))
Expand Down
Loading
Loading