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 @@ ...@@ -15,7 +15,7 @@
* You should have received a copy of the GNU Affero General Public License * 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/>. * 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.apache.commons.lang.StringUtils;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
...@@ -23,27 +23,25 @@ import org.b3log.latke.Latkes; ...@@ -23,27 +23,25 @@ import org.b3log.latke.Latkes;
import org.b3log.latke.ioc.BeanManager; import org.b3log.latke.ioc.BeanManager;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; 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 org.b3log.solo.service.InitService;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; 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="http://88250.b3log.org">Liang Ding</a>
* @author <a href="https://github.com/TsLenMo">TsLenMo</a> * @version 1.0.0.0, Mar 1, 2019
* @version 1.1.1.5, Jan 24, 2019 * @since 3.2.0
* @since 0.3.1
*/ */
public final class InitCheckFilter implements Filter { public class InitCheckHandler implements Handler {
/** /**
* Logger. * Logger.
*/ */
private static final Logger LOGGER = Logger.getLogger(InitCheckFilter.class); private static final Logger LOGGER = Logger.getLogger(InitCheckHandler.class);
/** /**
* Whether initialization info reported. * Whether initialization info reported.
...@@ -51,30 +49,14 @@ public final class InitCheckFilter implements Filter { ...@@ -51,30 +49,14 @@ public final class InitCheckFilter implements Filter {
private static boolean initReported; private static boolean initReported;
@Override @Override
public void init(final FilterConfig filterConfig) { public void handle(final RequestContext context) {
} final String requestURI = context.requestURI();
final boolean isSpiderBot = (boolean) context.attr(Keys.HttpRequest.IS_SEARCH_ENGINE_BOT);
/**
* 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);
LOGGER.log(Level.TRACE, "Request [URI={0}]", requestURI); LOGGER.log(Level.TRACE, "Request [URI={0}]", requestURI);
// 禁止直接获取 robots.txt https://github.com/b3log/solo/issues/12543 // 禁止直接获取 robots.txt https://github.com/b3log/solo/issues/12543
if (requestURI.startsWith("/robots.txt") && !isSpiderBot) { if (requestURI.startsWith("/robots.txt") && !isSpiderBot) {
final HttpServletResponse httpServletResponse = (HttpServletResponse) response; context.sendError(HttpServletResponse.SC_FORBIDDEN);
httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
return; return;
} }
...@@ -82,14 +64,14 @@ public final class InitCheckFilter implements Filter { ...@@ -82,14 +64,14 @@ public final class InitCheckFilter implements Filter {
final BeanManager beanManager = BeanManager.getInstance(); final BeanManager beanManager = BeanManager.getInstance();
final InitService initService = beanManager.getReference(InitService.class); final InitService initService = beanManager.getReference(InitService.class);
if (initService.isInited()) { if (initService.isInited()) {
chain.doFilter(request, response); context.handle();
return; return;
} }
if (StringUtils.startsWith(requestURI, Latkes.getContextPath() + "/oauth/github")) { if (StringUtils.startsWith(requestURI, Latkes.getContextPath() + "/oauth/github")) {
// Do initialization // Do initialization
chain.doFilter(request, response); context.handle();
return; return;
} }
...@@ -99,11 +81,7 @@ public final class InitCheckFilter implements Filter { ...@@ -99,11 +81,7 @@ public final class InitCheckFilter implements Filter {
initReported = true; initReported = true;
} }
request.setAttribute(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/start"); context.attr(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/start");
chain.doFilter(request, response); context.handle();
}
@Override
public void destroy() {
} }
} }
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* You should have received a copy of the GNU Affero General Public License * 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/>. * 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.apache.commons.lang.StringUtils;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
...@@ -27,6 +27,7 @@ import org.b3log.latke.repository.RepositoryException; ...@@ -27,6 +27,7 @@ import org.b3log.latke.repository.RepositoryException;
import org.b3log.latke.servlet.DispatcherServlet; import org.b3log.latke.servlet.DispatcherServlet;
import org.b3log.latke.servlet.HttpMethod; import org.b3log.latke.servlet.HttpMethod;
import org.b3log.latke.servlet.RequestContext; import org.b3log.latke.servlet.RequestContext;
import org.b3log.latke.servlet.handler.Handler;
import org.b3log.solo.model.Article; import org.b3log.solo.model.Article;
import org.b3log.solo.model.Page; import org.b3log.solo.model.Page;
import org.b3log.solo.repository.ArticleRepository; import org.b3log.solo.repository.ArticleRepository;
...@@ -36,65 +37,46 @@ import org.b3log.solo.service.PermalinkQueryService; ...@@ -36,65 +37,46 @@ import org.b3log.solo.service.PermalinkQueryService;
import org.b3log.solo.util.Solos; import org.b3log.solo.util.Solos;
import org.json.JSONObject; import org.json.JSONObject;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; 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> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.1.9, Jan 24, 2019 * @version 1.0.0.0, Mar 1, 2019
* @see org.b3log.solo.processor.ArticleProcessor#showArticle(org.b3log.latke.servlet.RequestContext) * @since 3.2.0
* @see org.b3log.solo.processor.PageProcessor#showPage(org.b3log.latke.servlet.RequestContext)
* @since 0.3.1
*/ */
public final class PermalinkFilter implements Filter { public class PermalinkHandler implements Handler {
/** /**
* Logger. * Logger.
*/ */
private static final Logger LOGGER = Logger.getLogger(PermalinkFilter.class); private static final Logger LOGGER = Logger.getLogger(PermalinkHandler.class);
@Override
public void init(final FilterConfig filterConfig) {
}
/** /**
* Tries to dispatch request to article processor. * Whether initialization info reported.
*
* @param request the specified request
* @param response the specified response
* @param chain filter chain
* @throws IOException io exception
* @throws ServletException servlet exception
*/ */
@Override private static boolean initReported;
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;
}
@Override
public void handle(final RequestContext context) {
JSONObject article; JSONObject article;
JSONObject page = null; JSONObject page = null;
final BeanManager beanManager = BeanManager.getInstance();
try { try {
final BeanManager beanManager = BeanManager.getInstance();
final InitService initService = beanManager.getReference(InitService.class); final InitService initService = beanManager.getReference(InitService.class);
if (!initService.isInited()) { 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; return;
} }
...@@ -108,61 +90,50 @@ public final class PermalinkFilter implements Filter { ...@@ -108,61 +90,50 @@ public final class PermalinkFilter implements Filter {
if (null == page && null == article) { if (null == page && null == article) {
LOGGER.log(Level.DEBUG, "Not found article/page with permalink [{0}]", permalink); LOGGER.log(Level.DEBUG, "Not found article/page with permalink [{0}]", permalink);
chain.doFilter(request, response); context.handle();
return; return;
} }
} catch (final RepositoryException e) { } catch (final RepositoryException e) {
LOGGER.log(Level.ERROR, "Processes article permalink filter failed", e); LOGGER.log(Level.ERROR, "Processes article permalink filter failed", e);
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND); context.sendError(HttpServletResponse.SC_NOT_FOUND);
return; return;
} }
// If requests an article and the article need view password, sends redirect to the password form // 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 { 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; return;
} catch (final Exception e) { } catch (final Exception e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND); context.sendError(HttpServletResponse.SC_NOT_FOUND);
return; return;
} }
} }
dispatchToArticleOrPageProcessor(request, response, article, page); dispatchToArticleOrPageProcessor(context, article, page);
chain.doFilter(request, response); context.handle();
} }
/** /**
* Dispatches the specified request to the specified article or page * Dispatches the specified request to the specified article or page processor with the specified response.
* processor with the specified response.
* *
* @param request the specified request * @param context the specified request context
* @param response the specified response * @param article the specified article
* @param article the specified article * @param page the specified page
* @param page the specified page
* @see DispatcherServlet#result(RequestContext) * @see DispatcherServlet#result(RequestContext)
*/ */
private void dispatchToArticleOrPageProcessor(final ServletRequest request, final ServletResponse response, private void dispatchToArticleOrPageProcessor(final RequestContext context, final JSONObject article, final JSONObject page) {
final JSONObject article, final JSONObject page) {
final RequestContext context = new RequestContext();
context.setRequest((HttpServletRequest) request);
context.setResponse((HttpServletResponse) response);
if (null != article) { if (null != article) {
request.setAttribute(Article.ARTICLE, article); context.attr(Article.ARTICLE, article);
request.setAttribute(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/article"); context.attr(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/article");
} else { } else {
request.setAttribute(Page.PAGE, page); context.attr(Page.PAGE, page);
request.setAttribute(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/page"); context.attr(Keys.HttpRequest.REQUEST_URI, Latkes.getContextPath() + "/page");
} }
request.setAttribute(Keys.HttpRequest.REQUEST_METHOD, HttpMethod.GET.name()); context.attr(Keys.HttpRequest.REQUEST_METHOD, HttpMethod.GET.name());
}
@Override
public void destroy() {
} }
} }
...@@ -921,7 +921,7 @@ public class ArticleQueryService { ...@@ -921,7 +921,7 @@ public class ArticleQueryService {
return null; 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"); final String content = langPropsService.get("articleContentPwd");
article.put(ARTICLE_CONTENT, content); article.put(ARTICLE_CONTENT, content);
} else { } else {
......
...@@ -922,7 +922,7 @@ public class DataModelService { ...@@ -922,7 +922,7 @@ public class DataModelService {
article.put(Common.HAS_UPDATED, false); 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"); final String content = langPropsService.get("articleContentPwd");
article.put(ARTICLE_CONTENT, content); article.put(ARTICLE_CONTENT, content);
} }
......
...@@ -393,18 +393,18 @@ public final class Solos { ...@@ -393,18 +393,18 @@ public final class Solos {
* The blogger itself dose not need view password never. * The blogger itself dose not need view password never.
* </p> * </p>
* *
* @param request the specified request * @param context the specified request context
* @param response the specified response * @param article the specified article
* @param article the specified article
* @return {@code true} if need, returns {@code false} otherwise * @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); final String articleViewPwd = article.optString(Article.ARTICLE_VIEW_PWD);
if (StringUtils.isBlank(articleViewPwd)) { if (StringUtils.isBlank(articleViewPwd)) {
return false; return false;
} }
final HttpServletRequest request = context.getRequest();
if (null == request) { if (null == request) {
return true; return true;
} }
...@@ -421,6 +421,7 @@ public final class Solos { ...@@ -421,6 +421,7 @@ public final class Solos {
} }
} }
final HttpServletResponse response = context.getResponse();
final JSONObject currentUser = getCurrentUser(request, response); final JSONObject currentUser = getCurrentUser(request, response);
return !(null != currentUser && !Role.VISITOR_ROLE.equals(currentUser.optString(User.USER_ROLE))); return !(null != currentUser && !Role.VISITOR_ROLE.equals(currentUser.optString(User.USER_ROLE)));
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
--> -->
<!-- <!--
Description: Solo web deployment descriptor. Description: Solo web deployment descriptor.
Version: 1.0.5.4, Jan 24, 2019 Version: 1.1.0.0, Mar 1, 2019
Author: Liang Ding 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" <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 @@ ...@@ -29,40 +29,6 @@
<listener-class>org.b3log.solo.SoloServletListener</listener-class> <listener-class>org.b3log.solo.SoloServletListener</listener-class>
</listener> </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-config>
<session-timeout> <session-timeout>
60 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