/** * Adds 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.POST) @Before(adviceClass = StopwatchStartAdvice.class) @After(adviceClass = StopwatchEndAdvice.class) public void addArticleFromRhythm( 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 add 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 add 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 authorId = user.optString(Keys.OBJECT_ID); final String clientArticleId = originalArticle.optString(Keys.OBJECT_ID); 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 JSONObject article = new JSONObject(); article.put(Article.ARTICLE_TITLE, articleTitle); 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()); final String permalink = originalArticle.optString(Article.ARTICLE_PERMALINK); final JSONObject articleExisted = articleQueryService.getArticleByClientArticleId(authorId, clientArticleId); final boolean toAdd = null == articleExisted; if (!toAdd) { // Client requests to add an article, but the article already exist in server article.put(Keys.OBJECT_ID, articleExisted.optString(Keys.OBJECT_ID)); article.put(Article.ARTICLE_T_IS_BROADCAST, false); 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>"; } else { // Add final boolean isBroadcast = "aBroadcast".equals(permalink); if (isBroadcast) { articleContent += "<p class='fn-clear'><span class='fn-right'><span class='ft-small'>该广播来自</span> " + "<i style='margin-right:5px;'><a target='_blank' href='" + clientHost + "'>" + clientTitle + "</a></i></span></p>"; } else { 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>"; } article.put(Article.ARTICLE_T_IS_BROADCAST, isBroadcast); } article.put(Article.ARTICLE_CONTENT, articleContent); 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); if (toAdd) { articleMgmtService.addArticle(article); } else { 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); } }
/** * Adds an article locally. * * <p>The request json object (an article): * * <pre> * { * "articleTitle": "", * "articleTags": "", // Tags spliting by ',' * "articleContent": "", * "articleCommentable": boolean, * "articleType": int, * "articleRewardContent": "", * "articleRewardPoint": int * } * </pre> * * @param context the specified context * @param request the specified request * @param response the specified response * @throws IOException io exception * @throws ServletException servlet exception */ @RequestProcessing(value = "/article", method = HTTPRequestMethod.POST) @Before( adviceClass = { StopwatchStartAdvice.class, LoginCheck.class, CSRFCheck.class, ArticleAddValidation.class }) @After(adviceClass = StopwatchEndAdvice.class) public void addArticle( final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException { final JSONRenderer renderer = new JSONRenderer(); context.setRenderer(renderer); final JSONObject ret = Results.falseResult(); renderer.setJSONObject(ret); final JSONObject requestJSONObject = (JSONObject) request.getAttribute(Keys.REQUEST); final String articleTitle = requestJSONObject.optString(Article.ARTICLE_TITLE); String articleTags = requestJSONObject.optString(Article.ARTICLE_TAGS); final String articleContent = requestJSONObject.optString(Article.ARTICLE_CONTENT); // final boolean articleCommentable = requestJSONObject.optBoolean(Article.ARTICLE_COMMENTABLE); final boolean articleCommentable = true; final int articleType = requestJSONObject.optInt(Article.ARTICLE_TYPE, Article.ARTICLE_TYPE_C_NORMAL); final String articleRewardContent = requestJSONObject.optString(Article.ARTICLE_REWARD_CONTENT); final int articleRewardPoint = requestJSONObject.optInt(Article.ARTICLE_REWARD_POINT); final JSONObject article = new JSONObject(); article.put(Article.ARTICLE_TITLE, articleTitle); article.put(Article.ARTICLE_CONTENT, articleContent); article.put(Article.ARTICLE_EDITOR_TYPE, 0); article.put(Article.ARTICLE_COMMENTABLE, articleCommentable); article.put(Article.ARTICLE_TYPE, articleType); article.put(Article.ARTICLE_REWARD_CONTENT, articleRewardContent); article.put(Article.ARTICLE_REWARD_POINT, articleRewardPoint); try { final JSONObject currentUser = (JSONObject) request.getAttribute(User.USER); article.put(Article.ARTICLE_AUTHOR_ID, currentUser.optString(Keys.OBJECT_ID)); final String authorEmail = currentUser.optString(User.USER_EMAIL); article.put(Article.ARTICLE_AUTHOR_EMAIL, authorEmail); if (!Role.ADMIN_ROLE.equals(currentUser.optString(User.USER_ROLE))) { articleTags = articleMgmtService.filterReservedTags(articleTags); } if (Strings.isEmptyOrNull(articleTags)) { throw new ServiceException(langPropsService.get("articleTagReservedLabel")); } article.put(Article.ARTICLE_TAGS, articleTags); article.put(Article.ARTICLE_T_IS_BROADCAST, false); articleMgmtService.addArticle(article); ret.put(Keys.STATUS_CODE, true); } catch (final ServiceException e) { final String msg = e.getMessage(); LOGGER.log( Level.ERROR, "Adds article[title=" + articleTitle + "] failed: {0}", e.getMessage()); ret.put(Keys.MSG, msg); } }