/** * 이메일 추가 * * @return */ @Transactional public static Result addEmail() { Form<Email> emailForm = form(Email.class).bindFromRequest(); String newEmail = emailForm.data().get("email"); if (emailForm.hasErrors()) { flash(Constants.WARNING, emailForm.error("email").message()); return redirect(routes.UserApp.editUserInfoForm()); } User currentUser = currentUser(); if (currentUser == null || currentUser.isAnonymous()) { return forbidden(ErrorViews.NotFound.render()); } if (User.isEmailExist(newEmail) || Email.exists(newEmail, true) || currentUser.has(newEmail)) { flash(Constants.WARNING, Messages.get("user.email.duplicate")); return redirect(routes.UserApp.editUserInfoForm()); } Email email = new Email(); User user = currentUser(); email.user = user; email.email = newEmail; email.valid = false; user.addEmail(email); return redirect(routes.UserApp.editUserInfoForm()); }
/** * 대표 메일로 설정하기 * * @param id * @return */ @Transactional public static Result setAsMainEmail(Long id) { User currentUser = currentUser(); Email email = Email.find.byId(id); if (currentUser == null || currentUser.isAnonymous() || email == null) { return forbidden(ErrorViews.NotFound.render()); } if (!AccessControl.isAllowed(currentUser, email.user.asResource(), Operation.UPDATE)) { return forbidden(ErrorViews.Forbidden.render(Messages.get("error.forbidden"))); } String oldMainEmail = currentUser.email; currentUser.email = email.email; currentUser.removeEmail(email); currentUser.update(); Email newSubEmail = new Email(); newSubEmail.valid = true; newSubEmail.email = oldMainEmail; newSubEmail.user = currentUser; currentUser.addEmail(newSubEmail); return redirect(routes.UserApp.editUserInfoForm()); }
/** * 토큰 정보를 이용해 생성한 사용자 객체를 {@link Http.Context#args} 에 저장한다. 생성된 사용자가 {@link User#anonymous} 가 아니고 * 존재하는 세션 정보가 없다면 세션 정보를 생성한다. * * @see UserApp#getUserFromToken() */ public static void initTokenUser() { User user = getUserFromToken(); Http.Context.current().args.put(TOKEN_USER, user); if (!user.isAnonymous() && getUserFromSession().isAnonymous()) { addUserInfoToSession(user); } }
/** * 세션에 저장된 정보를 이용해서 사용자 객체를 생성한다. 세션에 저장된 정보가 없다면 토큰 정보를 이용해서 사용자 객체를 생성한다. 세션과 토큰 쿠키에 저장된 정보가 없다면 * anonymous 객체가 리턴된다. * * @return */ public static User currentUser() { User user = getUserFromSession(); if (!user.isAnonymous()) { return user; } return getUserFromContext(); }
/* * 사용자 인증 * * 사용자 객체와 hash 값을 이용 */ private static User authenticate(User user, String password) { if (!user.isAnonymous()) { if (user.password.equals(password)) { return user; } } return null; }
/* * 사용자 인증 * * 사용자 객체와 hash 값을 이용 */ private static User authenticate(String loginId, String password, boolean hashed) { User user = User.findByLoginId(loginId); if (user.isAnonymous()) { return user; } String hashedPassword = hashed ? password : hashedPassword(password, user.passwordSalt); if (StringUtils.equals(user.password, hashedPassword)) { return user; } return User.anonymous; }
/** * 토큰 정보를 이용해서 사용자 객체를 가져온다. 토큰 정보가 없거나 잘못된 정보라면 anonymous 객체를 반환한다. 잘못된 정보의 경우 토큰 정보를 삭제한다. * * @return */ private static User getUserFromToken() { Cookie cookie = request().cookies().get(TOKEN); if (cookie == null) { return User.anonymous; } String[] subject = StringUtils.split(cookie.value(), TOKEN_SEPARATOR); if (ArrayUtils.getLength(subject) != TOKEN_LENGTH) { return invalidToken(); } User user = authenticateWithHashedPassword(subject[0], subject[1]); if (user.isAnonymous()) { return invalidToken(); } return user; }
/** * 이메일 삭제 * * @param id * @return */ @Transactional public static Result deleteEmail(Long id) { User currentUser = currentUser(); Email email = Email.find.byId(id); if (currentUser == null || currentUser.isAnonymous() || email == null) { return forbidden(ErrorViews.NotFound.render()); } if (!AccessControl.isAllowed(currentUser, email.user.asResource(), Operation.DELETE)) { return forbidden(ErrorViews.Forbidden.render(Messages.get("error.forbidden"))); } email.delete(); return redirect(routes.UserApp.editUserInfoForm()); }
/** * 로그인 처리 시스템 설정에서 가입승인 기능이 활성화 되어 있고 사용자 상태가 잠금상태(미승인?)라면 계정이 잠겼다는 메시지를 노출하고 로그인 폼으로 돌아감 시스템 설정에서 * 가입승인 기능이 활성화 되어 있지 않다면, 사용자 상태가 잠금상태라도 로그인이 가능하다 (스펙확인 필요) 요청의 정보로 사용자 인증에 성공하면 로그인쿠키를 생성하고 * 로그인유지하기가 선택되었다면, 로그인유지를 위한 쿠키를 별도로 생성한다 인증에 실패하면 관련된 메시지를 노출하고 로그인 폼으로 돌아간다 * * @return */ public static Result login() { Form<User> userForm = form(User.class).bindFromRequest(); if (userForm.hasErrors()) { return badRequest(login.render("title.login", userForm, null)); } User sourceUser = form(User.class).bindFromRequest().get(); Map<String, String[]> params = request().body().asFormUrlEncoded(); String redirectUrl = HttpUtil.getFirstValueFromQuery(params, "redirectUrl"); String loginFormUrl = routes.UserApp.loginForm().url(); loginFormUrl += "?redirectUrl=" + redirectUrl; if (isUseSignUpConfirm()) { if (User.findByLoginId(sourceUser.loginId).state == UserState.LOCKED) { flash(Constants.WARNING, "user.locked"); return redirect(loginFormUrl); } } if (User.findByLoginId(sourceUser.loginId).state == UserState.DELETED) { flash(Constants.WARNING, "user.deleted"); return redirect(loginFormUrl); } User authenticate = authenticateWithPlainPassword(sourceUser.loginId, sourceUser.password); if (!authenticate.isAnonymous()) { addUserInfoToSession(authenticate); if (sourceUser.rememberMe) { setupRememberMe(authenticate); } authenticate.lang = play.mvc.Http.Context.current().lang().code(); authenticate.update(); if (StringUtils.isEmpty(redirectUrl)) { return redirect(routes.Application.index()); } else { return redirect(redirectUrl); } } flash(Constants.WARNING, "user.login.failed"); return redirect(routes.UserApp.loginForm()); }
/** * 보조 이메일 확인 메일 보내기 * * @param id * @return */ @Transactional public static Result sendValidationEmail(Long id) { User currentUser = currentUser(); Email email = Email.find.byId(id); if (currentUser == null || currentUser.isAnonymous() || email == null) { return forbidden(ErrorViews.NotFound.render()); } if (!AccessControl.isAllowed(currentUser, email.user.asResource(), Operation.UPDATE)) { return forbidden(ErrorViews.Forbidden.render(Messages.get("error.forbidden"))); } email.sendValidationEmail(); flash(Constants.WARNING, "확인 메일을 전송했습니다."); return redirect(routes.UserApp.editUserInfoForm()); }
/** * 현재 사용자가 선호하는 언어를 갱신한다. * * <p>쿠키나 Accept-Language HTTP 헤더에 선호하는 언어가 설정되어 있는 경우, 그것을 현재 로그인한 사용자가 선호하는 언어로 설정한다. */ public static void updatePreferredLanguage() { Http.Request request = Http.Context.current().request(); User user = UserApp.currentUser(); if (user.isAnonymous()) { return; } if (request.acceptLanguages().isEmpty() && request.cookie(Play.langCookieName()) == null) { return; } String code = StringUtils.left(Http.Context.current().lang().code(), 255); if (!code.equals(user.lang)) { user.lang = code; user.update(); } }