Commit 73829b83 authored by Liang Ding's avatar Liang Ding

🔥 Fix #12682

parent a8c9c2cd
/**
* Filters for page caching, URL transformation.
*/
package org.b3log.solo.filter;
......@@ -15,7 +15,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.b3log.solo.filter;
package org.b3log.solo.processor;
import org.apache.commons.lang.StringUtils;
import org.b3log.latke.Keys;
......@@ -23,27 +23,25 @@ import org.b3log.latke.Latkes;
import org.b3log.latke.ioc.BeanManager;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.servlet.RequestContext;
import org.b3log.latke.servlet.handler.Handler;
import org.b3log.solo.service.InitService;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Checks initialization filter.
* Checks initialization handler.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author <a href="https://github.com/TsLenMo">TsLenMo</a>
* @version 1.1.1.5, Jan 24, 2019
* @since 0.3.1
* @version 1.0.0.0, Mar 1, 2019
* @since 3.2.0
*/
public final class InitCheckFilter implements Filter {
public class InitCheckHandler implements Handler {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(InitCheckFilter.class);
private static final Logger LOGGER = Logger.getLogger(InitCheckHandler.class);
/**
* Whether initialization info reported.
......@@ -51,30 +49,14 @@ public final class InitCheckFilter implements Filter {
private static boolean initReported;
@Override
public void init(final FilterConfig filterConfig) {
}
/**
* If Solo has not been initialized, so redirects to /start.
*
* @param request the specified request
* @param response the specified response
* @param chain filter chain
* @throws IOException io exception
* @throws ServletException servlet exception
*/
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
final String requestURI = httpServletRequest.getRequestURI();
final boolean isSpiderBot = (boolean) httpServletRequest.getAttribute(Keys.HttpRequest.IS_SEARCH_ENGINE_BOT);
public void handle(final RequestContext context) {
final String requestURI = context.requestURI();
final boolean isSpiderBot = (boolean) context.attr(Keys.HttpRequest.IS_SEARCH_ENGINE_BOT);
LOGGER.log(Level.TRACE, "Request [URI={0}]", requestURI);
// 禁止直接获取 robots.txt https://github.com/b3log/solo/issues/12543
if (requestURI.startsWith("/robots.txt") && !isSpiderBot) {
final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
context.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
......@@ -82,14 +64,14 @@ public final class InitCheckFilter implements Filter {
final BeanManager beanManager = BeanManager.getInstance();
final InitService initService = beanManager.getReference(InitService.class);
if (initService.isInited()) {
chain.doFilter(request, response);
context.handle();
return;
}
if (StringUtils.startsWith(requestURI, Latkes.getContextPath() + "/oauth/github")) {
// Do initialization
chain.doFilter(request, response);
context.handle();
return;
}
......@@ -99,11 +81,7 @@ public final class InitCheckFilter implements Filter {
initReported = true;
}
request.setAttribute(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/start");
chain.doFilter(request, response);
}
@Override
public void destroy() {
context.attr(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/start");
context.handle();
}
}
......@@ -15,7 +15,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.b3log.solo.filter;
package org.b3log.solo.processor;
import org.apache.commons.lang.StringUtils;
import org.b3log.latke.Keys;
......@@ -27,6 +27,7 @@ import org.b3log.latke.repository.RepositoryException;
import org.b3log.latke.servlet.DispatcherServlet;
import org.b3log.latke.servlet.HttpMethod;
import org.b3log.latke.servlet.RequestContext;
import org.b3log.latke.servlet.handler.Handler;
import org.b3log.solo.model.Article;
import org.b3log.solo.model.Page;
import org.b3log.solo.repository.ArticleRepository;
......@@ -36,65 +37,46 @@ import org.b3log.solo.service.PermalinkQueryService;
import org.b3log.solo.util.Solos;
import org.json.JSONObject;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Article/Page permalink filter.
* Article/Page permalink handler.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.1.9, Jan 24, 2019
* @see org.b3log.solo.processor.ArticleProcessor#showArticle(org.b3log.latke.servlet.RequestContext)
* @see org.b3log.solo.processor.PageProcessor#showPage(org.b3log.latke.servlet.RequestContext)
* @since 0.3.1
* @version 1.0.0.0, Mar 1, 2019
* @since 3.2.0
*/
public final class PermalinkFilter implements Filter {
public class PermalinkHandler implements Handler {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(PermalinkFilter.class);
@Override
public void init(final FilterConfig filterConfig) {
}
private static final Logger LOGGER = Logger.getLogger(PermalinkHandler.class);
/**
* Tries to dispatch request to article processor.
*
* @param request the specified request
* @param response the specified response
* @param chain filter chain
* @throws IOException io exception
* @throws ServletException servlet exception
* Whether initialization info reported.
*/
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
final String requestURI = httpServletRequest.getRequestURI();
final String contextPath = Latkes.getContextPath();
final String permalink = StringUtils.substringAfter(requestURI, contextPath);
if (PermalinkQueryService.invalidPermalinkFormat(permalink)) {
LOGGER.log(Level.DEBUG, "Skip filter request [URI={0}]", permalink);
chain.doFilter(request, response);
return;
}
private static boolean initReported;
@Override
public void handle(final RequestContext context) {
JSONObject article;
JSONObject page = null;
final BeanManager beanManager = BeanManager.getInstance();
try {
final BeanManager beanManager = BeanManager.getInstance();
final InitService initService = beanManager.getReference(InitService.class);
if (!initService.isInited()) {
chain.doFilter(request, response);
context.handle();
return;
}
final String requestURI = context.requestURI();
final String contextPath = Latkes.getContextPath();
final String permalink = StringUtils.substringAfter(requestURI, contextPath);
if (PermalinkQueryService.invalidPermalinkFormat(permalink)) {
LOGGER.log(Level.DEBUG, "Skip filter request [URI={0}]", permalink);
context.handle();
return;
}
......@@ -108,61 +90,50 @@ public final class PermalinkFilter implements Filter {
if (null == page && null == article) {
LOGGER.log(Level.DEBUG, "Not found article/page with permalink [{0}]", permalink);
chain.doFilter(request, response);
context.handle();
return;
}
} catch (final RepositoryException e) {
LOGGER.log(Level.ERROR, "Processes article permalink filter failed", e);
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
context.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// If requests an article and the article need view password, sends redirect to the password form
if (null != article && Solos.needViewPwd(httpServletRequest, httpServletResponse, article)) {
if (null != article && Solos.needViewPwd(context, article)) {
try {
httpServletResponse.sendRedirect(Latkes.getServePath() + "/console/article-pwd?articleId=" + article.optString(Keys.OBJECT_ID));
context.sendRedirect(Latkes.getServePath() + "/console/article-pwd?articleId=" + article.optString(Keys.OBJECT_ID));
return;
} catch (final Exception e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
context.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
}
dispatchToArticleOrPageProcessor(request, response, article, page);
chain.doFilter(request, response);
dispatchToArticleOrPageProcessor(context, article, page);
context.handle();
}
/**
* Dispatches the specified request to the specified article or page
* processor with the specified response.
* Dispatches the specified request to the specified article or page processor with the specified response.
*
* @param request the specified request
* @param response the specified response
* @param article the specified article
* @param page the specified page
* @param context the specified request context
* @param article the specified article
* @param page the specified page
* @see DispatcherServlet#result(RequestContext)
*/
private void dispatchToArticleOrPageProcessor(final ServletRequest request, final ServletResponse response,
final JSONObject article, final JSONObject page) {
final RequestContext context = new RequestContext();
context.setRequest((HttpServletRequest) request);
context.setResponse((HttpServletResponse) response);
private void dispatchToArticleOrPageProcessor(final RequestContext context, final JSONObject article, final JSONObject page) {
if (null != article) {
request.setAttribute(Article.ARTICLE, article);
request.setAttribute(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/article");
context.attr(Article.ARTICLE, article);
context.attr(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/article");
} else {
request.setAttribute(Page.PAGE, page);
request.setAttribute(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/page");
context.attr(Page.PAGE, page);
context.attr(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/page");
}
request.setAttribute(Keys.HttpRequest.REQUEST_METHOD, HttpMethod.GET.name());
}
@Override
public void destroy() {
context.attr(Keys.HttpRequest.REQUEST_METHOD, HttpMethod.GET.name());
}
}
......@@ -921,7 +921,7 @@ public class ArticleQueryService {
return null;
}
if (null != context && Solos.needViewPwd(context.getRequest(), context.getResponse(), article)) {
if (null != context && Solos.needViewPwd(context, article)) {
final String content = langPropsService.get("articleContentPwd");
article.put(ARTICLE_CONTENT, content);
} else {
......
......@@ -922,7 +922,7 @@ public class DataModelService {
article.put(Common.HAS_UPDATED, false);
}
if (Solos.needViewPwd(context.getRequest(), context.getResponse(), article)) {
if (Solos.needViewPwd(context, article)) {
final String content = langPropsService.get("articleContentPwd");
article.put(ARTICLE_CONTENT, content);
}
......
......@@ -393,18 +393,18 @@ public final class Solos {
* The blogger itself dose not need view password never.
* </p>
*
* @param request the specified request
* @param response the specified response
* @param article the specified article
* @param context the specified request context
* @param article the specified article
* @return {@code true} if need, returns {@code false} otherwise
*/
public static boolean needViewPwd(final HttpServletRequest request, final HttpServletResponse response, final JSONObject article) {
public static boolean needViewPwd(final RequestContext context, final JSONObject article) {
final String articleViewPwd = article.optString(Article.ARTICLE_VIEW_PWD);
if (StringUtils.isBlank(articleViewPwd)) {
return false;
}
final HttpServletRequest request = context.getRequest();
if (null == request) {
return true;
}
......@@ -421,6 +421,7 @@ public final class Solos {
}
}
final HttpServletResponse response = context.getResponse();
final JSONObject currentUser = getCurrentUser(request, response);
return !(null != currentUser && !Role.VISITOR_ROLE.equals(currentUser.optString(User.USER_ROLE)));
......
......@@ -20,7 +20,7 @@
-->
<!--
Description: Solo web deployment descriptor.
Version: 1.0.5.4, Jan 24, 2019
Version: 1.1.0.0, Mar 1, 2019
Author: Liang Ding
-->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
......@@ -29,40 +29,6 @@
<listener-class>org.b3log.solo.SoloServletListener</listener-class>
</listener>
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>org.b3log.latke.servlet.filter.EncodingFilter</filter-class>
<init-param>
<param-name>requestEncoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>responseEncoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>InitCheckFilter</filter-name>
<filter-class>org.b3log.solo.filter.InitCheckFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>InitCheckFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>PermalinkFilter</filter-name>
<filter-class>org.b3log.solo.filter.PermalinkFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PermalinkFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>
60
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment