Skip to content
Open
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
3 changes: 1 addition & 2 deletions src/main/java/org/wise/portal/dao/user/UserDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ public interface UserDao<T extends User> extends SimpleDao<T> {
T retrieveByMicrosoftUserId(String microsoftUserId);
List<String> retrieveAllUsernames();
T retrieveByResetPasswordKey(String resetPasswordKey);
List<User> retrieveStudentsByNameAndBirthday(String firstName, String lastName,
Integer birthMonth, Integer birthDay);
List<User> retrieveStudentsByName(String firstName, String lastName);
List<User> retrieveTeachersByName(String firstName, String lastName);
List<User> retrieveAllTeachers();
User retrieveTeacherById(Long id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,7 @@ public List<User> retrieveStudentsByGender(String gender) {
}

@SuppressWarnings("unchecked")
public List<User> retrieveStudentsByNameAndBirthday(String firstName, String lastName,
Integer birthMonth, Integer birthDay) {
public List<User> retrieveStudentsByName(String firstName, String lastName) {
CriteriaBuilder cb = getCriteriaBuilder();
CriteriaQuery<UserImpl> cq = cb.createQuery(UserImpl.class);
Root<UserImpl> userRoot = cq.from(UserImpl.class);
Expand All @@ -309,10 +308,6 @@ public List<User> retrieveStudentsByNameAndBirthday(String firstName, String las
.add(cb.equal(userRoot.get("userDetails").get("id"), studentUserDetailsRoot.get("id")));
predicates.add(cb.equal(studentUserDetailsRoot.get("firstname"), firstName));
predicates.add(cb.equal(studentUserDetailsRoot.get("lastname"), lastName));
predicates.add(cb.equal(
cb.function("MONTH", Integer.class, studentUserDetailsRoot.get("birthday")), birthMonth));
predicates.add(cb.equal(
cb.function("DAY", Integer.class, studentUserDetailsRoot.get("birthday")), birthDay));
cq.select(userRoot).where(predicates.toArray(new Predicate[predicates.size()]));
TypedQuery<UserImpl> query = entityManager.createQuery(cq);
return (List<User>) (Object) query.getResultList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,12 +186,6 @@ public interface MutableUserDetails extends UserDetails, Persistable {
*/
String getCoreUsername();

/**
* In case username is not unique, append an item from the list of suffices.
* @return array of suffices to add to end of username to make it unique
*/
String[] getUsernameSuffixes();

/**
* Get the next username suffix
* @param currentUsernameSuffix
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,12 +376,6 @@ public String getCoreUsername() {
return null;
}

@Override
public String[] getUsernameSuffixes() {
// TODO Auto-generated method stub
return null;
}

@Override
public String getNextUsernameSuffix(String currentUsernameSuffix) {
// TODO Auto-generated method stub
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,6 @@ public class StudentUserDetails extends PersistentUserDetails implements Mutable
@Transient
public static final String COLUMN_NAME_GENDER = "gender";

@Transient
public static final String COLUMN_NAME_BIRTHDAY = "birthday";

@Transient
public static final String COLUMN_NAME_NUMBEROFLOGINS = "numberoflogins";

Expand Down Expand Up @@ -104,11 +101,6 @@ public class StudentUserDetails extends PersistentUserDetails implements Mutable
@Setter
private Gender gender;

@Column(name = StudentUserDetails.COLUMN_NAME_BIRTHDAY, nullable = false)
@Getter
@Setter
private Date birthday;

@Column(name = StudentUserDetails.COLUMN_NAME_NUMBEROFLOGINS, nullable = false)
@Getter
@Setter
Expand All @@ -131,59 +123,23 @@ public class StudentUserDetails extends PersistentUserDetails implements Mutable
public String getCoreUsername() {
String firstname = getFirstname().replaceAll("[\\s-]+", "");
String lastnameInitial = getLastname().substring(0, 1);

Calendar birthday = Calendar.getInstance();
birthday.setTime(this.birthday);

int birthmonth = birthday.get(Calendar.MONTH) + 1; // month is 0-based
int birthdate = birthday.get(Calendar.DATE);
String birthmonthString = String.valueOf(birthmonth);
if (birthmonth <= 9) {
birthmonthString = "0" + birthmonthString;
}
String birthdateString = String.valueOf(birthdate);
if (birthdate <= 9) {
birthdateString = "0" + birthdateString;
}

return firstname + lastnameInitial + birthmonthString + birthdateString;
}

public String[] getUsernameSuffixes() {
return new String[] { "", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
"o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
return firstname + lastnameInitial;
}

/**
* Get the next username suffix. For students the suffix is just an alphabet letter. If we reach
* "z" we will then move on to "aa", if we reach "az" we will then move on to "aaa", etc. e.g. "x"
* "y" "z" "aa" "ab"
* Get the next numeric username suffix for students.
*
* @param currentUsernameSuffix
* the current suffix
* @see MutableUserDetails#getNextUsernameSuffix(String)
* @return the next username suffix which will be the next letter in the alphabet
* @param currentUsernameSuffix the current suffix
* @return the next suffix, starting with "2" after the unsuffixed username
*/
public String getNextUsernameSuffix(String currentUsernameSuffix) {
String nextUsernameSuffix = "";
if (currentUsernameSuffix == null) {
nextUsernameSuffix = "";
} else if ("".equals(currentUsernameSuffix)) {
nextUsernameSuffix = "a";
return "";
} else if (currentUsernameSuffix.isEmpty()) {
return "2";
} else {
if (currentUsernameSuffix.length() > 0) {
char lastChar = currentUsernameSuffix.charAt(currentUsernameSuffix.length() - 1);
if (lastChar == 'z') {
String beginningCurrentUsernameSuffix = currentUsernameSuffix.substring(0,
currentUsernameSuffix.length() - 1);
nextUsernameSuffix = beginningCurrentUsernameSuffix + "aa";
} else {
nextUsernameSuffix = currentUsernameSuffix.substring(0,
currentUsernameSuffix.length() - 1) + (char) (lastChar + 1);
}
}
return String.valueOf(Integer.parseInt(currentUsernameSuffix) + 1);
}
return nextUsernameSuffix;
}

public Date getLastLoginTime() {
Expand All @@ -206,7 +162,6 @@ public HashMap<String, Object> getInfo() {
infoMap.put("Username", this.getUsername());
infoMap.put("Sign Up Date", this.getSignupdate());
infoMap.put("Gender", this.getGender().toString());
infoMap.put("Birthday", this.getBirthday());
infoMap.put("Number of Logins", this.getNumberOfLogins().toString());
infoMap.put("Last Login", this.getLastLoginTime());
infoMap.put("Language", this.getLanguage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,6 @@ public String getCoreUsername() {
return (firstname + lastname).replaceAll("[\\s-]+", "");
}

public String[] getUsernameSuffixes() {
return new String[] { "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",
"14", "15", "16" };
}

/**
* Get the next username suffix. For teachers the suffix is just an integer that we will increment
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@ public class PasswordReminderParameters extends HashMap<String, String> {

public static final String LAST_NAME = "lastName";

public static final String BIRTH_MONTH = "birthMonth";

public static final String BIRTH_DAY = "birthDay";

public void setUsername(String username) {
this.put(USERNAME, username);
}
Expand Down Expand Up @@ -126,20 +122,4 @@ public void setLastName(String lastName) {
public String getLastName() {
return this.get(LAST_NAME);
}

public void setBirthMonth(String birthMonth) {
this.put(BIRTH_MONTH, birthMonth);
}

public String getBirthMonth() {
return this.get(BIRTH_MONTH);
}

public void setBirthDay(String birthDay) {
this.put(BIRTH_DAY, birthDay);
}

public String getBirthDay() {
return this.get(BIRTH_DAY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
Expand Down Expand Up @@ -62,6 +65,9 @@
@RequestMapping("/admin/account/batchcreateuseraccounts.html")
public class BatchCreateUserAccountsController {

private static final String CSV_FORMAT_ERROR =
"This CSV file does not match the updated format. Please download and use the updated template.";

@Autowired
private UserService userService;

Expand All @@ -72,72 +78,99 @@ public class BatchCreateUserAccountsController {
protected ModelAndView onSubmit(
@ModelAttribute("csvFile") BatchCreateUserAccountsUpload csvUpload,
BindingResult result) throws Exception {
ArrayList<String> newUsernames = new ArrayList<String>();
MultipartFile csvFile = csvUpload.getFile();
InputStreamReader inputStreamReader = new InputStreamReader(csvFile.getInputStream());
List<String[]> studentRows = new ArrayList<String[]>();
Gender[] genderArray = {Gender.MALE,Gender.FEMALE,Gender.UNSPECIFIED};
AccountQuestion[] accountQuestionArray =
{ AccountQuestion.QUESTION_FOUR, AccountQuestion.QUESTION_TWO,
AccountQuestion.QUESTION_THREE };
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
if (!readStudentRows(csvUpload.getFile(), studentRows, genderArray, accountQuestionArray)) {
return csvFormatError();
}
ArrayList<String> newUsernames =
createStudentAccounts(studentRows, genderArray, accountQuestionArray);
ModelAndView modelAndView = new ModelAndView("admin/account/batchcreateuseraccounts");
modelAndView.addObject("msg", "Batch create user accounts complete!");
modelAndView.addObject("newUsernames", newUsernames);
return modelAndView;
}

try {
br = new BufferedReader(inputStreamReader);
private boolean readStudentRows(MultipartFile csvFile, List<String[]> studentRows,
Gender[] genderArray, AccountQuestion[] accountQuestionArray) throws IOException {
try (BufferedReader br = new BufferedReader(
new InputStreamReader(csvFile.getInputStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = br.readLine()) != null) {
String[] userInfo = line.split(cvsSplitBy);
if ("Firstname".equals(userInfo[0]) && "Lastname".equals(userInfo[1])) {
continue;
}
String firstname = userInfo[0];
String lastname = userInfo[1];
Gender gender = genderArray[Integer.valueOf(userInfo[2])];
String password = userInfo[5];
AccountQuestion accountQuestion = accountQuestionArray[Integer.valueOf(userInfo[6])];
String accountAnswer = userInfo[7];
StudentUserDetails studentUserDetails = new StudentUserDetails();
studentUserDetails.setFirstname(firstname);
studentUserDetails.setLastname(lastname);
studentUserDetails.setGender(gender);
studentUserDetails.setPassword(password);
studentUserDetails.setAccountQuestion(accountQuestion.toString());
studentUserDetails.setAccountAnswer(accountAnswer);
studentUserDetails.setSignupdate(Calendar.getInstance().getTime());
int birthmonth = Integer.parseInt(userInfo[3]);
int birthdate = Integer.parseInt(userInfo[4]);
Calendar birthday = Calendar.getInstance();
birthday.set(Calendar.MONTH, birthmonth - 1); // month is 0-based
birthday.set(Calendar.DATE, birthdate);
studentUserDetails.setBirthday(birthday.getTime());
User user = userService.createUser(studentUserDetails);
String accessCode = userInfo[8];
String period = userInfo[9];
Projectcode projectcode = new Projectcode(accessCode,period);
studentService.addStudentToRun(user, projectcode);
newUsernames.add(studentUserDetails.getUsername());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStreamReader != null) {
try {
inputStreamReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
if (!line.isBlank()) {
String[] userInfo = line.split(",", -1);
boolean headerRow = isHeaderRow(userInfo);
boolean invalidRow = headerRow
? line.toLowerCase(Locale.ROOT).contains("birthday")
: isInvalidRow(genderArray, accountQuestionArray, userInfo);
if (invalidRow) {
return false;
} else if (!headerRow) {
studentRows.add(userInfo);
}
}
}
}
return true;
}

private boolean isInvalidRow(Gender[] genderArray, AccountQuestion[] accountQuestionArray,
String[] userInfo) {
return userInfo.length != 8 || !hasValidAccountIndexes(userInfo, genderArray,
accountQuestionArray);
}

private boolean isHeaderRow(String[] userInfo) {
return userInfo.length >= 2 && "Firstname".equals(userInfo[0])
&& "Lastname".equals(userInfo[1]);
}

private ArrayList<String> createStudentAccounts(List<String[]> studentRows,
Gender[] genderArray, AccountQuestion[] accountQuestionArray) throws Exception {
ArrayList<String> newUsernames = new ArrayList<String>();
for (String[] userInfo : studentRows) {
String firstname = userInfo[0];
String lastname = userInfo[1];
Gender gender = genderArray[Integer.valueOf(userInfo[2])];
String password = userInfo[3];
AccountQuestion accountQuestion = accountQuestionArray[Integer.valueOf(userInfo[4])];
String accountAnswer = userInfo[5];
StudentUserDetails studentUserDetails = new StudentUserDetails();
studentUserDetails.setFirstname(firstname);
studentUserDetails.setLastname(lastname);
studentUserDetails.setGender(gender);
studentUserDetails.setPassword(password);
studentUserDetails.setAccountQuestion(accountQuestion.toString());
studentUserDetails.setAccountAnswer(accountAnswer);
studentUserDetails.setSignupdate(Calendar.getInstance().getTime());
User user = userService.createUser(studentUserDetails);
String accessCode = userInfo[6];
String period = userInfo[7];
Projectcode projectcode = new Projectcode(accessCode, period);
studentService.addStudentToRun(user, projectcode);
newUsernames.add(studentUserDetails.getUsername());
}
return newUsernames;
}

private boolean hasValidAccountIndexes(String[] userInfo, Gender[] genderArray,
AccountQuestion[] accountQuestionArray) {
try {
int genderIndex = Integer.parseInt(userInfo[2]);
int accountQuestionIndex = Integer.parseInt(userInfo[4]);
return genderIndex >= 0 && genderIndex < genderArray.length
&& accountQuestionIndex >= 0 && accountQuestionIndex < accountQuestionArray.length;
} catch (NumberFormatException e) {
return false;
}
}

private ModelAndView csvFormatError() {
ModelAndView modelAndView = new ModelAndView("admin/account/batchcreateuseraccounts");
modelAndView.addObject("msg", "Batch create user accounts complete!");
modelAndView.addObject("newUsernames", newUsernames);
modelAndView.addObject("error", CSV_FORMAT_ERROR);
return modelAndView;
}

Expand Down
Loading
Loading