comparison src/nabble/view/web/template/NamlServlet.java @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:7ecd1a4ef557
1 package nabble.view.web.template;
2
3 import fschmidt.util.servlet.AuthorizingServlet;
4 import fschmidt.util.servlet.CanonicalUrl;
5 import fschmidt.util.servlet.JtpContext;
6 import fschmidt.util.servlet.ServletUtils;
7 import nabble.model.Site;
8 import nabble.model.User;
9 import nabble.modules.ModuleManager;
10 import nabble.naml.compiler.Command;
11 import nabble.naml.compiler.CompileException;
12 import nabble.naml.compiler.IPrintWriter;
13 import nabble.naml.compiler.Interpreter;
14 import nabble.naml.compiler.Namespace;
15 import nabble.naml.compiler.Template;
16 import nabble.naml.compiler.TemplateRuntimeException;
17 import nabble.naml.namespaces.BasicNamespace;
18 import nabble.view.lib.Jtp;
19
20 import javax.servlet.ServletException;
21 import javax.servlet.http.HttpServlet;
22 import javax.servlet.http.HttpServletRequest;
23 import javax.servlet.http.HttpServletResponse;
24 import java.io.IOException;
25 import java.io.PrintWriter;
26 import java.io.StringWriter;
27 import java.text.DateFormat;
28 import java.text.SimpleDateFormat;
29 import java.util.Collections;
30 import java.util.Date;
31
32
33 public final class NamlServlet extends HttpServlet implements CanonicalUrl, AuthorizingServlet {
34
35 private static String runTemplate(HttpServletRequest request,String templateName)
36 throws ServletException
37 {
38 Site site = Jtp.getSite(request);
39 if( site == null )
40 return null;
41 Template template = site.getTemplate( templateName ,
42 BasicNamespace.class, NabbleNamespace.class, RequestNamespace.class
43 );
44 if( template == null )
45 return null;
46 StringWriter sw = new StringWriter();
47 try {
48 ModuleManager.run( template, sw, Collections.<String,Object>emptyMap(),
49 new BasicNamespace(template), new NabbleNamespace(site), new RequestNamespace(request)
50 );
51 } catch(IOException e) {
52 throw new RuntimeException(e);
53 } catch(TemplateRuntimeException e) {
54 checkTweaked(request,site,e);
55 throw e;
56 }
57 return sw.toString();
58 }
59
60 public String getCanonicalUrl(HttpServletRequest request) {
61 if( request.getParameterMap().isEmpty() )
62 return Jtp.homePage();
63 try {
64 String macroName = request.getParameter("macro");
65 String path = runTemplate(request,macroName+" canonical path");
66 if( path == null )
67 return null;
68 path = path.trim();
69 if( path.length() > 0 )
70 return Jtp.getBaseUrl(request)+path;
71 } catch(ServletException e) {
72 return null;
73 }
74 /* why bother? - fschmidt
75 Site site = Jtp.getSite(request);
76 StringBuilder url = new StringBuilder();
77 url.append( site.getBaseUrl() ).append( request.getServletPath() );
78 String pathInfo = request.getPathInfo();
79 if( pathInfo != null )
80 url.append( pathInfo );
81 String query = request.getQueryString();
82 if( query != null )
83 url.append( '?' ).append( query );
84 return url.toString();
85 */
86 return null;
87 }
88
89 public String getAuthorizationKey(HttpServletRequest request) throws ServletException {
90 String s = runTemplate(request,"get read authorization key");
91 if( s == null )
92 return null;
93 s = s.trim();
94 return s.length() > 0 ? s : null;
95 }
96
97 @Namespace (
98 name = "read_authorization",
99 global = true
100 )
101 public static final class ReadAuthorization {
102 private final String key;
103
104 private ReadAuthorization(String key) {
105 this.key = key;
106 }
107
108 @Command public void authorization_key(IPrintWriter out,Interpreter interp) {
109 out.print(key);
110 }
111 }
112
113 public boolean authorize(String key,HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
114 Site site = Jtp.getSiteNotNull(request);
115 Template template = site.getTemplate( "authorize for read" ,
116 BasicNamespace.class, NabbleNamespace.class, ServletNamespace.class, ReadAuthorization.class
117 );
118 StringWriter sw = new StringWriter();
119 ModuleManager.run( template, sw, Collections.<String,Object>emptyMap(),
120 new BasicNamespace(template), new NabbleNamespace(site), new ServletNamespace(request,response), new ReadAuthorization(key)
121 );
122 String s = sw.toString();
123 return s.trim().equals("true");
124 }
125
126 protected void service(HttpServletRequest request,HttpServletResponse response)
127 throws ServletException, IOException
128 {
129 Site site = Jtp.getSite(request);
130 if( site == null ) {
131 response.sendError(HttpServletResponse.SC_NOT_FOUND, "Site Not Found");
132 return;
133 }
134 try {
135 service(site,request,response);
136 } catch(TemplateRuntimeException e) {
137 Throwable cause = e.getCause();
138 if( cause instanceof CompileException ) {
139 CompileException ce = (CompileException)cause;
140 if( site.setTweakException(ce) ) {
141 service(site,request,response);
142 return;
143 }
144 }
145 checkTweaked(request,site,e);
146 throw e;
147 }
148 }
149
150 private void service(Site site,HttpServletRequest request,HttpServletResponse response)
151 throws ServletException, IOException
152 {
153 String macroName = request.getParameter("macro");
154 if( macroName == null )
155 throw Jtp.servletException(request,"macroName is null");
156 Template template = site.getTemplate(macroName,
157 BasicNamespace.class, NabbleNamespace.class, ServletNamespace.class
158 );
159 if( template == null )
160 throw Jtp.servletException(request,"macro not found: "+macroName);
161 response.setHeader("X-XSS-Protection","0");
162 BasicNamespace basicNs = new BasicNamespace(template);
163 NabbleNamespace nabbleNs = new NabbleNamespace(site);
164 ServletNamespace servletNs = new ServletNamespace(request, response);
165 StringWriter sw = new StringWriter();
166 PrintWriter out = new PrintWriter(sw);
167 ModuleManager.run( template, out, Collections.<String,Object>emptyMap(),
168 basicNs, nabbleNs, servletNs
169 );
170 out.flush();
171 if( servletNs.cacheEvents != null ) {
172 JtpContext jtpContext = (JtpContext)getServletContext().getAttribute(JtpContext.attrName);
173 jtpContext.setEtag(request,response, servletNs.cacheEvents.toArray(new String[servletNs.cacheEvents.size()]) );
174 }
175 response.getWriter().print(sw.toString());
176 }
177
178 private static void checkTweaked(HttpServletRequest request,Site site,TemplateRuntimeException e)
179 throws ServletException
180 {
181 if( !site.getCustomTweaks().isEmpty() ) {
182 NamlLogger logger = NamlLogger.getLogger(site);
183 DateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
184 logger.log( dateFmt.format(new Date()) + " " + ServletUtils.getCurrentURL(request) + " referer=" + request.getHeader("referer"));
185 logger.log("IP = "+Jtp.getClientIpAddr(request));
186 User user = Jtp.getUser(request);
187 if( user != null )
188 logger.log("user = "+user.getId());
189 logger.log(e.toString());
190 logger.log("");
191 throw new ServletException("NAML exception in customized site: "+e.getMessage(),e);
192 }
193 }
194
195 }