/** * Resets forgotten password. * * <p>Renders the response with a json object, for example, * * <pre> * { * "isLoggedIn": boolean, * "msg": "" // optional, exists if isLoggedIn equals to false * } * </pre> * * @param context the specified context */ @RequestProcessing(value = "/reset", method = HTTPRequestMethod.POST) public void reset(final HTTPRequestContext context) { final HttpServletRequest request = context.getRequest(); final JSONRenderer renderer = new JSONRenderer(); context.setRenderer(renderer); final JSONObject jsonObject = new JSONObject(); renderer.setJSONObject(jsonObject); try { final JSONObject requestJSONObject; requestJSONObject = Requests.parseRequestJSONObject(request, context.getResponse()); final String userEmail = requestJSONObject.getString(User.USER_EMAIL); final String newPwd = requestJSONObject.getString("newPwd"); final JSONObject user = userQueryService.getUserByEmail(userEmail); user.put(User.USER_PASSWORD, newPwd); userMgmtService.updateUser(user); LOGGER.log(Level.DEBUG, "[{0}]'s password updated successfully.", new Object[] {userEmail}); jsonObject.put("succeed", true); jsonObject.put("to", Latkes.getServePath() + "/login?from=reset"); jsonObject.put(Keys.MSG, langPropsService.get("resetPwdSuccessMsg")); } catch (final Exception e) { LOGGER.log(Level.ERROR, e.getMessage(), e); } }
@Override public void requestInitialized(final ServletRequestEvent servletRequestEvent) { final HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequestEvent.getServletRequest(); if (Requests.searchEngineBotRequest(httpServletRequest)) { LOGGER.log( Level.DEBUG, "Request made from a search engine[User-Agent={0}]", httpServletRequest.getHeader("User-Agent")); httpServletRequest.setAttribute(Keys.HttpRequest.IS_SEARCH_ENGINE_BOT, true); } else { httpServletRequest.setAttribute(Keys.HttpRequest.IS_SEARCH_ENGINE_BOT, false); if (StaticResources.isStatic(httpServletRequest)) { return; } // Gets the session of this request final HttpSession session = httpServletRequest.getSession(); LOGGER.log( Level.TRACE, "Gets a session[id={0}, remoteAddr={1}, User-Agent={2}, isNew={3}]", new Object[] { session.getId(), httpServletRequest.getRemoteAddr(), httpServletRequest.getHeader("User-Agent"), session.isNew() }); // Online visitor count OptionQueryService.onlineVisitorCount(httpServletRequest); } }
/** * Logins. * * <p>Renders the response with a json object, for example, * * <pre> * { * "isLoggedIn": boolean, * "msg": "" // optional, exists if isLoggedIn equals to false * } * </pre> * * @param context the specified context */ @RequestProcessing(value = "/login", method = HTTPRequestMethod.POST) public void login(final HTTPRequestContext context) { final HttpServletRequest request = context.getRequest(); final JSONRenderer renderer = new JSONRenderer(); context.setRenderer(renderer); final JSONObject jsonObject = new JSONObject(); renderer.setJSONObject(jsonObject); try { jsonObject.put(Common.IS_LOGGED_IN, false); final String loginFailLabel = langPropsService.get("loginFailLabel"); jsonObject.put(Keys.MSG, loginFailLabel); final JSONObject requestJSONObject = Requests.parseRequestJSONObject(request, context.getResponse()); final String userEmail = requestJSONObject.getString(User.USER_EMAIL); final String userPwd = requestJSONObject.getString(User.USER_PASSWORD); if (Strings.isEmptyOrNull(userEmail) || Strings.isEmptyOrNull(userPwd)) { return; } LOGGER.log(Level.INFO, "Login[email={0}]", userEmail); final JSONObject user = userQueryService.getUserByEmail(userEmail); if (null == user) { LOGGER.log(Level.WARN, "Not found user[email={0}]", userEmail); return; } if (MD5.hash(userPwd).equals(user.getString(User.USER_PASSWORD))) { Sessions.login(request, context.getResponse(), user); LOGGER.log(Level.INFO, "Logged in[email={0}]", userEmail); jsonObject.put(Common.IS_LOGGED_IN, true); if (Role.VISITOR_ROLE.equals(user.optString(User.USER_ROLE))) { jsonObject.put("to", Latkes.getServePath()); } else { jsonObject.put("to", Latkes.getServePath() + Common.ADMIN_INDEX_URI); } jsonObject.remove(Keys.MSG); return; } LOGGER.log(Level.WARN, "Wrong password[{0}]", userPwd); } catch (final Exception e) { LOGGER.log(Level.ERROR, e.getMessage(), e); } }
/** * Mobile logins user. * * @param context the specified context * @param request the specified request * @param response the specified response * @throws ServletException servlet exception * @throws IOException io exception * @throws JSONException JSONException */ @RequestProcessing(value = "/oauth/token", method = HTTPRequestMethod.POST) public void mobileLogin( final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException, JSONException { final String error = "invalid grant"; final String errorDescription = "The provided authorization grant is invalid, expired, revoked, does not match"; final JSONRenderer renderer = new JSONRenderer(); context.setRenderer(renderer); final JSONObject ret = new JSONObject(); renderer.setJSONObject(ret); final String username = request.getParameter("username"); final String password = request.getParameter("password"); try { JSONObject user = userQueryService.getUserByName(username); if (null == user) { user = userQueryService.getUserByEmail(username); } if (null == user || null == password) { ret.put("error", error); ret.put("error_description", errorDescription); return; } if (UserExt.USER_STATUS_C_INVALID == user.optInt(UserExt.USER_STATUS) || UserExt.USER_STATUS_C_INVALID_LOGIN == user.optInt(UserExt.USER_STATUS)) { userMgmtService.updateOnlineStatus(user.optString(Keys.OBJECT_ID), "", false); ret.put("error", error); ret.put("error_description", errorDescription); return; } final String userPassword = user.optString(User.USER_PASSWORD); if (userPassword.equals(MD5.hash(password))) { final String ip = Requests.getRemoteAddr(request); userMgmtService.updateOnlineStatus(user.optString(Keys.OBJECT_ID), ip, true); ret.put( "access_token", "{\"userPassword\":\"" + user.optString(User.USER_PASSWORD) + "\",\"userEmail\":\"" + user.optString(User.USER_EMAIL) + "\"}"); ret.put("token_type", "bearer"); ret.put("scope", "user"); ret.put("created_at", new Date().getTime()); } } catch (final ServiceException e) { ret.put("error", error); ret.put("error_description", errorDescription); } }
/** * Gets the request page number from the specified request URI and tag title. * * @param requestURI the specified request URI * @param tagTitle the specified tag title * @return page number, returns {@code -1} if the specified request URI can not convert to an * number */ private static int getCurrentPageNum(final String requestURI, final String tagTitle) { if (Strings.isEmptyOrNull(tagTitle)) { return -1; } final String pageNumString = requestURI.substring((Latkes.getContextPath() + "/tags/" + tagTitle + "/").length()); return Requests.getCurrentPageNum(pageNumString); }
/** * Resets forgotten password. * * <p>Renders the response with a json object, for example, * * <pre> * { * "isLoggedIn": boolean, * "msg": "" // optional, exists if isLoggedIn equals to false * } * </pre> * * @param context the specified context */ @RequestProcessing(value = "/forgot", method = HTTPRequestMethod.POST) public void forgot(final HTTPRequestContext context) { final HttpServletRequest request = context.getRequest(); final JSONRenderer renderer = new JSONRenderer(); context.setRenderer(renderer); final JSONObject jsonObject = new JSONObject(); renderer.setJSONObject(jsonObject); try { jsonObject.put("succeed", false); jsonObject.put(Keys.MSG, langPropsService.get("resetPwdSuccessMsg")); final JSONObject requestJSONObject = Requests.parseRequestJSONObject(request, context.getResponse()); final String userEmail = requestJSONObject.getString(User.USER_EMAIL); if (Strings.isEmptyOrNull(userEmail)) { LOGGER.log(Level.WARN, "Why user's email is empty"); return; } LOGGER.log(Level.INFO, "Login[email={0}]", userEmail); final JSONObject user = userQueryService.getUserByEmail(userEmail); if (null == user) { LOGGER.log(Level.WARN, "Not found user[email={0}]", userEmail); jsonObject.put(Keys.MSG, langPropsService.get("userEmailNotFoundMsg")); return; } sendResetUrl(userEmail, jsonObject); } catch (final Exception e) { LOGGER.log(Level.ERROR, e.getMessage(), e); } }
/** * Updates an article remotely. * * <p>This interface will be called by Rhythm, so here is no article data validation, just only * validate the B3 key. * * <p>The request json object, for example, * * <pre> * { * "article": { * "articleAuthorEmail": "*****@*****.**", * "articleContent": "<p>test<\/p>", * "articleCreateDate": 1350635469922, * "articlePermalink": "/articles/2012/10/19/1350635469866.html", * "articleTags": "test", * "articleTitle": "test", * "clientArticleId": "1350635469866", * "oId": "1350635469866" * }, * "clientAdminEmail": "*****@*****.**", * "clientHost": "http://localhost:11099", * "clientName": "B3log Solo", * "clientTitle": "简约设计の艺术", * "clientRuntimeEnv": "LOCAL", * "clientVersion": "0.5.0", * "symphonyKey": "....", * "userB3Key": "Your key" * } * </pre> * * @param context the specified context * @param request the specified request * @param response the specified response * @throws Exception exception */ @RequestProcessing(value = "/rhythm/article", method = HTTPRequestMethod.PUT) @Before(adviceClass = StopwatchStartAdvice.class) @After(adviceClass = StopwatchEndAdvice.class) public void updateArticleFromRhythm( final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) throws Exception { final JSONRenderer renderer = new JSONRenderer(); context.setRenderer(renderer); final JSONObject ret = Results.falseResult(); renderer.setJSONObject(ret); final JSONObject requestJSONObject = Requests.parseRequestJSONObject(request, response); final String userB3Key = requestJSONObject.getString(UserExt.USER_B3_KEY); final String symphonyKey = requestJSONObject.getString(Common.SYMPHONY_KEY); final String clientAdminEmail = requestJSONObject.getString(Client.CLIENT_ADMIN_EMAIL); final String clientName = requestJSONObject.getString(Client.CLIENT_NAME); final String clientTitle = requestJSONObject.getString(Client.CLIENT_T_TITLE); final String clientVersion = requestJSONObject.getString(Client.CLIENT_VERSION); final String clientHost = requestJSONObject.getString(Client.CLIENT_HOST); final String clientRuntimeEnv = requestJSONObject.getString(Client.CLIENT_RUNTIME_ENV); final String maybeIP = StringUtils.substringBetween(clientHost, "://", ":"); if (Networks.isIPv4(maybeIP)) { LOGGER.log( Level.WARN, "Sync update article error, caused by the client host [{0}] is invalid", clientHost); return; } final JSONObject user = userQueryService.getUserByEmail(clientAdminEmail); if (null == user) { LOGGER.log( Level.WARN, "The user[email={0}, host={1}] not found in community", clientAdminEmail, clientHost); return; } final String userName = user.optString(User.USER_NAME); if (!Symphonys.get("keyOfSymphony").equals(symphonyKey) || !user.optString(UserExt.USER_B3_KEY).equals(userB3Key)) { LOGGER.log( Level.WARN, "B3 key not match, ignored update article [name={0}, host={1}]", userName, clientHost); return; } if (UserExt.USER_STATUS_C_VALID != user.optInt(UserExt.USER_STATUS)) { LOGGER.log( Level.WARN, "The user[name={0}, host={1}] has been forbidden", userName, clientHost); return; } final JSONObject originalArticle = requestJSONObject.getJSONObject(Article.ARTICLE); final String articleTitle = originalArticle.optString(Article.ARTICLE_TITLE); String articleTags = articleMgmtService.formatArticleTags(originalArticle.optString(Article.ARTICLE_TAGS)); String articleContent = originalArticle.optString(Article.ARTICLE_CONTENT); final String permalink = originalArticle.optString(Article.ARTICLE_PERMALINK); articleContent += "<p class='fn-clear'><span class='fn-right'><span class='ft-small'>该文章同步自</span> " + "<i style='margin-right:5px;'><a target='_blank' href='" + clientHost + permalink + "'>" + clientTitle + "</a></i></span></p>"; final String authorId = user.optString(Keys.OBJECT_ID); final String clientArticleId = originalArticle.optString(Keys.OBJECT_ID); final JSONObject oldArticle = articleQueryService.getArticleByClientArticleId(authorId, clientArticleId); if (null == oldArticle) { LOGGER.log( Level.WARN, "Not found article [clientHost={0}, clientArticleId={1}] to update", clientHost, clientArticleId); return; } final JSONObject article = new JSONObject(); article.put(Keys.OBJECT_ID, oldArticle.optString(Keys.OBJECT_ID)); article.put(Article.ARTICLE_TITLE, articleTitle); article.put(Article.ARTICLE_CONTENT, articleContent); article.put(Article.ARTICLE_EDITOR_TYPE, 0); article.put(Article.ARTICLE_SYNC_TO_CLIENT, false); article.put(Article.ARTICLE_CLIENT_ARTICLE_ID, clientArticleId); article.put(Article.ARTICLE_AUTHOR_ID, authorId); article.put(Article.ARTICLE_AUTHOR_EMAIL, clientAdminEmail.toLowerCase().trim()); article.put(Article.ARTICLE_T_IS_BROADCAST, false); if (!Role.ADMIN_ROLE.equals(user.optString(User.USER_ROLE))) { articleTags = articleMgmtService.filterReservedTags(articleTags); } try { if (Strings.isEmptyOrNull(articleTags)) { throw new ServiceException(langPropsService.get("articleTagReservedLabel")); } article.put(Article.ARTICLE_TAGS, articleTags); articleMgmtService.updateArticle(article); ret.put(Keys.STATUS_CODE, true); } catch (final ServiceException e) { final String msg = langPropsService.get("updateFailLabel") + " - " + e.getMessage(); LOGGER.log(Level.ERROR, msg, e); ret.put(Keys.MSG, msg); } // Updates client record JSONObject client = clientQueryService.getClientByAdminEmail(clientAdminEmail); if (null == client) { client = new JSONObject(); client.put(Client.CLIENT_ADMIN_EMAIL, clientAdminEmail); client.put(Client.CLIENT_HOST, clientHost); client.put(Client.CLIENT_NAME, clientName); client.put(Client.CLIENT_RUNTIME_ENV, clientRuntimeEnv); client.put(Client.CLIENT_VERSION, clientVersion); client.put(Client.CLIENT_LATEST_ADD_COMMENT_TIME, 0L); client.put(Client.CLIENT_LATEST_ADD_ARTICLE_TIME, System.currentTimeMillis()); clientMgmtService.addClient(client); } else { client.put(Client.CLIENT_ADMIN_EMAIL, clientAdminEmail); client.put(Client.CLIENT_HOST, clientHost); client.put(Client.CLIENT_NAME, clientName); client.put(Client.CLIENT_RUNTIME_ENV, clientRuntimeEnv); client.put(Client.CLIENT_VERSION, clientVersion); client.put(Client.CLIENT_LATEST_ADD_ARTICLE_TIME, System.currentTimeMillis()); clientMgmtService.updateClient(client); } }
@Override public void doAdvice(final HTTPRequestContext context, final Map<String, Object> args) throws RequestProcessAdviceException { final HttpServletRequest request = context.getRequest(); JSONObject requestJSONObject; try { requestJSONObject = Requests.parseRequestJSONObject(request, context.getResponse()); request.setAttribute(Keys.REQUEST, requestJSONObject); } catch (final Exception e) { throw new RequestProcessAdviceException(new JSONObject().put(Keys.MSG, e.getMessage())); } final String userURL = requestJSONObject.optString(User.USER_URL); if (!Strings.isEmptyOrNull(userURL) && invalidUserURL(userURL)) { throw new RequestProcessAdviceException( new JSONObject() .put( Keys.MSG, "URL" + langPropsService.get("colonLabel") + langPropsService.get("invalidUserURLLabel"))); } final String userQQ = requestJSONObject.optString(UserExt.USER_QQ); if (!Strings.isEmptyOrNull(userQQ) && (!Strings.isNumeric(userQQ) || userQQ.length() > MAX_USER_QQ_LENGTH)) { throw new RequestProcessAdviceException( new JSONObject().put(Keys.MSG, langPropsService.get("invalidUserQQLabel"))); } final String userIntro = requestJSONObject.optString(UserExt.USER_INTRO); if (!Strings.isEmptyOrNull(userIntro) && userIntro.length() > MAX_USER_INTRO_LENGTH) { throw new RequestProcessAdviceException( new JSONObject().put(Keys.MSG, langPropsService.get("invalidUserIntroLabel"))); } final String tagErrMsg = langPropsService.get("selfTagLabel") + langPropsService.get("colonLabel") + langPropsService.get("tagsErrorLabel"); String userTags = requestJSONObject.optString(UserExt.USER_TAGS); if (Strings.isEmptyOrNull(userTags)) { throw new RequestProcessAdviceException(new JSONObject().put(Keys.MSG, tagErrMsg)); } final LatkeBeanManager beanManager = Lifecycle.getBeanManager(); final UserMgmtService userMgmtService = beanManager.getReference(UserMgmtService.class); userTags = userMgmtService.formatUserTags(userTags); String[] tagTitles = userTags.split(","); if (null == tagTitles || 0 == tagTitles.length) { throw new RequestProcessAdviceException(new JSONObject().put(Keys.MSG, tagErrMsg)); } tagTitles = new LinkedHashSet<String>(Arrays.asList(tagTitles)).toArray(new String[0]); final StringBuilder tagBuilder = new StringBuilder(); for (int i = 0; i < tagTitles.length; i++) { final String tagTitle = tagTitles[i].trim(); if (Strings.isEmptyOrNull(tagTitle)) { throw new RequestProcessAdviceException(new JSONObject().put(Keys.MSG, tagErrMsg)); } if (!Tag.TAG_TITLE_PATTERN.matcher(tagTitle).matches()) { throw new RequestProcessAdviceException(new JSONObject().put(Keys.MSG, tagErrMsg)); } if (Strings.isEmptyOrNull(tagTitle) || tagTitle.length() > Tag.MAX_TAG_TITLE_LENGTH || tagTitle.length() < 1) { throw new RequestProcessAdviceException(new JSONObject().put(Keys.MSG, tagErrMsg)); } final JSONObject currentUser = (JSONObject) request.getAttribute(User.USER); if (!Role.ADMIN_ROLE.equals(currentUser.optString(User.USER_ROLE)) && ArrayUtils.contains(Symphonys.RESERVED_TAGS, tagTitle)) { throw new RequestProcessAdviceException( new JSONObject() .put( Keys.MSG, langPropsService.get("selfTagLabel") + langPropsService.get("colonLabel") + langPropsService.get("articleTagReservedLabel") + " [" + tagTitle + "]")); } tagBuilder.append(tagTitle).append(","); } if (tagBuilder.length() > 0) { tagBuilder.deleteCharAt(tagBuilder.length() - 1); } requestJSONObject.put(UserExt.USER_TAGS, tagBuilder.toString()); }