Mercurial Hosting > nabble
view src/nabble/view/web/template/ServletNamespace.java @ 24:e0c501fb5229
remove trk
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 14 Jun 2020 17:56:59 -0600 |
parents | 18cf4872fd7f |
children |
line wrap: on
line source
package nabble.view.web.template; import fschmidt.util.java.HtmlUtils; import fschmidt.util.servlet.JtpContext; import fschmidt.util.servlet.ServletUtils; import nabble.model.DailyNumber; import nabble.model.ModelException; import nabble.model.Node; import nabble.model.Person; import nabble.model.Site; import nabble.model.User; import nabble.model.ViewCount; import nabble.naml.compiler.Command; import nabble.naml.compiler.CommandSpec; import nabble.naml.compiler.Encoder; import nabble.naml.compiler.ExitException; import nabble.naml.compiler.IPrintWriter; import nabble.naml.compiler.Interpreter; import nabble.naml.compiler.Namespace; import nabble.naml.compiler.ScopedInterpreter; import nabble.naml.namespaces.CommandDoc; import nabble.naml.namespaces.TemplateException; import nabble.view.lib.Jtp; import nabble.view.lib.MyJtpServlet; import nabble.view.lib.Shared; import nabble.view.web.user.OnlineStatus; import nabble.view.lib.Recaptcha; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.HashSet; import java.util.regex.Matcher; import java.util.regex.Pattern; @Namespace ( name = "servlet", global = true ) public final class ServletNamespace extends RequestNamespace { private static final Logger logger = LoggerFactory.getLogger(ServletNamespace.class); public final HttpServletResponse response; private final NabbleNamespace nabbleNs; private UserNamespace visitorNs = null; public ServletNamespace(HttpServletRequest request, HttpServletResponse response) { super(request); this.response = response; this.nabbleNs = NabbleNamespace.current(); } public final JtpContext jtpContext() { return MyJtpServlet.getJtpContext(); } private Site site() { return nabbleNs.site(); } private UserNamespace visitorNamespace() throws ServletException { if( visitorNs == null ) { if(Jtp.isCached(request,response) ) throw new RuntimeException("can't get visitor on cached page"); Person visitor = Jtp.getUser(request); visitorNs = new UserNamespace(visitor); } return visitorNs; } @Command public void dont_cache(IPrintWriter out,Interpreter interp) { Jtp.dontCache(response); } @Command public void default_host_name(IPrintWriter out,Interpreter interp) { out.print(Jtp.getDefaultHost()); } public Person getVisitor() throws ServletException { return visitorNamespace().person(); } public User getVisitorUser() throws ServletException { Person visitor = getVisitor(); return !(visitor instanceof User) ? null : (User)visitor; } public static final CommandSpec visitor = CommandSpec.DO; @Command public void visitor(IPrintWriter out,ScopedInterpreter<UserNamespace> interp) throws ServletException { out.print( interp.getArg(visitorNamespace(),"do") ); } private Map<String,FieldNamespace> fields; public static final CommandSpec field = new CommandSpec.Builder() .scopedParameters("do") .dotParameter("do") .parameters("name") .build() ; @Command public void field(IPrintWriter out,ScopedInterpreter<FieldNamespace> interp) { String name = interp.getArgString("name"); if (fields == null) fields = new HashMap<String,FieldNamespace>(); FieldNamespace field = fields.get(name); if( field == null ) { field = new FieldNamespace(name); field.setValue(request); FieldNamespace f = fields.put(name,field); if( f != null ) throw new RuntimeException("field named '"+name+"' already defined"); } out.print( interp.getArg(field,"do") ); } public static final CommandSpec redirect_to = CommandSpec.NO_OUTPUT() .dotParameter("url") .build() ; @Command public void redirect_to(IPrintWriter out,Interpreter interp) throws IOException { interp.setEncoder(Encoder.TEXT); String redirectUrl = interp.getArgString("url").trim(); Jtp.sendRedirect(request,response,redirectUrl); throw new ExitException(); } public static final CommandSpec redirect_with_notice = new CommandSpec.Builder() .parameters("url") .dotParameter("notice") .build() ; @Command public void redirect_with_notice(IPrintWriter out,Interpreter interp) throws IOException, ServletException { String notice = interp.getArgString("notice").trim(); notice = notice.replaceAll("(\n|\r|\t)",""); notice = HtmlUtils.javascriptStringEncode(notice); String redirectUrl = interp.getArgString("url").trim(); Shared.javascriptRedirect(request, response, redirectUrl, "Nabble.setVar('notice','" + notice + "');"); throw new ExitException(); } public static final CommandSpec profile_update_with_redirection_to = CommandSpec.NO_OUTPUT() .dotParameter("url") .build() ; @Command public void profile_update_with_redirection_to(IPrintWriter out,Interpreter interp) throws IOException, ServletException { StringBuffer js = new StringBuffer(); String userId = ServletUtils.getCookieValue(request,"userId"); if (Jtp.isInteger(userId)) { Person visitor = site().getUser(Long.valueOf(userId)); if (visitor != null && visitor instanceof User) { User user = (User) visitor; String name = user.getName(); String passcookie = user.getPasscookie(); ServletUtils.setCookie(request, response, "username", HtmlUtils.urlEncode(name), true, null); ServletUtils.setCookie(request, response, "password", HtmlUtils.urlEncode(passcookie), true, null); js.append("if (parent.nabbleinfo) {"); js.append("Nabble.setCookie('username','").append(HtmlUtils.javascriptStringEncode(HtmlUtils.urlEncode(name))).append("');"); js.append("Nabble.setCookie('password','").append(HtmlUtils.javascriptStringEncode(HtmlUtils.urlEncode(passcookie))).append("');"); js.append("}"); } } String redirectUrl = interp.getArgString("url").trim(); Shared.javascriptRedirect(request, response, redirectUrl, js.toString()); throw new ExitException(); } public static final CommandSpec send_http_error = new CommandSpec.Builder() .parameters("code") .dotParameter("text") .build() ; @Command public void send_http_error(IPrintWriter out,Interpreter interp) throws IOException { String text = interp.getArgString("text").trim(); int code = interp.getArgAsInt("code"); response.sendError(code, text); throw new ExitException(); } @Command public void set_visitor_online(IPrintWriter out,Interpreter interp) throws ServletException { User visitor = Jtp.getUser(request); OnlineStatus.setOnline(request, visitor, site()); } public static final CommandSpec author_is_online = new CommandSpec.Builder() .parameters("search_id") .build() ; @Command public void author_is_online(IPrintWriter out,Interpreter interp) { String authorId = interp.getArgString("search_id"); out.print( OnlineStatus.isOnline(authorId, site()) ); } public static final CommandSpec nabble_html = new CommandSpec.Builder() .scopedParameters("do","output") .build() ; @CommandDoc( "Commands in \"do\" call \"put_in_head\" and print to the body at the same time. Commands in \"output\" can't do this. The \"output\" is the final output." ) @Command public void nabble_html(IPrintWriter out,ScopedInterpreter<HtmlNamespace> interp) { HtmlNamespace ns = new HtmlNamespace(interp); out.print( interp.getArg(ns,"output") ); } public static final CommandSpec check_user = new CommandSpec.Builder() .dotParameter("user_id") .outputtedParameters() .build() ; @Command public void check_user(IPrintWriter out,Interpreter interp) throws ServletException { String userId = interp.getArgString("user_id"); if( site().getUser(Jtp.parseLong(request,userId)) == null ) throw Jtp.servletException(request,"user not found: "+userId); } public static final CommandSpec do_login = new CommandSpec.Builder() .parameters("email","password") .optionalParameters("nextUrl") .build() ; @Command public void do_login(IPrintWriter out,Interpreter interp) throws IOException, ServletException { String email = interp.getArgString("email").trim(); String password = interp.getArgString("password"); String nextUrl = interp.getArgString("nextUrl"); if( nextUrl == null ) nextUrl = "/"; User user = site().getUserFromEmail(email); if( user != null && user.isRegistered() && user.checkPassword(password) ) { Jtp.doLogin(request,response,user,true); DailyNumber.logins.inc(); Shared.javascriptRedirect(request,response, nextUrl); throw new ExitException(); } } public static final CommandSpec registration = CommandSpec.DO() .parameters("email","password","user_name") .optionalParameters("next_url") .build() ; @Command public void registration(IPrintWriter out,ScopedInterpreter<RegistrationNamespace> interp) throws IOException, ServletException, ModelException { String email = interp.getArgString("email").trim(); String userName = interp.getArgString("user_name"); String password = interp.getArgString("password"); String nextUrl = interp.getArgString("next_url"); if( nextUrl == null ) nextUrl = "/"; out.print( interp.getArg(new RegistrationNamespace(site(), email,password,userName,nextUrl),"do") ); } public static final CommandSpec check_captcha = CommandSpec.NO_OUTPUT; @Command public void check_captcha(IPrintWriter out, Interpreter interp) throws ModelException.InvalidRecaptcha, IOException { Recaptcha.check(request); } @Command public void do_logout(IPrintWriter out,Interpreter interp) { Jtp.logout(request,response); } public static final CommandSpec set_response_header = new CommandSpec.Builder() .parameters("name","value") .outputtedParameters() .build() ; @Command public void set_response_header(IPrintWriter out,Interpreter interp) { response.setHeader( interp.getArgString("name"), interp.getArgString("value") ); } @Command public void remote_address(IPrintWriter out,Interpreter interp) { out.print(Jtp.getClientIpAddr(request)); } public static final CommandSpec increment_node_view_count = new CommandSpec.Builder() .parameters("node_id") .build() ; @Command public void increment_node_view_count(IPrintWriter out,Interpreter interp) throws ServletException { Site site = NabbleNamespace.current().site(); long nodeId = interp.getArgAsLong("node_id"); boolean isUser = getVisitor() instanceof User; ViewCount.inc(site,nodeId,isUser); } public static final CommandSpec get_node_from_request_parameter = CommandSpec.DO; @Command public void get_node_from_request_parameter(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) throws IOException, ServletException, TemplateException { Node node = site().getNode( Jtp.getLong(request, "node") ); if( node == null ) { throw TemplateException.newInstance("node_not_found"); } out.print( interp.getArg(new NodeNamespace(node),"do") ); } public static final CommandSpec get_user_from_parameter = CommandSpec.DO; @Command public void get_user_from_parameter(IPrintWriter out,ScopedInterpreter<UserNamespace> interp) throws IOException, ServletException { String userId = Jtp.getString(request,"user"); Person person = site().getPerson(userId); if( person == null ) { response.sendError(HttpServletResponse.SC_NOT_FOUND, "User not found."); throw new ExitException(); } out.print( interp.getArg(new UserNamespace(person),"do") ); } Set<String> cacheEvents = null; public void cache(String event) { if( cacheEvents != null ) cacheEvents.add(event); } public static final CommandSpec uncache_for = CommandSpec.NO_OUTPUT() .scopedParameters("do") .dotParameter("do") .optionalParameters("do") .build() ; @Command public void uncache_for(IPrintWriter out,ScopedInterpreter<CacheNamespace> interp) { if( visitorNs != null ) throw new RuntimeException("can't cache page that depends on visitor"); CacheNamespace ns = new CacheNamespace(); try { interp.getArgString(ns,"do"); cacheEvents = ns.events; request.setAttribute(Jtp.CACHED,"yes"); } catch(CacheNamespace.DontCache e) {} } public static final CommandSpec set_anonymous_name = CommandSpec.NO_OUTPUT() .parameters("name") .build() ; @Command public void set_anonymous_name(IPrintWriter out,Interpreter interp) throws ServletException { Person visitor = getVisitor(); String anonymousName = interp.getArgString("name"); if( visitor instanceof User || anonymousName == null || anonymousName.trim().length() == 0 || !"POST".equals(request.getMethod()) // ??? ) return; try { visitor.setName(anonymousName); } catch(ModelException e) { throw new RuntimeException(e); } ServletUtils.setCookie(request, response, "anonymousName", HtmlUtils.urlEncode(anonymousName), true, null); } public static final CommandSpec get_registration = CommandSpec.DO() .parameters("registration_key","email") .build() ; @Command public void get_registration(IPrintWriter out,ScopedInterpreter<UserNamespace> interp) throws ModelException { String key = interp.getArgString("registration_key"); String email = interp.getArgString("email"); User user = site().getRegistration(key); if (user==null || !user.getEmail().equalsIgnoreCase(email)) { logger.error("Registration failed: url="+ServletUtils.getCurrentURL(request)+" email="+email+" user="+(user==null?"null":user.getEmail())+" key="+key+" user-agent="+request.getHeader("user-agent")); out.print((String)null); return; } out.print( interp.getArg(new UserNamespace(user),"do") ); } public static final CommandSpec get_next_url_from_registration = new CommandSpec.Builder() .parameters("registration_key") .build() ; @Command public void get_next_url_from_registration(IPrintWriter out,Interpreter interp) { String key = interp.getArgString("registration_key"); String nextUrl = site().getNextUrl(key); if( nextUrl==null ) nextUrl = "/"; out.print(nextUrl); } @Command public void visitor_ip_address(IPrintWriter out,Interpreter interp) { out.print(Jtp.getClientIpAddr(request)); } }