package com.agilecontrol.embed.control; import com.agilecontrol.nea.core.control.util.FileDownload; import com.agilecontrol.nea.core.control.web.AttachmentManager; import com.agilecontrol.nea.core.control.web.UserWebImpl; import com.agilecontrol.nea.core.control.web.WebUtils; import com.agilecontrol.nea.core.control.web.filter.CustomerHttpSessionFilter; import com.agilecontrol.nea.core.query.ColumnLink; import com.agilecontrol.nea.core.query.Expression; import com.agilecontrol.nea.core.query.QueryEngine; import com.agilecontrol.nea.core.query.QueryRequestImpl; import com.agilecontrol.nea.core.query.QueryResult; import com.agilecontrol.nea.core.schema.Column; import com.agilecontrol.nea.core.schema.Filter; import com.agilecontrol.nea.core.schema.Table; import com.agilecontrol.nea.core.schema.TableManager; import com.agilecontrol.nea.core.util.ConfigValues; import com.agilecontrol.nea.util.Attachment; import com.agilecontrol.nea.util.CommandExecuter; import com.agilecontrol.nea.util.NDSException; import com.agilecontrol.nea.util.Tools; import com.agilecontrol.nea.util.Validator; import io.swagger.annotations.Api; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.PrintWriter; import java.net.URLEncoder; import java.sql.Clob; import java.util.Properties; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.SystemUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @Api( tags = {"Attach资源"} ) @RestController @RequestMapping({"/Attach"}) public class AttachController { private static final Logger log = LoggerFactory.getLogger(AttachController.class); private static final String NO_ATTACH = "Attachment

File not found!"; @GetMapping( value = {"/schema/{schema}/table/{table}/column/{column}/t/{t}/f/{f}"}, params = {"token"} ) public void download(HttpServletRequest request, HttpServletResponse response, @PathVariable("schema") String schema, @PathVariable("table") int tableId, @PathVariable("column") int columnId, @PathVariable("t") long t, @PathVariable("f") String f, @RequestParam( value = "token", defaultValue = "" ) String token) throws Exception { log.debug("download attachment: schema={},table={},column={},t={},f={},token={}", new Object[]{schema, Integer.valueOf(tableId), Integer.valueOf(columnId), Long.valueOf(t), f, token}); this.attachDo(request, response, schema, tableId, columnId, -1, -1, t, f); } @GetMapping( value = {"/schema/{schema}/table/{table}/column/{column}/id/{id}/v/{v}/f/{f}"}, params = {"token"} ) public void downloadWithObjectVersion(HttpServletRequest request, HttpServletResponse response, @PathVariable("schema") String schema, @PathVariable("table") int tableId, @PathVariable("column") int columnId, @PathVariable("id") int objectId, @PathVariable("v") int version, @PathVariable("f") String f, @RequestParam( value = "token", defaultValue = "" ) String token) throws Exception { log.debug("download attachment: schema={},table={},column={},objectId={},v={},f={},token={}", new Object[]{schema, Integer.valueOf(tableId), Integer.valueOf(columnId), Integer.valueOf(objectId), Integer.valueOf(version), f, token}); this.attachDo(request, response, schema, tableId, columnId, objectId, version, -1L, f); } @GetMapping( value = {"/schema/{schema}/table/{table}/column/{column}/id/{id}/f/{f}"}, params = {"token"} ) public void downloadWithObject(HttpServletRequest request, HttpServletResponse response, @PathVariable("schema") String schema, @PathVariable("table") int tableId, @PathVariable("column") int columnId, @PathVariable("id") int objectId, @PathVariable("f") String f, @RequestParam( value = "token", defaultValue = "" ) String token) throws Exception { log.debug("download attachment: schema={},table={},column={},objectId={},f={},token={}", new Object[]{schema, Integer.valueOf(tableId), Integer.valueOf(columnId), Integer.valueOf(objectId), f, token}); this.attachDo(request, response, schema, tableId, columnId, objectId, -1, -1L, f); } @GetMapping( value = {"/table/{table}/column/{column}/t/{t}/f/{f}"}, params = {"token"} ) public void downloadNoSchema(HttpServletRequest request, HttpServletResponse response, @PathVariable("table") int tableId, @PathVariable("column") int columnId, @PathVariable("t") long t, @PathVariable("f") String f, @RequestParam( value = "schema", defaultValue = "" ) String schema, @RequestParam( value = "token", defaultValue = "" ) String token) throws Exception { log.debug("download attachment: schema={},table={},column={},t={},f={},token={}", new Object[]{schema, Integer.valueOf(tableId), Integer.valueOf(columnId), Long.valueOf(t), f, token}); this.attachDo(request, response, schema, tableId, columnId, -1, -1, t, f); } @GetMapping( value = {"/table/{table}/column/{column}/id/{id}/v/{v}/f/{f}"}, params = {"token"} ) public void downloadWithObjectVersionNoSchema(HttpServletRequest request, HttpServletResponse response, @PathVariable("table") int tableId, @PathVariable("column") int columnId, @PathVariable("id") int objectId, @PathVariable("v") int version, @PathVariable("f") String f, @RequestParam( value = "schema", defaultValue = "" ) String schema, @RequestParam( value = "token", defaultValue = "" ) String token) throws Exception { log.debug("download attachment: schema={},table={},column={},objectId={},v={},f={},token={}", new Object[]{schema, Integer.valueOf(tableId), Integer.valueOf(columnId), Integer.valueOf(objectId), Integer.valueOf(version), f, token}); this.attachDo(request, response, schema, tableId, columnId, objectId, version, -1L, f); } @GetMapping( value = {"/table/{table}/column/{column}/id/{id}/f/{f}"}, params = {"token"} ) public void downloadWithObjectNoSchema(HttpServletRequest request, HttpServletResponse response, @PathVariable("table") int tableId, @PathVariable("column") int columnId, @PathVariable("id") int objectId, @PathVariable("f") String f, @RequestParam( value = "schema", defaultValue = "" ) String schema, @RequestParam( value = "token", defaultValue = "" ) String token) throws Exception { log.debug("download attachment: schema={},table={},column={},objectId={},f={},token={}", new Object[]{schema, Integer.valueOf(tableId), Integer.valueOf(columnId), Integer.valueOf(objectId), f, token}); this.attachDo(request, response, schema, tableId, columnId, objectId, -1, -1L, f); } private void attachDo(HttpServletRequest request, HttpServletResponse response, String schema, int tableId, int columnId, int objectId, int version, long time, String f) throws Exception { UserWebImpl userWeb = CustomerHttpSessionFilter.getUserWeb(); if(StringUtils.hasText(schema)) { if(ConfigValues.get("portal.attach.lowercase", false)) { schema = schema.toLowerCase(); } userWeb.setDataSource(schema); } TableManager tableManager = TableManager.getInstance(); if(tableId == -1) { throw new IllegalArgumentException("object type not set"); } else { Table table = tableManager.getTable(tableId); Column col = tableManager.getColumn(columnId); String size = request.getParameter("s"); AttachmentManager writer; String is; File destSize; File attDir; File destFile1; if(time > 0L) { if(this.shouldCheckColumnPermission(col) && (userWeb.getPermission(table.getSecurityDirectory()) & 1) != 1) { throw new NDSException("@no-permission@"); } writer = (AttachmentManager)WebUtils.getServletContextManager().getActor("nea.web.AttachmentManager"); String att = writer.getTimeFolderParent(userWeb, table, col, time); Attachment writer1 = writer.getAttachmentInfo(att, String.valueOf(time), version); if(writer1 != null) { this.countDownloadTimes(userWeb, col, objectId); int fileName = (int)writer1.getSize(); is = writer1.getOrigFileName(); Object file = null; destSize = writer.getAttachmentFile(writer1); if(col.getDisplaySetting().getObjectType() == 9 && Validator.isNotNull(size)) { destFile1 = new File(destSize.getParent() + File.separator + size + "_" + destSize.getName()); if(!destFile1.exists()) { file = writer.getAttachmentData(writer1); } else { file = new FileInputStream(destFile1); fileName = (int)destFile1.length(); } writeFile(is, writer1.getExtension(), fileName, (InputStream)file, request, response); } else { String destFile = ""; if(Validator.isNotNull(size)) { destFile = destSize.getParent() + File.separator + size + "_" + is; } else { destFile = destSize.getParent() + File.separator + is; } File downloadFileName = new File(destFile); if(!downloadFileName.exists()) { attDir = writer.findAttachmentDir(writer1); downloadFileName = writer.findFile(attDir, writer1); } this.writeFileWithMoreContentType(request, response, downloadFileName, new String[]{is}); } if(null != file) { ((InputStream)file).close(); } } else { PrintWriter fileName1 = response.getWriter(); fileName1.print("Attachment

File not found!"); fileName1.close(); } } else if(objectId != -1) { if(this.shouldCheckColumnPermission(col)) { boolean writer2 = this.objectExists(table, objectId, userWeb); if(writer2) { if(!userWeb.hasObjectPermission(table.getName(), objectId, 1) && !this.hasExtendReadPermission(table, objectId, userWeb)) { throw new NDSException("@no-permission@"); } } else if((userWeb.getPermission(table.getSecurityDirectory()) & 1) != 1) { throw new NDSException("@no-permission@"); } } this.countDownloadTimes(userWeb, col, objectId); writer = (AttachmentManager)WebUtils.getServletContextManager().getActor("nea.web.AttachmentManager"); Attachment att1 = writer.getAttachmentInfo(userWeb.getClientDomain() + "/" + AttachmentManager.getSchemaPath(userWeb.getDataSource()) + table.getRealTableName() + "/" + col.getName(), objectId + "", version); if(att1 != null) { if(Boolean.TRUE.equals(col.getJSONProp("swf")) && "pdf".equalsIgnoreCase(att1.getExtension())) { String writer6 = writer.getAttachmentFile(att1).getAbsolutePath(); File fileName3 = new File(writer.getAttachmentFile(att1).getAbsolutePath() + ".swf"); if(!fileName3.exists()) { CommandExecuter is2 = new CommandExecuter(fileName3.getAbsolutePath() + ".log"); String file2 = ConfigValues.get("program.swf", ConfigValues.get("dir.nea.root") + "/bin/pdf2swf"); if(SystemUtils.IS_OS_WINDOWS) { is2.run(file2 + " -f -G -t -T 9 \"" + writer6 + "\" -o \"" + writer6 + ".swf\""); } else { is2.run(file2 + " -f -G -t -T 9 " + writer6 + " -o " + writer6 + ".swf"); } } is = "/servlets/binserv/SWF?" + request.getQueryString(); response.sendRedirect("/nea/core/object/swfviewer.jsp?swf=" + URLEncoder.encode(is, "UTF-8")); } else { int writer5 = (int)att1.getSize(); String fileName2 = att1.getOrigFileName(); Object is1 = null; File file1 = writer.getAttachmentFile(att1); if(col.getDisplaySetting().getObjectType() == 9 && Validator.isNotNull(size)) { destSize = new File(file1.getParent() + File.separator + size + "_" + file1.getName()); if(!destSize.exists()) { is1 = writer.getAttachmentData(att1); } else { is1 = new FileInputStream(destSize); writer5 = (int)destSize.length(); } writeFile(fileName2, att1.getExtension(), writer5, (InputStream)is1, request, response); } else { String destSize1 = ""; if(Validator.isNotNull(size)) { destSize1 = file1.getParent() + File.separator + size + "_" + fileName2; } else { destSize1 = file1.getParent() + File.separator + fileName2; } destFile1 = new File(destSize1); String downloadFileName1 = destFile1.getName(); if(!destFile1.exists()) { attDir = writer.findAttachmentDir(att1); destFile1 = writer.findFile(attDir, att1); } this.writeFileWithMoreContentType(request, response, destFile1, new String[]{downloadFileName1}); } if(is1 != null) { ((InputStream)is1).close(); } } return; } PrintWriter writer4 = response.getWriter(); writer4.print("Attachment

File not found!"); writer4.close(); } else { PrintWriter writer3 = response.getWriter(); writer3.print("Attachment

File not found!"); writer3.close(); } } } protected boolean hasExtendReadPermission(Table table, int objectId, UserWebImpl userWeb) throws Exception { QueryEngine engine = QueryEngine.getInstance(); String col = (String)table.getJSONProp("user_read_column"); if(Validator.isNotNull(col)) { Column cnt = table.getColumn(col); if(cnt != null) { if(cnt.getReferenceTable() != null && cnt.getReferenceTable().getName().equals("USERS")) { int props1 = QueryEngine.getInstance().doQueryInt("select " + cnt.getName() + " from " + table.getName() + " " + table.getRealTableName() + " where id=?", new Object[]{Integer.valueOf(objectId)}); if(props1 == userWeb.getUserId()) { return true; } } else { Properties props = cnt.getProperties(); if(props != null && cnt.getDisplaySetting().getObjectType() == 12) { String tbName = props.getProperty("table"); if("USERS".equalsIgnoreCase(tbName)) { Table userTable = TableManager.getInstance().getTable("users"); Object obj = engine.doQueryOne("select " + cnt.getName() + " from " + table.getName() + " " + table.getRealTableName() + " where id=?", new Object[]{Integer.valueOf(objectId)}); if(obj != null) { String value; if(obj instanceof Clob) { value = ((Clob)obj).getSubString(1L, (int)((Clob)obj).length()); } else { if(!(obj instanceof String)) { throw new NDSException("Unsupported value for user read checking:" + table + "." + cnt + " of record id=" + objectId); } value = (String)obj; } QueryRequestImpl query = engine.createRequest(userWeb.getSession()); query.setMainTable(userTable.getId()); query.addSelection(userTable.getPrimaryKey().getId()); Expression expr = new Expression(new ColumnLink(new int[]{userTable.getPrimaryKey().getId()}), "=" + userWeb.getUserId(), (String)null); Filter fo = Filter.parse(value); expr = expr.combine(fo.getExprObject(), 1); query.addParam(expr); Object params = null; int cnt1 = engine.doQueryInt(query.toCountSQL(), (Object[])params); return cnt1 == 1; } return true; } } } } } int cnt2 = engine.doQueryInt("select count(*) from au_process where ad_table_id=? ", new Object[]{Integer.valueOf(table.getId())}); if(cnt2 > 0) { cnt2 = engine.doQueryInt("select count(*) from au_pi_user u, au_phaseinstance pi where u.ad_user_id=? and pi.ad_table_id=? and pi.record_id=? and u.au_pi_id=pi.id and rownum<2", new Object[]{Integer.valueOf(userWeb.getUserId()), Integer.valueOf(table.getId()), Integer.valueOf(objectId)}); if(cnt2 > 0) { return true; } } return false; } protected boolean objectExists(Table table, int objectId, UserWebImpl userWeb) throws Exception { QueryRequestImpl query = QueryEngine.getInstance().createRequest(userWeb.getSession()); query.setMainTable(table.getId()); query.addSelection(table.getPrimaryKey().getId()); Expression expr = new Expression(); expr.setColumnLink(table.getName() + "." + table.getPrimaryKey().getName()); expr.setCondition("=" + objectId); expr.setDescription("(" + table + ".ID=" + objectId + ")"); query.addParam(expr); QueryResult result = QueryEngine.getInstance().doQuery(query); log.debug(query.toSQL()); return result.getTotalRowCount() > 0; } protected void countDownloadTimes(UserWebImpl userWeb, Column column, int objectId) { try { TableManager tx = TableManager.getInstance(); Table cdt = tx.getTable("u_attach_cnt"); if(cdt != null) { int cnt = QueryEngine.getInstance().executeUpdate("update u_attach_cnt set cnt=nvl(cnt,0)+1 where table_id=? and column_id=? and record_id=?", new Object[]{Integer.valueOf(column.getTable().getId()), Integer.valueOf(column.getId()), Integer.valueOf(objectId)}); if(cnt == 0) { QueryEngine.getInstance().executeUpdate("insert into u_attach_cnt(id,table_id,column_id,record_id,cnt) values (get_sequences(\'u_attach_cnt\'),?,?,?,1)", new Object[]{Integer.valueOf(column.getTable().getId()), Integer.valueOf(column.getId()), Integer.valueOf(objectId)}); } } } catch (Throwable var7) { log.error("fail to count download times:", var7); } } private boolean shouldCheckColumnPermission(Column col) throws Exception { return col.getJSONProps() == null || !col.getJSONProps().optBoolean("skip_permission_check", false); } public static void writeFile(String fileName, String extension, int contentLength, InputStream is, HttpServletRequest request, HttpServletResponse response) throws Exception { String ct = Tools.getContentType(extension, "application/octetstream"); response.setContentType(ct + "; charset=GBK"); response.setContentLength(contentLength); response.setHeader("Content-Disposition", "inline;" + WebUtils.getContentDispositionFileName(fileName, request)); ServletOutputStream os = response.getOutputStream(); byte[] b = new byte[8192]; int bInt; while((bInt = is.read(b, 0, b.length)) != -1) { os.write(b, 0, bInt); } os.flush(); os.close(); } public void writeFileWithMoreContentType(HttpServletRequest request, HttpServletResponse response, File file, String ... fileNames) throws Exception { FileDownload fileDownload = new FileDownload(); fileDownload.processRequest(request, response, true, file, fileNames); } }