001: /*
002: Copyright (C) 2003 Know Gate S.L. All rights reserved.
003: C/Oņa, 107 1š2 28050 Madrid (Spain)
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions
007: are met:
008:
009: 1. Redistributions of source code must retain the above copyright
010: notice, this list of conditions and the following disclaimer.
011:
012: 2. The end-user documentation included with the redistribution,
013: if any, must include the following acknowledgment:
014: "This product includes software parts from hipergate
015: (http://www.hipergate.org/)."
016: Alternately, this acknowledgment may appear in the software itself,
017: if and wherever such third-party acknowledgments normally appear.
018:
019: 3. The name hipergate must not be used to endorse or promote products
020: derived from this software without prior written permission.
021: Products derived from this software may not be called hipergate,
022: nor may hipergate appear in their name, without prior written
023: permission.
024:
025: This library is distributed in the hope that it will be useful,
026: but WITHOUT ANY WARRANTY; without even the implied warranty of
027: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
028:
029: You should have received a copy of hipergate License with this code;
030: if not, visit http://www.hipergate.org or mail to info@hipergate.org
031: */
032:
033: package com.knowgate.http;
034:
035: import java.lang.reflect.InvocationTargetException;
036:
037: import java.io.IOException;
038:
039: import java.util.Properties;
040: import java.util.Enumeration;
041: import java.util.HashMap;
042:
043: import java.text.SimpleDateFormat;
044: import java.text.ParseException;
045:
046: import java.sql.SQLException;
047:
048: import javax.servlet.*;
049: import javax.servlet.http.*;
050:
051: import com.knowgate.debug.DebugFile;
052: import com.knowgate.debug.StackTraceUtil;
053: import com.knowgate.jdc.JDCConnection;
054: import com.knowgate.dataobjs.DB;
055: import com.knowgate.dataobjs.DBBind;
056: import com.knowgate.dataobjs.DBColumn;
057: import com.knowgate.dataobjs.DBPersist;
058: import com.knowgate.dataobjs.DBSubset;
059: import com.knowgate.misc.Environment;
060: import com.knowgate.misc.Gadgets;
061: import com.knowgate.acl.ACL;
062: import com.knowgate.acl.ACLUser;
063: import com.knowgate.workareas.WorkArea;
064:
065: /**
066: * @author Sergio Montoro Ten
067: * @version 3.0
068: */
069:
070: public class HttpDataObjsServlet extends HttpServlet {
071:
072: private static HashMap oBindings;
073: private static HashMap oWorkAreas;
074:
075: public HttpDataObjsServlet() {
076: oBindings = new HashMap();
077: oWorkAreas = new HashMap();
078:
079: }
080:
081: // ---------------------------------------------------------------------------
082:
083: private static synchronized boolean isUserAllowed(
084: JDCConnection oCon, String sUser, String sWrkA)
085: throws SQLException {
086:
087: if (DebugFile.trace) {
088: DebugFile
089: .writeln("Begin HttpDataObjsServlet.isUserAllowed("
090: + sUser + "," + sWrkA + ")");
091: DebugFile.incIdent();
092: }
093:
094: HashMap oUserMap = (HashMap) oWorkAreas.get(sWrkA);
095: if (null == oUserMap) {
096: oUserMap = new HashMap();
097: oWorkAreas.put(sWrkA, oUserMap);
098: }
099: Boolean oAllowed = (Boolean) oUserMap.get(sUser);
100: if (null == oAllowed) {
101: oAllowed = new Boolean(WorkArea.isAdmin(oCon, sWrkA, sUser)
102: || WorkArea.isPowerUser(oCon, sWrkA, sUser)
103: || WorkArea.isUser(oCon, sWrkA, sUser));
104: oUserMap.put(sUser, oAllowed);
105: }
106:
107: if (DebugFile.trace) {
108: DebugFile.decIdent();
109: DebugFile
110: .writeln("End HttpDataObjsServlet.isUserAllowed() : "
111: + String.valueOf(oAllowed.booleanValue()));
112: }
113:
114: return oAllowed.booleanValue();
115: } // isUserAllowed
116:
117: // ---------------------------------------------------------------------------
118:
119: public void doGet(HttpServletRequest request,
120: HttpServletResponse response) throws IOException,
121: ServletException {
122:
123: String sCmd = request.getParameter("command");
124:
125: if (sCmd.equalsIgnoreCase("update")) {
126: response
127: .sendError(
128: HttpServletResponse.SC_METHOD_NOT_ALLOWED,
129: "Command " + sCmd
130: + " only allowed for POST method");
131: return;
132: }
133:
134: if (!sCmd.equalsIgnoreCase("ping")
135: && !sCmd.equalsIgnoreCase("query")) {
136: response.sendError(
137: HttpServletResponse.SC_METHOD_NOT_ALLOWED,
138: "Command " + sCmd + " not recognized");
139: return;
140: }
141:
142: if (sCmd.equalsIgnoreCase("ping")) {
143: response.setContentType("text/plain");
144: response.getOutputStream().print(
145: "HttpDataObjsServlet ping OK");
146: } else if (sCmd.equalsIgnoreCase("query")) {
147: doPost(request, response);
148: }
149:
150: } // doGet
151:
152: // ---------------------------------------------------------------------------
153:
154: public void doPost(HttpServletRequest request,
155: HttpServletResponse response) throws IOException,
156: ServletException {
157:
158: DBBind oBnd = null;
159: JDCConnection oCon = null;
160:
161: short iAuth;
162: boolean bAllowed;
163: String sDbb = request.getParameter("profile");
164: String sUsr = request.getParameter("user");
165: String sPwd = request.getParameter("password");
166: String sCmd = request.getParameter("command");
167: String sCls = request.getParameter("class");
168: String sTbl = request.getParameter("table");
169: String sFld = request.getParameter("fields");
170: String sWhr = request.getParameter("where");
171: String sMax = request.getParameter("maxrows");
172: String sSkp = request.getParameter("skip");
173: String sCol = request.getParameter("coldelim");
174: String sRow = request.getParameter("rowdelim");
175:
176: if (DebugFile.trace) {
177: DebugFile.writeln("Begin HttpDataObjsServlet.doPost()");
178: DebugFile.incIdent();
179: }
180:
181: if (null == sDbb) {
182: sDbb = "hipergate";
183: }
184: if (null == sUsr) {
185: if (DebugFile.trace)
186: DebugFile.decIdent();
187: response.sendError(HttpServletResponse.SC_BAD_REQUEST,
188: "Parameter user is requiered");
189: return;
190: }
191: if (null == sPwd) {
192: if (DebugFile.trace)
193: DebugFile.decIdent();
194: response.sendError(HttpServletResponse.SC_BAD_REQUEST,
195: "Parameter password is requiered");
196: return;
197: }
198: if (null == sCmd) {
199: if (DebugFile.trace)
200: DebugFile.decIdent();
201: response.sendError(HttpServletResponse.SC_BAD_REQUEST,
202: "Parameter command is requiered");
203: return;
204: }
205: if (null == sTbl) {
206: if (DebugFile.trace)
207: DebugFile.decIdent();
208: response.sendError(HttpServletResponse.SC_BAD_REQUEST,
209: "Parameter table is requiered");
210: return;
211: }
212:
213: Properties oEnv = Environment.getProfile(sDbb);
214:
215: if (null == oEnv) {
216: if (DebugFile.trace)
217: DebugFile.decIdent();
218: response.sendError(
219: HttpServletResponse.SC_SERVICE_UNAVAILABLE,
220: "Databind " + sDbb + " is not available");
221: return;
222: }
223:
224: if (!sCmd.equalsIgnoreCase("ping")
225: && !sCmd.equalsIgnoreCase("query")
226: && !sCmd.equalsIgnoreCase("update")) {
227: if (DebugFile.trace)
228: DebugFile.decIdent();
229: response.sendError(
230: HttpServletResponse.SC_METHOD_NOT_ALLOWED,
231: "Command " + sCmd + " not recognized");
232: return;
233: }
234:
235: if (sCmd.equalsIgnoreCase("ping")) {
236: response.setContentType("text/plain");
237: response.getOutputStream().print(
238: "HttpDataObjsServlet ping OK");
239: if (DebugFile.trace) {
240: DebugFile.decIdent();
241: DebugFile.writeln("End HttpDataObjsServlet.doPost()");
242: }
243: return;
244: }
245:
246: if (oBindings.containsKey(sDbb)) {
247: oBnd = (DBBind) oBindings.get(sDbb);
248: } else {
249: oBnd = new DBBind(sDbb);
250: oBindings.put(sDbb, oBnd);
251: }
252:
253: if (sCmd.equalsIgnoreCase("query")) {
254: int iMax;
255: if (null == sMax)
256: iMax = 500;
257: else
258: iMax = Integer.parseInt(sMax);
259: int iSkp;
260: if (null == sSkp)
261: iSkp = 0;
262: else
263: iSkp = Integer.parseInt(sSkp);
264: DBSubset oDbs = new DBSubset(sTbl, sFld, sWhr, iMax);
265: if (null != sRow)
266: oDbs.setRowDelimiter(sRow);
267: if (null != sCol)
268: oDbs.setColumnDelimiter(sCol);
269: oDbs.setMaxRows(iMax);
270: try {
271: oCon = oBnd.getConnection("HttpDataObjsServlet");
272: if (null == oCon) {
273: if (DebugFile.trace)
274: DebugFile.decIdent();
275: throw new ServletException(
276: "ERROR Unable to get database connection from pool "
277: + sDbb);
278: }
279: if (Gadgets.checkEMail(sUsr)) {
280: sUsr = ACLUser.getIdFromEmail(oCon, sUsr);
281: if (null == sUsr)
282: iAuth = ACL.USER_NOT_FOUND;
283: else
284: iAuth = ACL.autenticate(oCon, sUsr, sPwd,
285: ACL.PWD_CLEAR_TEXT);
286: } else {
287: iAuth = ACL.autenticate(oCon, sUsr, sPwd,
288: ACL.PWD_CLEAR_TEXT);
289: }
290: switch (iAuth) {
291: case ACL.ACCOUNT_CANCELLED:
292: response.sendError(
293: HttpServletResponse.SC_FORBIDDEN,
294: "Account cancelled");
295: break;
296: case ACL.ACCOUNT_DEACTIVATED:
297: response.sendError(
298: HttpServletResponse.SC_FORBIDDEN,
299: "Account deactivated");
300: break;
301: case ACL.INVALID_PASSWORD:
302: response.sendError(
303: HttpServletResponse.SC_FORBIDDEN,
304: "Invalid password");
305: break;
306: case ACL.PASSWORD_EXPIRED:
307: response.sendError(
308: HttpServletResponse.SC_FORBIDDEN,
309: "Password expired");
310: break;
311: case ACL.USER_NOT_FOUND:
312: response.sendError(
313: HttpServletResponse.SC_FORBIDDEN,
314: "User not found");
315: break;
316: default:
317: oDbs.load(oCon, iSkp);
318: response.setContentType("text/plain");
319: response.setCharacterEncoding("UTF-8");
320: response.getOutputStream().write(
321: oDbs.toString().getBytes("UTF-8"));
322: }
323: oCon.close("HttpDataObjsServlet");
324: oCon = null;
325: } catch (SQLException sqle) {
326: if (null != oCon) {
327: try {
328: oCon.close("HttpDataObjsServlet");
329: } catch (Exception ignore) {
330: }
331: oCon = null;
332: }
333: if (DebugFile.trace)
334: DebugFile.decIdent();
335: throw new ServletException("SQLException "
336: + sqle.getMessage());
337: }
338: } else if (sCmd.equalsIgnoreCase("update")) {
339: if (DebugFile.trace)
340: DebugFile.writeln("command is update");
341: Enumeration oParamNames = request.getParameterNames();
342: DBPersist oDbp;
343: Class oCls;
344: if (null == sCls) {
345: oDbp = new DBPersist(sTbl, "DBPersist");
346: try {
347: oCls = Class
348: .forName("com.knowgate.dataobjs.DBPersist");
349: } catch (ClassNotFoundException neverthrown) {
350: oCls = null;
351: }
352: } else {
353: try {
354: oCls = Class.forName(sCls);
355: oDbp = (DBPersist) oCls.newInstance();
356: } catch (ClassNotFoundException nfe) {
357: if (DebugFile.trace)
358: DebugFile.decIdent();
359: throw new ServletException("ClassCastException "
360: + nfe.getMessage() + " " + sCls);
361: } catch (InstantiationException ine) {
362: if (DebugFile.trace)
363: DebugFile.decIdent();
364: throw new ServletException("ClassCastException "
365: + ine.getMessage() + " " + sCls);
366: } catch (IllegalAccessException iae) {
367: if (DebugFile.trace)
368: DebugFile.decIdent();
369: throw new ServletException("ClassCastException "
370: + iae.getMessage() + " " + sCls);
371: } catch (ClassCastException cce) {
372: if (DebugFile.trace)
373: DebugFile.decIdent();
374: throw new ServletException("ClassCastException "
375: + cce.getMessage() + " " + sCls);
376: }
377: }
378: if (DebugFile.trace)
379: DebugFile.writeln("class " + oDbp.getClass().getName()
380: + " instantiated");
381: while (oParamNames.hasMoreElements()) {
382: String sKey = (String) oParamNames.nextElement();
383: if (DebugFile.trace)
384: DebugFile.writeln("reading parameter " + sKey);
385: sKey = sKey.trim();
386: int iSpc = sKey.indexOf(' ');
387: if (iSpc > 0) {
388: String sKeyName = sKey.substring(0, iSpc);
389: iSpc++;
390: if (iSpc < sKey.length() - 1) {
391: String sSQLType = sKey.substring(iSpc);
392: if (DebugFile.trace)
393: DebugFile.writeln("sqltype is " + sSQLType);
394: if (sSQLType.toUpperCase().startsWith("DATE")
395: || sSQLType.toUpperCase().startsWith(
396: "DATETIME")
397: || sSQLType.toUpperCase().startsWith(
398: "TIMESTAMP")) {
399: iSpc = sSQLType.indexOf(' ');
400: String sDtFmt = "";
401: try {
402: if (iSpc > 0) {
403: sDtFmt = sSQLType.substring(++iSpc);
404: if (DebugFile.trace)
405: DebugFile
406: .writeln("date format is "
407: + sDtFmt);
408: oDbp
409: .put(
410: sKeyName,
411: request
412: .getParameter(sKey),
413: new SimpleDateFormat(
414: sDtFmt));
415: } else {
416: oDbp
417: .put(
418: sKeyName,
419: request
420: .getParameter(sKey),
421: DBColumn
422: .getSQLType(sSQLType));
423: }
424: } catch (ParseException pe) {
425: if (DebugFile.trace)
426: DebugFile.decIdent();
427: throw new ServletException(
428: "ERROR ParseException "
429: + sKey
430: + "|"
431: + sDtFmt
432: + "|"
433: + request
434: .getParameter(sKey)
435: + " " + pe.getMessage());
436: } catch (IllegalArgumentException ia) {
437: if (DebugFile.trace)
438: DebugFile.decIdent();
439: throw new ServletException(
440: "ERROR IllegalArgumentException "
441: + sKey
442: + "|"
443: + sDtFmt
444: + "|"
445: + request
446: .getParameter(sKey)
447: + ia.getMessage());
448: }
449: } else {
450: try {
451: oDbp.put(sKeyName, request
452: .getParameter(sKey), DBColumn
453: .getSQLType(sSQLType));
454: } catch (NumberFormatException nfe) {
455: if (DebugFile.trace)
456: DebugFile.decIdent();
457: throw new ServletException(
458: "ERROR NumberFormatException "
459: + sKey
460: + " "
461: + " "
462: + request
463: .getParameter(sKey)
464: + " "
465: + nfe.getMessage());
466: }
467: }
468: } else {
469: oDbp.put(sKeyName, request.getParameter(sKey));
470: }
471: } else {
472: oDbp.put(sKey, request.getParameter(sKey));
473: }
474: } // wend
475: try {
476: oCon = oBnd.getConnection("HttpDataObjsServlet");
477: if (null == oCon) {
478: if (DebugFile.trace)
479: DebugFile.decIdent();
480: throw new ServletException(
481: "ERROR Unable to get database connection from pool "
482: + sDbb);
483: }
484: if (Gadgets.checkEMail(sUsr)) {
485: sUsr = ACLUser.getIdFromEmail(oCon, sUsr);
486: if (null == sUsr)
487: iAuth = ACL.USER_NOT_FOUND;
488: else
489: iAuth = ACL.autenticate(oCon, sUsr, sPwd,
490: ACL.PWD_CLEAR_TEXT);
491: } else {
492: iAuth = ACL.autenticate(oCon, sUsr, sPwd,
493: ACL.PWD_CLEAR_TEXT);
494: }
495: switch (iAuth) {
496: case ACL.ACCOUNT_CANCELLED:
497: response.sendError(
498: HttpServletResponse.SC_FORBIDDEN,
499: "Account cancelled");
500: break;
501: case ACL.ACCOUNT_DEACTIVATED:
502: response.sendError(
503: HttpServletResponse.SC_FORBIDDEN,
504: "Account deactivated");
505: break;
506: case ACL.INVALID_PASSWORD:
507: response.sendError(
508: HttpServletResponse.SC_FORBIDDEN,
509: "Invalid password");
510: break;
511: case ACL.PASSWORD_EXPIRED:
512: response.sendError(
513: HttpServletResponse.SC_FORBIDDEN,
514: "Password expired");
515: break;
516: case ACL.USER_NOT_FOUND:
517: response.sendError(
518: HttpServletResponse.SC_FORBIDDEN,
519: "User not found");
520: break;
521: default:
522: if (oDbp.isNull(DB.gu_workarea))
523: bAllowed = true;
524: else
525: bAllowed = isUserAllowed(oCon, sUsr, oDbp
526: .getString(DB.gu_workarea));
527: if (bAllowed) {
528: oCon.setAutoCommit(true);
529: if (null == sCls) {
530: oDbp.store(oCon);
531: } else {
532: if (DebugFile.trace)
533: DebugFile
534: .writeln(oCls.getName()
535: + ".getMethod(\"store\", new Class[]{Class.forName(\"com.knowgate.jdc.JDCConnection\")}).invoke(...)");
536: oCls
537: .getMethod(
538: "store",
539: new Class[] { Class
540: .forName("com.knowgate.jdc.JDCConnection") })
541: .invoke(oDbp, new Object[] { oCon });
542: }
543: response.setContentType("text/plain");
544: response.setCharacterEncoding("UTF-8");
545: response.getOutputStream().print("SUCCESS");
546: } else {
547: response
548: .sendError(
549: HttpServletResponse.SC_FORBIDDEN,
550: "User does not have write permissions on target WorkArea");
551: }
552: } // end switch
553: oCon.close("HttpDataObjsServlet");
554: oCon = null;
555: } catch (InvocationTargetException ite) {
556: if (null != oCon) {
557: try {
558: oCon.close("HttpDataObjsServlet");
559: oCon = null;
560: } catch (Exception ignore) {
561: }
562: } // fi
563: if (DebugFile.trace)
564: DebugFile.decIdent();
565: throw new ServletException(ite.getCause().getClass()
566: .getName()
567: + " "
568: + ite.getCause().getMessage()
569: + "\n"
570: + StackTraceUtil.getStackTrace(ite));
571: } catch (Exception xcpt) {
572: if (null != oCon) {
573: try {
574: oCon.close("HttpDataObjsServlet");
575: oCon = null;
576: } catch (Exception ignore) {
577: }
578: } // fi
579: if (DebugFile.trace)
580: DebugFile.decIdent();
581: throw new ServletException(xcpt.getClass().getName()
582: + " " + xcpt.getMessage() + "\n"
583: + StackTraceUtil.getStackTrace(xcpt));
584: }
585: } // fi
586: if (DebugFile.trace) {
587: DebugFile.decIdent();
588: DebugFile.writeln("End HttpDataObjsServlet.doPost()");
589: }
590: } // doPost
591:
592: // ---------------------------------------------------------------------------
593: }
|