1   package com.trendmicro.grid.acl.l0;
2   
3   import com.trendmicro.grid.acl.l0.datatypes.*;
4   import net.sf.tinyjee.util.Hex;
5   import org.springframework.stereotype.Service;
6   
7   import javax.annotation.PostConstruct;
8   import javax.annotation.Resource;
9   import javax.ws.rs.*;
10  import java.util.List;
11  import java.util.Set;
12  
13  /**
14   * Implements a REST styled interface on top of the SOAP api using JAX-RS
15   *
16   * @author Juergen_Kellerer, 2010-04-30
17   * @version 1.0
18   */
19  @Service
20  //@PublicRequestContext - Not required as injected instance is already wrapped by an AspectJ proxy.
21  @Path("/packages")
22  @Produces({"application/xml", "application/json"})
23  public class PublicPackageRestService implements Level0RestService {
24  
25  	@Resource
26  	Set<PublicPackageService> services;
27  	PublicPackageService packageService;
28  
29  	@PostConstruct
30  	void init() {
31  		// Selecting the public implementation only.
32  		for (PublicPackageService service : services) {
33  			if (!(service instanceof PackageService)) packageService = service;
34  		}
35  	}
36  
37  	private static NamedFileIdentifierListPage convertNamedFileIdentifierListPage(NamedFileIdentifierListPage name) {
38  		if (name != null)
39  			return new NamedFileIdentifierListPage(name.getPageNumber(), name.isLastPage(), name.getElements());
40  		else
41  			return null;
42  	}
43  
44  	public static PackageInformation convertJpaPackageInformation(PackageInformation pf) {
45  		if (pf != null)
46  			return new PackageInformation(pf.getName(), pf.getDisplayName(), pf.getFamilyName(), pf.getVendorName(),
47  					(String[]) pf.getTags().toArray(), pf.getPackageFileInformation());
48  		else
49  			return null;
50  	}
51  
52  	public static PackageDetails convertJpaPackageDetails(PackageDetails pd) {
53  		if (pd != null)
54  			return new PackageDetails(pd.getPackageFamily(), pd.getPackageInformation(), pd.getMetadata(), pd.getFileMetadata());
55  		else
56  			return null;
57  	}
58  
59  	/**
60  	 * Returns all known vendor names.
61  	 *
62  	 * @param pageNumber The number of the list page to return, starting from 0 for the first chunk.
63  	 * @return A page of known vendor names or 'null' if no page exists under the given number.
64  	 * @throws AuthenticationException In case of this service requires authentication and the current user session
65  	 *                                 is not authenticated or doesn't have the right to access the service.
66  	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES
67  	 */
68  	@GET
69  	@Path("/vendorNames/{pageNumber}")
70  	public NameListPage getVendorNames(
71  			@DefaultValue("0") @PathParam("pageNumber") int pageNumber) throws AuthenticationException {
72  		return packageService.getVendorNames(pageNumber);
73  	}
74  
75  	/**
76  	 * Returns the displayname for the given reference name.
77  	 *
78  	 * @param vendorName the name of the vendor to return the display name for.
79  	 * @return a collection of displaynames for the given names, never 'null'.
80  	 * @throws AuthenticationException In case of this service requires authentication and the current user session
81  	 *                                 is not authenticated or doesn't have the right to access the service.
82  	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES
83  	 */
84  	@GET
85  	@Produces("text/plain")
86  	@Path("/vendorDisplayName/{name}")
87  	public String getVendorDisplayName(
88  			@PathParam("name") String vendorName) throws AuthenticationException {
89  		RestUtil.assertIsNotCrossSiteScriptingVulnerable(vendorName);
90  		return packageService.getVendorDisplayNames(BatchCollection.of(vendorName)).iterator().next();
91  	}
92  
93  	/**
94  	 * Returns all known package family names.
95  	 *
96  	 * @param pageNumber The number of the list page to return, starting from 0 for the first chunk.
97  	 * @return A page of known package family names or 'null' if no page exists under the given number.
98  	 * @throws AuthenticationException In case of this service requires authentication and the current user session
99  	 *                                 is not authenticated or doesn't have the right to access the service.
100 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES
101 	 */
102 	@GET
103 	@Path("/packageFamilyNames/{pageNumber}")
104 	public NameListPage getPackageFamilyNames(
105 			@DefaultValue("0") @PathParam("pageNumber") int pageNumber) throws AuthenticationException {
106 		return packageService.getPackageFamilyNames(pageNumber);
107 	}
108 
109 	/**
110 	 * Returns the displayname for the given reference name.
111 	 *
112 	 * @param packageFamilyName the name of the package family to return the display name for.
113 	 * @return the displayname for the given name, never 'null'.
114 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
115 	 *                                 is not authenticated or doesn't have the right to access the service.
116 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES
117 	 */
118 	@GET
119 	@Produces("text/plain")
120 	@Path("/packageFamilyDisplayName/{packageFamilyName}")
121 	public String getPackageFamilyDisplayName(
122 			@PathParam("packageFamilyName") String packageFamilyName) throws AuthenticationException {
123 		RestUtil.assertIsNotCrossSiteScriptingVulnerable(packageFamilyName);
124 		return packageService.getPackageFamilyDisplayNames(BatchCollection.of(packageFamilyName)).iterator().next();
125 	}
126 
127 	/**
128 	 * Returns all known package family names for the given vendor.
129 	 *
130 	 * @param vendorName the name of the vendor to query package families from.
131 	 * @param pageNumber The number of the list page to return, starting from 0 for the first chunk.
132 	 * @return A page of known package family names or 'null' if no page exists under the given number.
133 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
134 	 *                                 is not authenticated or doesn't have the right to access the service.
135 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES
136 	 */
137 	@GET
138 	@Path("/packageFamilyNamesForVendor/{vendorName}/{pageNumber}")
139 	public NameListPage getPackageFamilyNamesForVendor(
140 			@PathParam("vendorName") String vendorName,
141 			@DefaultValue("0") @PathParam("pageNumber") int pageNumber) throws AuthenticationException {
142 		return packageService.getPackageFamilyNamesForVendor(vendorName, pageNumber);
143 	}
144 
145 	/**
146 	 * Returns all package names that are members of the given package family.
147 	 *
148 	 * @param packageFamilyName the name of the package family to query package names from.
149 	 * @param pageNumber        The number of the list page to return, starting from 0 for the first chunk.
150 	 * @return A page of package names or 'null' if no page exists under the given number.
151 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
152 	 *                                 is not authenticated or doesn't have the right to access the service.
153 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES
154 	 */
155 	@GET
156 	@Path("/packageNamesInFamily/{packageFamilyName}/{pageNumber}")
157 	public NameListPage getPackageNamesInFamily(
158 			@PathParam("packageFamilyName") String packageFamilyName,
159 			@DefaultValue("0") @PathParam("pageNumber") int pageNumber) throws AuthenticationException {
160 		return packageService.getPackageNamesInFamily(packageFamilyName, pageNumber);
161 	}
162 
163 	/**
164 	 * Returns the displayname for the given reference name.
165 	 *
166 	 * @param packageName the name of the package to return the display name for.
167 	 * @return the displayname for the given name, never 'null'.
168 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
169 	 *                                 is not authenticated or doesn't have the right to access the service.
170 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES
171 	 */
172 	@GET
173 	@Produces("text/plain")
174 	@Path("/packageDisplayName/{name}")
175 	public String getPackageDisplayName(
176 			@PathParam("name") String packageName) throws AuthenticationException {
177 		RestUtil.assertIsNotCrossSiteScriptingVulnerable(packageName);
178 		return packageService.getPackageDisplayNames(BatchCollection.of(packageName)).iterator().next();
179 	}
180 
181 	/**
182 	 * Returns true if the given package is tagged with the specified tags.
183 	 *
184 	 * @param sha1OrMd5Hash The package file to verify.
185 	 * @param tags          The tags to check against.
186 	 * @return 'true' if the tags apply to the package, 'false' if not, 'null' (HTTP 204 No Content)
187 	 *         if the package is unknown or the file id references a ordinary file not a package.
188 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
189 	 *                                 is not authenticated or doesn't have the right to access the service.
190 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES
191 	 */
192 	@GET
193 	@Produces("text/plain")
194 	@Path("/isPackageTaggedWithById/{sha1OrMd5}")
195 	public String isPackageTaggedWithById(
196 			@PathParam("sha1OrMd5") String sha1OrMd5Hash,
197 			@QueryParam("tag") List<String> tags) throws AuthenticationException {
198 		IsTrueResult result = packageService.isPackageTaggedWithAllById(
199 				new FileIdentifier(Hex.decode(sha1OrMd5Hash)), tags.toArray(new String[tags.size()]));
200 		return result == IsTrueResult.NotKnown ? null : result.toString();
201 	}
202 
203 	/**
204 	 * Returns true if the given package is tagged with the specified tags.
205 	 *
206 	 * @param packageName The package to verify.
207 	 * @param tags        The tags to check against.
208 	 * @return 'true' if the tags apply to the package, 'false' if not, 'null' (HTTP 204 No Content)
209 	 *         if the package is unknown.
210 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
211 	 *                                 is not authenticated or doesn't have the right to access the service.
212 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES
213 	 */
214 	@GET
215 	@Produces("text/plain")
216 	@Path("/isPackageTaggedWithByName/{packageName}")
217 	public String isPackageTaggedWithByName(
218 			@PathParam("packageName") String packageName,
219 			@QueryParam("tag") List<String> tags) throws AuthenticationException {
220 		IsTrueResult result = packageService.isPackageTaggedWithAllByName(
221 				packageName, tags.toArray(new String[tags.size()]));
222 		return result == IsTrueResult.NotKnown ? null : result.toString();
223 	}
224 
225 	/**
226 	 * Returns all known files that are tagged with the given list of tags.
227 	 *
228 	 * @param tags       The tags to get the files for.
229 	 * @param pageNumber The number of the list page to return, starting from 0 for the first chunk.
230 	 * @return A page of package names for the packages tagged with the given tags or
231 	 *         'null' if no page exists under the given number.
232 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
233 	 *                                 is not authenticated or doesn't have the right to access the service.
234 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES, ROLE_RUN_TAG_MATCHING_QUERIES
235 	 */
236 	@GET
237 	@Path("/packageNamesTaggedWith/{pageNumber}")
238 	public NameListPage getPackageNamesTaggedWith(
239 			@DefaultValue("0") @PathParam("pageNumber") int pageNumber,
240 			@QueryParam("tag") List<String> tags) throws AuthenticationException {
241 		return packageService.getPackageNamesTaggedWith(tags.toArray(new String[tags.size()]), pageNumber);
242 	}
243 
244 	/**
245 	 * Returns all known packages that are matched by the given tag expression.
246 	 *
247 	 * @param tagExpression        An expression following the tag query grammar used to identify packages.
248 	 * @param tagExpressionVersion The version of the expression (the most recent version is assumed if ommitted).
249 	 * @param pageNumber           The number of the list page to return, starting from 0 for the first chunk.
250 	 * @return A page of package names for the packages, matching the given expression or
251 	 *         'null' if no page exists under the given number.
252 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
253 	 *                                 is not authenticated or doesn't have the right to access the service.
254 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES, ROLE_RUN_TAG_MATCHING_QUERIES
255 	 */
256 	@GET
257 	@Path("/matchingPackageNames/{pageNumber}")
258 	public NameListPage getMatchingPackageNames(
259 			@DefaultValue("0") @PathParam("pageNumber") int pageNumber,
260 			@QueryParam("tagQueryExpression") String tagExpression,
261 			@DefaultValue("") @QueryParam("tagQueryExpressionVersion") String tagExpressionVersion) throws AuthenticationException {
262 		return packageService.getMatchingPackageNames(tagExpression, tagExpressionVersion, pageNumber);
263 	}
264 
265 	/**
266 	 * Returns the names of all packages that reference the given file directly.
267 	 * <p/>
268 	 * A package references a file if the file is a direct child of the package.
269 	 *
270 	 * @param sha1OrMd5Hash The file to return the referencing package names for.
271 	 * @param pageNumber    The number of the list page to return, starting from 0 for the first page.
272 	 * @return A page of package names or 'null' if no page exists under the given number.
273 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
274 	 *                                 is not authenticated or doesn't have the right to access the service.
275 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES, ROLE_RUN_COMPLEX_QUERIES
276 	 */
277 	@GET
278 	@Path("/referencingPackageNamesById/{sha1OrMd5}/{pageNumber}")
279 	public NameListPage getReferencingPackageNamesById(
280 			@PathParam("sha1OrMd5") String sha1OrMd5Hash,
281 			@DefaultValue("0") @PathParam("pageNumber") int pageNumber) throws AuthenticationException {
282 		return packageService.getReferencingPackageNamesById(new FileIdentifier(sha1OrMd5Hash), pageNumber);
283 	}
284 
285 	/**
286 	 * Returns the names of all packages that reference the given package directly.
287 	 *
288 	 * @param packageName The package name to return the names of referencing packages.
289 	 * @param pageNumber  The number of the list page to return, starting from 0 for the first page.
290 	 * @return A page of package names or 'null' if no page exists under the given name or pageNumber.
291 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
292 	 *                                 is not authenticated or doesn't have the right to access the service.
293 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES, ROLE_RUN_COMPLEX_QUERIES
294 	 */
295 	@GET
296 	@Path("/referencingPackageNames/{packageName}/{pageNumber}")
297 	public NameListPage getReferencingPackageNames(
298 			@PathParam("packageName") String packageName,
299 			@DefaultValue("0") @PathParam("pageNumber") int pageNumber) throws AuthenticationException {
300 		return packageService.getReferencingPackageNames(packageName, pageNumber);
301 	}
302 
303 	/**
304 	 * Returns the ids of all files contained inside the given package.
305 	 *
306 	 * @param sha1OrMd5Hash The id of the package file to look for its children.
307 	 * @param pageNumber    The number of the list page to return, starting from 0 for the first page.
308 	 * @return the ids of all files contained inside the given package.
309 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
310 	 *                                 is not authenticated or doesn't have the right to access the service.
311 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES, ROLE_RUN_COMPLEX_QUERIES
312 	 */
313 	@GET
314 	@Path("/filesContainedInPackageById/{sha1OrMd5}/{pageNumber}")
315 	public NamedFileIdentifierListPage getFilesContainedInPackageById(
316 			@PathParam("sha1OrMd5") String sha1OrMd5Hash,
317 			@DefaultValue("0") @PathParam("pageNumber") int pageNumber) throws AuthenticationException {
318 		return convertNamedFileIdentifierListPage(packageService.getFilesContainedInPackageById(new FileIdentifier(sha1OrMd5Hash), pageNumber));
319 	}
320 
321 	/**
322 	 * Returns the ids of all files contained inside the given package.
323 	 *
324 	 * @param packageName The name of the package to look for its children.
325 	 * @param pageNumber  The number of the list page to return, starting from 0 for the first page.
326 	 * @return the ids of all files contained inside the given package.
327 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
328 	 *                                 is not authenticated or doesn't have the right to access the service.
329 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES, ROLE_RUN_COMPLEX_QUERIES
330 	 */
331 	@GET
332 	@Path("/filesContainedInPackageByName/{packageName}/{pageNumber}")
333 	public NamedFileIdentifierListPage getFilesContainedInPackageByName(
334 			@PathParam("packageName") String packageName,
335 			@DefaultValue("0") @PathParam("pageNumber") int pageNumber) throws AuthenticationException {
336 		return convertNamedFileIdentifierListPage(packageService.getFilesContainedInPackageByName(packageName, pageNumber));
337 	}
338 
339 	/**
340 	 * Returns the names of all packages contained inside the given package.
341 	 *
342 	 * @param sha1OrMd5Hash The id of the package file to look for its children.
343 	 * @param pageNumber    The number of the list page to return, starting from 0 for the first page.
344 	 * @return the names of all packages contained inside the given package.
345 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
346 	 *                                 is not authenticated or doesn't have the right to access the service.
347 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES, ROLE_RUN_COMPLEX_QUERIES
348 	 */
349 	@GET
350 	@Path("/packagesContainedInPackageById/{sha1OrMd5}/{pageNumber}")
351 	public NameListPage getPackagesContainedInPackageById(
352 			@PathParam("sha1OrMd5") String sha1OrMd5Hash,
353 			@DefaultValue("0") @PathParam("pageNumber") int pageNumber) throws AuthenticationException {
354 		return packageService.getPackagesContainedInPackageById(new FileIdentifier(sha1OrMd5Hash), pageNumber);
355 	}
356 
357 	/**
358 	 * Returns the names of all packages contained inside the given package.
359 	 *
360 	 * @param packageName The name of the package to look for its children.
361 	 * @param pageNumber  The number of the list page to return, starting from 0 for the first page.
362 	 * @return the names of all packages contained inside the given package.
363 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
364 	 *                                 is not authenticated or doesn't have the right to access the service.
365 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES, ROLE_RUN_COMPLEX_QUERIES
366 	 */
367 	@GET
368 	@Path("/packagesContainedInPackageByName/{packageName}/{pageNumber}")
369 	public NameListPage getPackagesContainedInPackageByName(
370 			@PathParam("packageName") String packageName,
371 			@DefaultValue("0") @PathParam("pageNumber") int pageNumber) throws AuthenticationException {
372 		return packageService.getPackagesContainedInPackageByName(packageName, pageNumber);
373 	}
374 
375 	/**
376 	 * Returns the package information of the given package.
377 	 *
378 	 * @param sha1OrMd5Hash The id of the package file to look for.
379 	 * @return the package information of the given package or 'null' if
380 	 *         no package exists under the specified arguments.
381 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
382 	 *                                 is not authenticated or doesn't have the right to access the service.
383 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES
384 	 * @dim.example.response com.trendmicro.grid.acl.l0.datatypes.TestContext.newFinalProcessPackageDataSet().getProcessedPackage().getPackageInformation()
385 	 */
386 	@GET
387 	@Path("/packageInformationById/{sha1OrMd5}")
388 	public PackageInformation getPackageInformationById(
389 			@PathParam("sha1OrMd5") String sha1OrMd5Hash) throws AuthenticationException {
390 		return convertJpaPackageInformation(packageService.getPackageInformationById(new FileIdentifier(sha1OrMd5Hash)));
391 	}
392 
393 	/**
394 	 * Returns the package information of the given package.
395 	 *
396 	 * @param packageName The name of the package to look for.
397 	 * @return the package information of the given package or 'null' if
398 	 *         no package exists under the specified arguments.
399 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
400 	 *                                 is not authenticated or doesn't have the right to access the service.
401 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES
402 	 * @dim.example.response com.trendmicro.grid.acl.l0.datatypes.TestContext.newFinalProcessPackageDataSet().getProcessedPackage().getPackageInformation()
403 	 */
404 	@GET
405 	@Path("/packageInformationByName/{packageName}")
406 	public PackageInformation getPackageInformationByName(
407 			@PathParam("packageName") String packageName) throws AuthenticationException {
408 		return convertJpaPackageInformation(packageService.getPackageInformationByName(packageName));
409 	}
410 
411 	/**
412 	 * Returns the package details of the given package.
413 	 *
414 	 * @param sha1OrMd5Hash The id of the package file to look for.
415 	 * @return the package details of the given package or 'null' if
416 	 *         no package exists under the specified arguments.
417 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
418 	 *                                 is not authenticated or doesn't have the right to access the service.
419 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES ROLE_ACCESS_DETAILS
420 	 * @dim.example.response com.trendmicro.grid.acl.l0.datatypes.TestContext.newFinalProcessPackageDataSet().getProcessedPackage()
421 	 */
422 	@GET
423 	@Path("/packageDetailsById/{sha1OrMd5}")
424 	public PackageDetails getPackageDetailsById(
425 			@PathParam("sha1OrMd5") String sha1OrMd5Hash) throws AuthenticationException {
426 		return convertJpaPackageDetails(packageService.getPackageDetailsById(new FileIdentifier(sha1OrMd5Hash)));
427 	}
428 
429 	/**
430 	 * Returns the package details of the given package.
431 	 *
432 	 * @param packageName The name of the package to look for.
433 	 * @return the package details of the given package or 'null' if
434 	 *         no package exists under the specified arguments.
435 	 * @throws AuthenticationException In case of this service requires authentication and the current user session
436 	 *                                 is not authenticated or doesn't have the right to access the service.
437 	 * @RequiredRoles ROLE_RUN_PACKAGE_QUERIES ROLE_ACCESS_DETAILS
438 	 * @dim.example.response com.trendmicro.grid.acl.l0.datatypes.TestContext.newFinalProcessPackageDataSet().getProcessedPackage()
439 	 */
440 	@GET
441 	@Path("/packageDetailsByName/{packageName}")
442 	public PackageDetails getPackageDetailsByName(
443 			@PathParam("packageName") String packageName) throws AuthenticationException {
444 		return convertJpaPackageDetails(packageService.getPackageDetailsByName(packageName));
445 	}
446 }