Mercurial Hosting > nabble
diff src/nabble/view/web/template/NodePageNamespace.java @ 0:7ecd1a4ef557
add content
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 21 Mar 2019 19:15:52 -0600 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nabble/view/web/template/NodePageNamespace.java Thu Mar 21 19:15:52 2019 -0600 @@ -0,0 +1,226 @@ +package nabble.view.web.template; + +import fschmidt.db.DbDatabase; +import nabble.model.FileUpload; +import nabble.model.Message; +import nabble.model.ModelException; +import nabble.model.Node; +import nabble.model.Person; +import nabble.naml.compiler.Command; +import nabble.naml.compiler.CommandSpec; +import nabble.naml.compiler.IPrintWriter; +import nabble.naml.compiler.Interpreter; +import nabble.naml.compiler.Namespace; +import nabble.naml.compiler.ScopedInterpreter; +import nabble.naml.namespaces.TemplateException; +import nabble.view.lib.Jtp; +import nabble.view.lib.Permissions; +import nabble.view.web.forum.NodeEditorNamespace; +import nabble.view.web.forum.SearchNamespace; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import java.util.Date; +import java.util.Random; + + +@Namespace ( + name = "node_page", + global = true +) +public final class NodePageNamespace { + + private static final Logger logger = LoggerFactory.getLogger(NodePageNamespace.class); + + private NodeNamespace nodeNs; + + public NodePageNamespace(Node node) { + this(new NodeNamespace(node)); + } + + public NodePageNamespace(NodeNamespace nodeNs) { + this.nodeNs = nodeNs; + } + + public final Node node() { + return nodeNs.node(); + } + + public final NodeNamespace nodeNamespace() { + return nodeNs; + } + + private DbDatabase db() { + return node().getSite().getDb(); + } + + + public static final CommandSpec page_node = CommandSpec.DO; + + @Command public void page_node(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) { + out.print( interp.getArg(nodeNs,"do") ); + } + + public static final CommandSpec search_namespace = CommandSpec.DO() + .requiredInStack(ServletNamespace.class) + .build() + ; + + @Command public void search_namespace(IPrintWriter out,ScopedInterpreter<SearchNamespace> interp) + throws ServletException + { + ServletNamespace servletNamespace = interp.getFromStack(ServletNamespace.class); + out.print( interp.getArg(new SearchNamespace(node(),servletNamespace),"do") ); + } + + + public static final CommandSpec edit_page_node = CommandSpec.DO() + .optionalParameters("commit") + .requiredInStack(ServletNamespace.class) + .build() + ; + + @Command public void edit_page_node(IPrintWriter out,ScopedInterpreter<NodeEditorNamespace> interp) { + ServletNamespace servletNs = interp.getFromStack(ServletNamespace.class); + boolean commit = interp.getArgAsBoolean("commit",true); + DbDatabase db = db(); + db.beginTransaction(); + try { + nodeNs.refreshNode(); + interp.getArgString(new NodeEditorNamespace(node(),servletNs),"do"); + if( commit ) { + db.commitTransaction(); + nodeNs.refreshNode(); + } + } finally { + db.endTransaction(); + } + } + + + public static final CommandSpec create_child_of_page_node = CommandSpec.DO() + .parameters("subject","message","is_html","kind") + .optionalParameters("commit","type") + .restrictedParameter("kind","app","post") + .requiredInStack(ServletNamespace.class) + .build() + ; + + @Command public void create_child_of_page_node(IPrintWriter out,ScopedInterpreter<NodeEditorNamespace> interp) + throws ModelException, ServletException + { + ServletNamespace servletNs = interp.getFromStack(ServletNamespace.class); + HttpServletRequest request = servletNs.request; + boolean commit = interp.getArgAsBoolean("commit",true); + String subject = interp.getArgString("subject"); + String message = interp.getArgString("message"); + Message.Format msgFmt = interp.getArgAsBoolean("is_html",false) ? Message.Format.HTML : Message.Format.TEXT; + String type = interp.getArgString("type"); + Node.Kind kind = "app".equals(interp.getArgString("kind"))? Node.Kind.APP : Node.Kind.POST; + Person visitor = servletNs.getVisitor(); + DbDatabase db = db(); + db.beginTransaction(); + try { + nodeNs.refreshNode(); + Node node = node(); + Node newNode = visitor.newChildNode(kind,subject,message,msgFmt,node); + FileUpload.checkFileTags(newNode.getMessage(), visitor); + if (type != null) + newNode.setType(type); + interp.getArgString(new NodeEditorNamespace(newNode,servletNs),"do"); + if( commit ) { + db.commitTransaction(); + nodeNs.refreshNode(); + } + } finally { + db.endTransaction(); + } + } + + private static final long TWO_HOURS = 2 * 60 * 60 * 1000; + + @Command public void should_show_creation_notice(IPrintWriter out,Interpreter interp) { + long created = node().getWhenCreated().getTime(); + out.print( System.currentTimeMillis() - created < TWO_HOURS ); + } + + + // + // Spambot security checker + // + private static final byte SUBMIT_POSSIBILITIES = 10; + private static final long START = new Date().getTime(); + private static final long FIVE_MINUTES = 5 * 60 * 1000; + private static final Random SECURITY_RND = new Random(); + + public static final CommandSpec antispam_submit_button = CommandSpec.DO() + .parameters("class", "value") + .requiredInStack(ServletNamespace.class) + .build() + ; + + @Command public void antispam_submit_button(IPrintWriter out,Interpreter interp) { + ServletNamespace servletNs = interp.getFromStack(ServletNamespace.class); + HttpServletRequest request = servletNs.request; + + String className = interp.getArgString("class"); + String value = interp.getArgString("value"); + + Byte goodIndex = (byte) SECURITY_RND.nextInt(SUBMIT_POSSIBILITIES); + request.getSession().setAttribute("sec"+node().getId(), goodIndex); + for (byte i = 0; i < SUBMIT_POSSIBILITIES; i++) { + out.print("<input id=\"s" + i + "\" type=\"submit\" class=\""+ className + "\" value=\"" + value + "\" name=\"s" + i + "\" style=\"display:none\"/>"); + } + String elementId = "s" + goodIndex; + StringBuilder bufValue = new StringBuilder(); + for (int i = 0; i < elementId.length(); i++) { + if (bufValue.length() > 0) + bufValue.append(','); + bufValue.append((int) elementId.charAt(i)); + } + out.print("<script type='text/javascript'>"); + out.print("var sv=String.fromCharCode("+ bufValue.toString() +");"); + out.print("document.getElementById(sv).style.display='inline-block';"); + out.print("</script>"); + } + + public static final CommandSpec check_antispam_submit = CommandSpec.DO() + .optionalParameters("bypass") + .requiredInStack(ServletNamespace.class) + .build() + ; + + @Command public void check_antispam_submit(IPrintWriter out,Interpreter interp) + throws TemplateException + { + ServletNamespace servletNs = interp.getFromStack(ServletNamespace.class); + HttpServletRequest request = servletNs.request; + + String bypass = interp.getArgString("bypass"); + if (bypass != null && request.getParameter(bypass) != null) + return; + + String attributeName = "sec"+node().getId(); + Byte goodIndex = (Byte) request.getSession().getAttribute(attributeName); + boolean isSafe = goodIndex != null; + if (isSafe) { + for (int i= 0; i < SUBMIT_POSSIBILITIES; i++) { + String param = request.getParameter("s"+i); + if (i == goodIndex) + isSafe = isSafe && param != null; + else + isSafe = isSafe && param == null; + } + } + request.getSession().removeAttribute(attributeName); + if (!isSafe) { + long now = new Date().getTime(); + if (now - START > FIVE_MINUTES) { + logger.error("suspicious_request - IP: " + Jtp.getClientIpAddr(request)); + throw TemplateException.newInstance("suspicious_request"); + } + } + } +}