|
21 | 21 | import java.io.IOException;
|
22 | 22 | import java.io.OutputStreamWriter;
|
23 | 23 | import java.nio.charset.StandardCharsets;
|
| 24 | +import java.nio.file.AccessDeniedException; |
24 | 25 | import java.nio.file.Files;
|
25 | 26 | import java.nio.file.Path;
|
26 | 27 | import java.nio.file.attribute.FileAttribute;
|
|
31 | 32 | import java.util.Arrays;
|
32 | 33 | import java.util.List;
|
33 | 34 | import java.util.Set;
|
| 35 | +import java.util.logging.Level; |
| 36 | +import java.util.logging.Logger; |
34 | 37 |
|
35 | 38 | import org.apache.commons.io.FileUtils;
|
36 | 39 | import org.apache.commons.lang.SystemUtils;
|
@@ -75,163 +78,181 @@ public class ExportTask implements RequestHandler {
|
75 | 78 |
|
76 | 79 | /**
|
77 | 80 | * public constructor
|
| 81 | + * |
78 | 82 | * @param config sonarqube configuration
|
79 | 83 | */
|
80 |
| - ExportTask(Configuration config){ |
| 84 | + ExportTask(Configuration config) { |
81 | 85 | this.config = config;
|
82 | 86 | }
|
83 | 87 |
|
84 | 88 | /**
|
85 | 89 | * Handles a request and writes the output in the response stream.
|
86 |
| - * @param request The request object containing the details of the client's request. |
| 90 | + * |
| 91 | + * @param request The request object containing the details of the client's |
| 92 | + * request. |
87 | 93 | * @param response The response object used to send the data back to the client.
|
88 | 94 | */
|
89 | 95 | @Override
|
90 | 96 | public void handle(Request request, Response response) throws BadExportationDataTypeException, IOException,
|
91 |
| - UnknownQualityGateException, OpenXML4JException, XmlException, SonarQubeException, ParseException { |
| 97 | + UnknownQualityGateException, OpenXML4JException, XmlException, SonarQubeException, ParseException, |
| 98 | + AccessDeniedException { |
92 | 99 |
|
93 | 100 | // Get project key
|
94 | 101 | String projectKey = request.getParam(PluginStringManager.getProperty("api.report.args.key")).getValue();
|
95 | 102 |
|
96 | 103 | // Getting stream and change headers
|
97 | 104 | Response.Stream stream = response.stream();
|
98 | 105 |
|
99 |
| - // Get a temp folder |
| 106 | + // Get a safe temporary folder for UNIX or windows. |
100 | 107 |
|
101 | 108 | Path tempDirectory;
|
102 |
| - |
103 |
| - if (SystemUtils.IS_OS_UNIX) { |
104 |
| - FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions |
105 |
| - .asFileAttribute(PosixFilePermissions.fromString("rwx------")); |
106 |
| - Files.createTempFile("cnesreport", ".tmp", attr); |
107 |
| - tempDirectory = Files.createTempDirectory("cnesreport", attr); |
108 |
| - } else { |
109 |
| - File f = Files.createTempFile("cnesreport", ".tmp").toFile(); |
110 |
| - f.setReadable(false); |
111 |
| - f.setWritable(false); |
112 |
| - f.setExecutable(false); |
113 |
| - f.setReadable(true, true); |
114 |
| - f.setWritable(true, true); |
115 |
| - f.setExecutable(true, true); |
116 |
| - tempDirectory = f.toPath(); |
117 |
| - } |
118 |
| - final File outputDirectory = File.createTempFile("cnesreport", Long.toString(System.nanoTime()), tempDirectory.toFile()); |
119 |
| - |
120 |
| - |
121 |
| - // Last line create file instead of folder, we delete file to put folder at the same place later |
122 |
| - Files.delete(outputDirectory.toPath()); |
123 |
| - |
124 |
| - // Start generation, re-using standalone script |
| 109 | + File outputDirectory = null; |
125 | 110 | try {
|
126 |
| - final Request.StringParam pBranch = |
127 |
| - request.getParam(PluginStringManager.getProperty("api.report.args.branch")); |
128 |
| - |
129 |
| - final Request.StringParam pLanguage = |
130 |
| - request.getParam(PluginStringManager.getProperty("api.report.args.language")); |
131 |
| - |
132 |
| - final Request.StringParam pEnableDocx = |
133 |
| - request.getParam(PluginStringManager.getProperty("api.report.args.enableDocx")); |
134 |
| - |
135 |
| - final Request.StringParam pEnableMd = |
136 |
| - request.getParam(PluginStringManager.getProperty("api.report.args.enableMd")); |
137 |
| - |
138 |
| - final Request.StringParam pEnableXlsx = |
139 |
| - request.getParam(PluginStringManager.getProperty("api.report.args.enableXlsx")); |
140 |
| - |
141 |
| - final Request.StringParam pEnableCsv = |
142 |
| - request.getParam(PluginStringManager.getProperty("api.report.args.enableCsv")); |
143 |
| - |
144 |
| - final Request.StringParam pEnableConf = |
145 |
| - request.getParam(PluginStringManager.getProperty("api.report.args.enableConf")); |
146 |
| - |
147 |
| - // Build SonarQube local URL |
148 |
| - String port = config.get("sonar.web.port").orElse(PluginStringManager.getProperty("plugin.defaultPort")); |
149 |
| - String context = config.get("sonar.web.context").orElse(PluginStringManager.getProperty("plugin.defaultContext")); |
150 |
| - String sonarUrl = String.format(PluginStringManager.getProperty("plugin.defaultHost"), port, context); |
151 |
| - |
152 |
| - // Get files templates paths if defined in the decicated SonarQube configuration panel |
153 |
| - String docxPath = config.get("sonar.cnesreport.docx.path").orElse(null); |
154 |
| - String mdPath = config.get("sonar.cnesreport.md.path").orElse(null); |
155 |
| - String xlsxPath = config.get("sonar.cnesreport.xlsx.path").orElse(null); |
156 |
| - |
157 |
| - // create a new client to talk with sonarqube's services |
158 |
| - WsClient wsClient = WsClientFactories.getLocal().newClient(request.localConnector()); |
159 |
| - |
160 |
| - // prepare params for the report generation |
161 |
| - List<String> reportParams = new ArrayList<>(Arrays.asList( |
162 |
| - "report", |
163 |
| - "-o", outputDirectory.getAbsolutePath(), |
164 |
| - "-s", sonarUrl, |
165 |
| - "-p", projectKey, |
166 |
| - "-b", pBranch.isPresent()?pBranch.getValue(): DefaultBranch.getDefaultBranchFromProject(wsClient, projectKey), |
167 |
| - "-a", request.getParam(PluginStringManager.getProperty("api.report.args.author")).getValue(), |
168 |
| - "-t", request.getParam(PluginStringManager.getProperty("api.report.args.token")).getValue(), |
169 |
| - "-l", pLanguage.isPresent()?pLanguage.getValue(): StringManager.getProperty(StringManager.DEFAULT_LANGUAGE) |
170 |
| - )); |
171 |
| - |
172 |
| - // add files templates paths to params if defined |
173 |
| - if (docxPath != null) { |
174 |
| - reportParams.add("-r"); |
175 |
| - reportParams.add(docxPath); |
| 111 | + if (SystemUtils.IS_OS_UNIX) { |
| 112 | + FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions |
| 113 | + .asFileAttribute(PosixFilePermissions.fromString("rwx------")); |
| 114 | + Files.createTempFile("cnesreport", ".tmp", attr); |
| 115 | + tempDirectory = Files.createTempDirectory("cnesreport", attr); |
| 116 | + } else { |
| 117 | + File f = Files.createTempFile("cnesreport", ".tmp").toFile(); |
| 118 | + boolean isOk = true; |
| 119 | + isOk = isOk && f.setReadable(false); |
| 120 | + isOk = isOk && f.setWritable(false); |
| 121 | + isOk = isOk && f.setExecutable(false); |
| 122 | + isOk = isOk && f.setReadable(true, true); |
| 123 | + isOk = isOk && f.setWritable(true, true); |
| 124 | + isOk = isOk && f.setExecutable(true, true); |
| 125 | + tempDirectory = f.toPath(); |
| 126 | + if (!isOk) |
| 127 | + throw new AccessDeniedException(f.toString(), "", "Could not set permissions of temporary file: "); |
176 | 128 | }
|
177 |
| - if (mdPath != null) { |
178 |
| - reportParams.add("-n"); |
179 |
| - reportParams.add(mdPath); |
180 |
| - } |
181 |
| - if (xlsxPath != null) { |
182 |
| - reportParams.add("-x"); |
183 |
| - reportParams.add(xlsxPath); |
184 |
| - } |
185 |
| - |
186 |
| - String pEnableDocxValue = pEnableDocx.getValue(); |
187 |
| - String pEnableMdValue = pEnableMd.getValue(); |
188 |
| - String pEnableXlsxValue = pEnableXlsx.getValue(); |
189 |
| - String pEnableCsvValue = pEnableCsv.getValue(); |
190 |
| - String pEnableConfValue = pEnableConf.getValue(); |
191 |
| - |
192 |
| - // add disable files generation params if requested |
193 |
| - if(pEnableDocxValue != null && (pEnableDocxValue.equals(FALSE) || pEnableDocxValue.equals(NO))) { |
194 |
| - reportParams.add("-w"); |
195 |
| - } |
196 |
| - if(pEnableMdValue != null && (pEnableMdValue.equals(FALSE) || pEnableMdValue.equals(NO))) { |
197 |
| - reportParams.add("-m"); |
198 |
| - } |
199 |
| - if(pEnableXlsxValue != null && (pEnableXlsxValue.equals(FALSE) || pEnableXlsxValue.equals(NO))) { |
200 |
| - reportParams.add("-e"); |
201 |
| - } |
202 |
| - if(pEnableCsvValue != null && (pEnableCsvValue.equals(FALSE) || pEnableCsvValue.equals(NO))) { |
203 |
| - reportParams.add("-f"); |
204 |
| - } |
205 |
| - if(pEnableConfValue != null && (pEnableConfValue.equals(FALSE) || pEnableConfValue.equals(NO))) { |
206 |
| - reportParams.add("-c"); |
| 129 | + outputDirectory = File.createTempFile("cnesreport", Long.toString(System.nanoTime()), |
| 130 | + tempDirectory.toFile()); |
| 131 | + } catch (AccessDeniedException e) { |
| 132 | + Logger logger = Logger.getLogger(ExportTask.class.getName()); |
| 133 | + logger.log(Level.SEVERE, "{0}{1}", new Object[] { e.getReason(), e.getFile() }); |
| 134 | + } |
| 135 | + // Last line create file instead of folder, we delete file to put folder at the |
| 136 | + // same place later |
| 137 | + if (outputDirectory != null) { |
| 138 | + Files.delete(outputDirectory.toPath()); |
| 139 | + |
| 140 | + // Start generation, re-using standalone script |
| 141 | + try { |
| 142 | + final Request.StringParam pBranch = request |
| 143 | + .getParam(PluginStringManager.getProperty("api.report.args.branch")); |
| 144 | + |
| 145 | + final Request.StringParam pLanguage = request |
| 146 | + .getParam(PluginStringManager.getProperty("api.report.args.language")); |
| 147 | + |
| 148 | + final Request.StringParam pEnableDocx = request |
| 149 | + .getParam(PluginStringManager.getProperty("api.report.args.enableDocx")); |
| 150 | + |
| 151 | + final Request.StringParam pEnableMd = request |
| 152 | + .getParam(PluginStringManager.getProperty("api.report.args.enableMd")); |
| 153 | + |
| 154 | + final Request.StringParam pEnableXlsx = request |
| 155 | + .getParam(PluginStringManager.getProperty("api.report.args.enableXlsx")); |
| 156 | + |
| 157 | + final Request.StringParam pEnableCsv = request |
| 158 | + .getParam(PluginStringManager.getProperty("api.report.args.enableCsv")); |
| 159 | + |
| 160 | + final Request.StringParam pEnableConf = request |
| 161 | + .getParam(PluginStringManager.getProperty("api.report.args.enableConf")); |
| 162 | + |
| 163 | + // Build SonarQube local URL |
| 164 | + String port = config.get("sonar.web.port") |
| 165 | + .orElse(PluginStringManager.getProperty("plugin.defaultPort")); |
| 166 | + String context = config.get("sonar.web.context") |
| 167 | + .orElse(PluginStringManager.getProperty("plugin.defaultContext")); |
| 168 | + String sonarUrl = String.format(PluginStringManager.getProperty("plugin.defaultHost"), port, context); |
| 169 | + |
| 170 | + // Get files templates paths if defined in the decicated SonarQube configuration |
| 171 | + // panel |
| 172 | + String docxPath = config.get("sonar.cnesreport.docx.path").orElse(null); |
| 173 | + String mdPath = config.get("sonar.cnesreport.md.path").orElse(null); |
| 174 | + String xlsxPath = config.get("sonar.cnesreport.xlsx.path").orElse(null); |
| 175 | + |
| 176 | + // create a new client to talk with sonarqube's services |
| 177 | + WsClient wsClient = WsClientFactories.getLocal().newClient(request.localConnector()); |
| 178 | + |
| 179 | + // prepare params for the report generation |
| 180 | + List<String> reportParams = new ArrayList<>(Arrays.asList( |
| 181 | + "report", |
| 182 | + "-o", outputDirectory.getAbsolutePath(), |
| 183 | + "-s", sonarUrl, |
| 184 | + "-p", projectKey, |
| 185 | + "-b", |
| 186 | + pBranch.isPresent() ? pBranch.getValue() |
| 187 | + : DefaultBranch.getDefaultBranchFromProject(wsClient, projectKey), |
| 188 | + "-a", request.getParam(PluginStringManager.getProperty("api.report.args.author")).getValue(), |
| 189 | + "-t", request.getParam(PluginStringManager.getProperty("api.report.args.token")).getValue(), |
| 190 | + "-l", pLanguage.isPresent() ? pLanguage.getValue() |
| 191 | + : StringManager.getProperty(StringManager.DEFAULT_LANGUAGE))); |
| 192 | + |
| 193 | + // add files templates paths to params if defined |
| 194 | + if (docxPath != null) { |
| 195 | + reportParams.add("-r"); |
| 196 | + reportParams.add(docxPath); |
| 197 | + } |
| 198 | + if (mdPath != null) { |
| 199 | + reportParams.add("-n"); |
| 200 | + reportParams.add(mdPath); |
| 201 | + } |
| 202 | + if (xlsxPath != null) { |
| 203 | + reportParams.add("-x"); |
| 204 | + reportParams.add(xlsxPath); |
| 205 | + } |
| 206 | + |
| 207 | + String pEnableDocxValue = pEnableDocx.getValue(); |
| 208 | + String pEnableMdValue = pEnableMd.getValue(); |
| 209 | + String pEnableXlsxValue = pEnableXlsx.getValue(); |
| 210 | + String pEnableCsvValue = pEnableCsv.getValue(); |
| 211 | + String pEnableConfValue = pEnableConf.getValue(); |
| 212 | + |
| 213 | + // add disable files generation params if requested |
| 214 | + if (pEnableDocxValue != null && (pEnableDocxValue.equals(FALSE) || pEnableDocxValue.equals(NO))) { |
| 215 | + reportParams.add("-w"); |
| 216 | + } |
| 217 | + if (pEnableMdValue != null && (pEnableMdValue.equals(FALSE) || pEnableMdValue.equals(NO))) { |
| 218 | + reportParams.add("-m"); |
| 219 | + } |
| 220 | + if (pEnableXlsxValue != null && (pEnableXlsxValue.equals(FALSE) || pEnableXlsxValue.equals(NO))) { |
| 221 | + reportParams.add("-e"); |
| 222 | + } |
| 223 | + if (pEnableCsvValue != null && (pEnableCsvValue.equals(FALSE) || pEnableCsvValue.equals(NO))) { |
| 224 | + reportParams.add("-f"); |
| 225 | + } |
| 226 | + if (pEnableConfValue != null && (pEnableConfValue.equals(FALSE) || pEnableConfValue.equals(NO))) { |
| 227 | + reportParams.add("-c"); |
| 228 | + } |
| 229 | + |
| 230 | + // Execute report generation |
| 231 | + ReportCommandLine.execute(reportParams.toArray(new String[reportParams.size()])); |
| 232 | + |
| 233 | + stream.setMediaType("application/zip"); |
| 234 | + String filename = ReportFactory.formatFilename("zip.report.output", "", "", projectKey); |
| 235 | + response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + '"'); |
| 236 | + |
| 237 | + // generate zip output and send it |
| 238 | + ZipFolder.pack(outputDirectory.getAbsolutePath(), outputDirectory.getAbsolutePath() + ".zip"); |
| 239 | + File zip = new File(outputDirectory.getAbsolutePath() + ".zip"); |
| 240 | + FileUtils.copyFile(zip, stream.output()); |
| 241 | + Files.deleteIfExists(zip.toPath()); |
| 242 | + } catch (BadSonarQubeRequestException e) { |
| 243 | + response.stream().setMediaType(MediaTypes.JSON); |
| 244 | + try ( |
| 245 | + OutputStreamWriter writer = new OutputStreamWriter(response.stream().output(), |
| 246 | + StandardCharsets.UTF_8); |
| 247 | + JsonWriter jsonWriter = new JsonWriter(writer);) { |
| 248 | + jsonWriter.beginObject(); |
| 249 | + jsonWriter.name("error").value(PluginStringManager.getProperty("api.tokenerror")); |
| 250 | + jsonWriter.endObject(); |
| 251 | + jsonWriter.flush(); |
| 252 | + } |
207 | 253 | }
|
208 | 254 |
|
209 |
| - // Execute report generation |
210 |
| - ReportCommandLine.execute(reportParams.toArray(new String[reportParams.size()])); |
211 |
| - |
212 |
| - stream.setMediaType("application/zip"); |
213 |
| - String filename = ReportFactory.formatFilename("zip.report.output", "", "", projectKey); |
214 |
| - response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + '"'); |
215 |
| - |
216 |
| - |
217 |
| - // generate zip output and send it |
218 |
| - ZipFolder.pack(outputDirectory.getAbsolutePath(), outputDirectory.getAbsolutePath() + ".zip"); |
219 |
| - File zip = new File(outputDirectory.getAbsolutePath() + ".zip"); |
220 |
| - FileUtils.copyFile(zip, stream.output()); |
221 |
| - Files.deleteIfExists(zip.toPath()); |
222 |
| - } catch (BadSonarQubeRequestException e) { |
223 |
| - response.stream().setMediaType(MediaTypes.JSON); |
224 |
| - try ( |
225 |
| - OutputStreamWriter writer = new OutputStreamWriter(response.stream().output(), StandardCharsets.UTF_8); |
226 |
| - JsonWriter jsonWriter = new JsonWriter(writer); |
227 |
| - ) { |
228 |
| - jsonWriter.beginObject(); |
229 |
| - jsonWriter.name("error").value(PluginStringManager.getProperty("api.tokenerror")); |
230 |
| - jsonWriter.endObject(); |
231 |
| - jsonWriter.flush(); |
232 |
| - } |
| 255 | + FileTools.deleteFolder(outputDirectory); |
233 | 256 | }
|
234 |
| - |
235 |
| - FileTools.deleteFolder(outputDirectory); |
236 | 257 | }
|
237 | 258 | }
|
0 commit comments