Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rescan #169

Merged
merged 21 commits into from
Sep 25, 2024
Merged

Rescan #169

merged 21 commits into from
Sep 25, 2024

Conversation

vishalhcl-5960
Copy link

@vishalhcl-5960 vishalhcl-5960 commented Aug 20, 2024

Rescan implementation for the SAST scan
Note: Validation of the scanId is pending from our side & will add a new method in the serviceUtil class for it.

Kripajoy Melitpalathingal added 3 commits August 19, 2024 12:28
@CLAassistant
Copy link

CLAassistant commented Aug 20, 2024

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ vishalhcl-5960
❌ Kripajoy Melitpalathingal


Kripajoy Melitpalathingal seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@@ -96,7 +96,56 @@ public String createAndExecuteScan(String type, Map<String, String> params) {
}
return null;
}

@Override

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is an exact copy of createAndExecuteScan() with just a few minor changes (the url and the constant used for getting the id). This should be refactored to put all of the common logic into a private method, so the 2 public methods can simply call that private method, passing in the minor differences.

Copy link
Author

@vishalhcl-5960 vishalhcl-5960 Sep 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, We have created a new private common method executeScan() which has been called from both create&ExecuteScan() & rescan() method.

JSONObject json = (JSONObject) response.getResponseBodyAsJSON();

if (status == HttpsURLConnection.HTTP_CREATED || status == HttpsURLConnection.HTTP_OK) {
String scanId = json.getString(SCAN_ID);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for getting the scan id and returning it? Since this is a rescan, the scan id is already known. I think it makes more sense to return the execution id.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, Now we are fetching the executionId if the user go for rescanning.

submitScan();

if (params.containsKey(CoreConstants.SCAN_ID)) {
params.put(CoreConstants.FILE_ID, fileId);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both the "if" and "else" branches make the same call to add the file id to the params. That should be done once outside of the conditional rather than repeating the code.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keys are different. For scan, the key is ApplicationFileId, while for a rescan, it's FileId.

if(getScanId() == null)
throw new ScannerException(Messages.getMessage(ERROR_SUBMITTING_IRX));
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This same method will be needed for DAST rescans, as well. Assuming it will be the same implementation, this should be moved to the ASoCScan class, so the logic can be reused.


submitScan();

if (params.containsKey(CoreConstants.SCAN_ID)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since other scanners will need to do this same check, I suggest doing this in the ASoCScan constructor. It can set a boolean member variable in that class (e.g. m_isRescan) that can also have a getter (e.g. isRescan()). You could then call isRescan() to see if you should call the specific scanner's submitScan() method or the general submitRescan() method on the ASoCScan class (see comment below).

Copy link
Author

@vishalhcl-5960 vishalhcl-5960 Sep 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have created a new method called submitRescan() in the ASoCScan class which has been called from the analyzeIR() method of the SASTscan class.
"protected void submitRescan() {
setExecutionId(getServiceProvider().rescan(getScanId(),getProperties()));
}
"

message.created.scan=Successfully submitted {0} scan for analysis. Scan ID: {1}
message.scan.overview={0} scan overview: {1}
message.created.scan=Successfully submitted {0} scan for analysis. Scan ID:
message.scan.overview={0} scan overview:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for removing the {1} at the end of each of these strings? It looks like the calls that use them still provide information for the 2nd parameter.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are assigning the 2nd value in a common method ("executeScan") used for createAndExecuteScan() & rescan(). So, for new scan the 2nd value will be scanId while for the rescanning it would be executionId.

message.created.scan=Successfully submitted {0} scan for analysis. Scan ID:
message.scan.overview={0} scan overview:
message.rescan= Successfully submitted rescan for analysis. Execution ID:
message.rescan.overview= Rescan overview:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are message.rescan and message.rescan.overview used anywhere? I don't see them referenced in this PR.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -57,6 +58,16 @@ public CloudResultsProvider(String scanId, String type, IScanServiceProvider pro
m_reportFormat = DEFAULT_REPORT_FORMAT;
}

public CloudResultsProvider(String scanId, String executionId, String type, IScanServiceProvider provider, IProgress progress) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To limit duplication of code, it would be good to have the original constructor that does not take an executionId call this one directly. E.g.:
this(scanId, null, type, provider, progress);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, sure.

}

public Boolean isRescan() {
return m_properties.containsKey(CoreConstants.SCAN_ID);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a setter function setRescan(boolean rescan) that sets the member variable m_rescan, but the getter function isRescan() checks for a key in m_properties. These should be made consistent, so they both work with the member variable, which can be set in the constructor based on m_properties.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a getter method & assigning the m_rescan value in the constructor based on the m_properties. Also, removed the isRescan() method.

@@ -25,6 +25,8 @@ public abstract class ASoCScan implements IScan, ScanConstants, Serializable {

private String m_target;
private String m_scanId;
private String m_executionId;
private Boolean m_rescan;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to use the class Boolean as opposed to the primitive type boolean?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed the "m_rescan" type to boolean.

*/
public HttpResponse put(String url, Map<String, String> headerProperties, Map<String, String> parameters)
throws IOException, JSONException {
JSONObject params = new JSONObject(parameters);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of creating the params JSONObject instead of just working with the parameters Map?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is because we are putting the boolean value if the key value equals to "true"/"false", Map properties doesn't allow me to put boolean as well as string values in the same map.
For v4 APIs, we can't assign a string value for boolean taking parameters.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the creation of objectMap, but params is never written to. It's only read. So we should be able to just read from the Map parameters, as opposed to creating the JSONObject params from it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, Made the changes accordingly.

*/
public HttpResponse put(String url, Map<String, String> headerProperties, Map<String, String> parameters)
throws IOException, JSONException {
JSONObject params = new JSONObject(parameters);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the creation of objectMap, but params is never written to. It's only read. So we should be able to just read from the Map parameters, as opposed to creating the JSONObject params from it.

for (Object key : params.keySet()) {
if (params.get(key) != null){
String value = params.get(key).toString();
if (value != null) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 175 does a null check on params.get(key). The value is then put into the variable "value" and we do another null check of it on line 177, which is redundent.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the 2nd null check.

@vishalhcl-5960 vishalhcl-5960 merged commit 98db010 into master Sep 25, 2024
1 of 2 checks passed
@vishalhcl-5960 vishalhcl-5960 deleted the Rescan branch September 25, 2024 11:11
@kripajoym kripajoym restored the Rescan branch October 1, 2024 09:26
@kripajoym kripajoym deleted the Rescan branch October 1, 2024 09:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants