001package jmri.web.servlet.permission; 002 003import java.io.*; 004import java.net.URLDecoder; 005import java.nio.charset.StandardCharsets; 006 007import static jmri.web.servlet.ServletUtil.UTF8_TEXT_HTML; 008 009import javax.servlet.ServletException; 010import javax.servlet.annotation.WebServlet; 011import javax.servlet.http.*; 012 013import jmri.*; 014import jmri.util.FileUtil; 015import jmri.web.servlet.ServletUtil; 016 017import org.openide.util.lookup.ServiceProvider; 018 019/** 020 * 021 * @author Randall Wood (C) 2014, 2016 022 * @author mstevetodd (C) 2017 023 * @author Daniel Bergqvist (C) 2024 024 */ 025@WebServlet(name = "PermissionServlet", 026 urlPatterns = {"/permission"}) 027@ServiceProvider(service = HttpServlet.class) 028public class PermissionServlet extends HttpServlet { 029 030 protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 031 032 String theRequest = request.getRequestURI().substring("/permission/".length()); 033 // log.error("Request: {}", theRequest); 034 035 switch (theRequest) { 036 case "login": 037 login(request, response); 038 break; 039 case "logout": 040 logout(request, response); 041 break; 042// case "status": 043// status(request, response); 044// break; 045 default: 046 response.sendError(HttpServletResponse.SC_NOT_FOUND); 047 } 048 } 049 050 private static void sendPage(String page, String message, 051 HttpServletRequest request, HttpServletResponse response) 052 throws IOException { 053 054 //print the html, using the replacement values listed to fill in the calculated stuff 055 response.setHeader("Connection", "Keep-Alive"); // NOI18N 056 response.setContentType(UTF8_TEXT_HTML); 057 response.getWriter().print(String.format(request.getLocale(), 058 FileUtil.readURL(FileUtil.findURL(Bundle.getMessage(request.getLocale(), page))), 059 Bundle.getMessage(request.getLocale(), "PermissionTitle"), // page title is parm 1 060 InstanceManager.getDefault(ServletUtil.class).getNavBar(request.getLocale(), "/permission"), // navbar is parm 2 061 InstanceManager.getDefault(ServletUtil.class).getRailroadName(false), // railroad name is parm 3 062 InstanceManager.getDefault(ServletUtil.class).getFooter(request.getLocale(), "/permission"), // footer is parm 4 063 message // Response message 064 )); 065 } 066 067 private void login(HttpServletRequest request, HttpServletResponse response) throws IOException { 068 if (request.getContentLength() > 0) { 069 StringBuilder textBuilder = new StringBuilder(); 070 try (BufferedReader reader = new BufferedReader(new InputStreamReader( 071 request.getInputStream(), StandardCharsets.UTF_8))) { 072 int c; 073 while ((c = reader.read()) != -1) { 074 textBuilder.append((char) c); 075 } 076 } 077 078 PermissionManager mngr = InstanceManager.getDefault(PermissionManager.class); 079 080 String username = null; 081 String password = null; 082 083 for (String param : textBuilder.toString().split("&")) { 084 String[] parts = param.split("="); 085 switch (parts[0]) { 086 case "username": 087 username = URLDecoder.decode(parts[1], StandardCharsets.UTF_8); 088 break; 089 case "password": 090 if (parts.length > 1) 091 password = URLDecoder.decode(parts[1], StandardCharsets.UTF_8); 092 else 093 password = ""; 094 break; 095 default: 096 throw new IllegalArgumentException("Unknown parameter: \""+parts[0]+"\" with value \""+parts[1]+"\""); 097 } 098 } 099 100 if (username != null && password != null) { 101 // log.warn("Login with {} and {}", username, password); 102 103 if (mngr.isAGuestUser(username)) { 104 String message = Bundle.getMessage("GuestMessage"); 105 sendPage("Response.html", message, request, response); 106 return; 107 } 108 109 String sessId = PermissionServlet.getSessionId(request); 110 if (sessId == null) sessId = ""; 111 112 StringBuilder sessionId = new StringBuilder(sessId); 113 114 boolean result = mngr.remoteLogin(sessionId, request.getLocale(), username, password); 115 116 if (result) { 117 setSessionId(sessionId.toString(), response); 118 } 119 String message = result ? Bundle.getMessage("LoginSuccessful") : Bundle.getMessage("BadUsernameOrPassword"); 120 sendPage("Response.html", message, request, response); 121 122 return; 123 } 124 } 125 126 //print the html, using the replacement values listed to fill in the calculated stuff 127 response.setHeader("Connection", "Keep-Alive"); // NOI18N 128 response.setContentType(UTF8_TEXT_HTML); 129 response.getWriter().print(String.format(request.getLocale(), 130 FileUtil.readURL(FileUtil.findURL(Bundle.getMessage(request.getLocale(), "Login.html"))), 131 Bundle.getMessage(request.getLocale(), "PermissionTitle"), // page title is parm 1 132 InstanceManager.getDefault(ServletUtil.class).getNavBar(request.getLocale(), "/permission"), // navbar is parm 2 133 InstanceManager.getDefault(ServletUtil.class).getRailroadName(false), // railroad name is parm 3 134 InstanceManager.getDefault(ServletUtil.class).getFooter(request.getLocale(), "/permission") // footer is parm 4 135 )); 136 } 137 138 private void logout(HttpServletRequest request, HttpServletResponse response) throws IOException { 139 String sessionId = PermissionServlet.getSessionId(request); 140 InstanceManager.getDefault(PermissionManager.class).remoteLogout(sessionId); 141 sendPage("Response.html", Bundle.getMessage("LogoutSuccessful"), request, response); 142 } 143/* 144 private void status(HttpServletRequest request, HttpServletResponse response) throws IOException { 145 146 log.error("Context path: {}", request.getContextPath()); 147 log.error("Servlet path: {}", request.getServletPath()); 148 log.error("Query string: {}", request.getQueryString()); 149 log.error("Request URI: {}", request.getRequestURI()); 150 log.error("Request URL: {}", request.getRequestURL().toString()); 151 152// request.getContentLength(); 153// request.getInputStream(); 154// request.getMethod(); 155 } 156*/ 157 public static void permissionDenied(HttpServletRequest request, HttpServletResponse response) throws IOException { 158 String session = ""; 159 InstanceManager.getDefault(PermissionManager.class).remoteLogout(session); 160 sendPage("Response.html", Bundle.getMessage("PermissionDenied"), request, response); 161 } 162 163 public static String getSessionId(HttpServletRequest request) { 164 Cookie[] cookies = request.getCookies(); 165 if (cookies == null) return null; 166 for (Cookie c : cookies) { 167 if ("sessionId".equals(c.getName())) { 168 return c.getValue(); 169 } 170 } 171 return null; 172 } 173 174 public static void setSessionId(String sessionId, HttpServletResponse response) { 175 Cookie cookie = new Cookie("sessionId", sessionId); 176 cookie.setPath("/"); 177 response.addCookie(cookie); 178 } 179 180// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> 181 /** 182 * Handles the HTTP <code>GET</code> method. 183 * 184 * @param request servlet request 185 * @param response servlet response 186 * @throws ServletException if a servlet-specific error occurs 187 * @throws IOException if an I/O error occurs 188 */ 189 @Override 190 protected void doGet(HttpServletRequest request, HttpServletResponse response) 191 throws ServletException, IOException { 192 processRequest(request, response); 193 } 194 195 /** 196 * Handles the HTTP <code>POST</code> method. 197 * 198 * @param request servlet request 199 * @param response servlet response 200 * @throws ServletException if a servlet-specific error occurs 201 * @throws IOException if an I/O error occurs 202 */ 203 @Override 204 protected void doPost(HttpServletRequest request, HttpServletResponse response) 205 throws ServletException, IOException { 206 processRequest(request, response); 207 } 208 209 /** 210 * Returns a short description of the servlet. 211 * 212 * @return a String containing servlet description 213 */ 214 @Override 215 public String getServletInfo() { 216 return "About Servlet"; 217 }// </editor-fold> 218 219// private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(PermissionServlet.class); 220 221}