Skip to content

Adding new values to extensible list-type custom tags in SSC issue update during remediation#994

Open
jmadhur87 wants to merge 2 commits into
fortify:dev/v3.xfrom
jmadhur87:mjain/959
Open

Adding new values to extensible list-type custom tags in SSC issue update during remediation#994
jmadhur87 wants to merge 2 commits into
fortify:dev/v3.xfrom
jmadhur87:mjain/959

Conversation

@jmadhur87

Copy link
Copy Markdown
Contributor

This PR enhances the SSC issue update command used during remediation to support adding new values to custom tags of type list when the tag is marked as extensible=true using new option --extend.
ssc issue update --extend

While verifying for ssc tag update command, found that value updates for non-LIST custom tags (TEXT, DECIMAL, DATE) were incorrectly reported as Updated in fcli, even though SSC made no change.
Added explicit validation and a clear error message so these unsupported value operations now fail fast instead of showing a false success.

Fix: Support adding new values to extensible list-type custom tags in SSC issue update during remediation(#959 )

@SangameshV SangameshV left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also please check whether the SSCCustomTagDescriptor requires extensible field

SSCCustomTagDescriptor desc = getDescriptorByCustomTagSpec(tagGuid, true);
ObjectNode body = (ObjectNode) desc.asJsonNode().deepCopy();
LinkedHashMap<String, ObjectNode> valueMap = buildValueMap(body);
if (!valueMap.containsKey(newValue)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A case mismatch in the keys can create duplicate list values in SSC. The buildValueMap method returns the listValues map with lowercase keys, and the containsKey check always returns false due to the case difference, thereby allowing duplicate list values to be added to the overall list.

Note: The same bug would cascade into extendTagWithValue, which caches the returned newLookupIndex in tagInfo.getValueList() a wrong index would be reused for all subsequent issues in the same command run.

}

private int extendTagWithValue(CustomTagInfo tagInfo, String newValue) {
int newIndex = new SSCCustomTagDefinitionHelper(unirest).addValueToListTag(tagInfo.getGuid(), newValue);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The addValueToListTag makes a redundant full GET /customTags call.

extendTagWithValue in SSCIssueCustomTagHelper creates a new SSCCustomTagDefinitionHelper instance that triggers lazy-loading of all custom tags via GET /api/v1/customTags?limit=-1 just to get the descriptor for one tag. A targeted GET /api/v1/customTags/{id} would be more efficient.

private String comment;
@Option(names = {"--assign-user"})
private String assignUser;
@Option(names = {"--extend"}, defaultValue = "false")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

--extend at issue update level, not per-tag.
If updating multiple custom tags in one command (e.g. --custom-tags TagA=NewVal,TagB=ExistingVal), which custom tag the --extend applies to? What if a custom tag is not extensible?
For the extensible custom-tag it should add a value and for the not extensible tags, proper error message must be displayed.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR enhances the SSC remediation workflow by adding support for automatically creating missing values for extensible LIST-type custom tags during ssc issue update via a new --extend flag. It also refactors SSC custom-tag definition update/create logic into a dedicated helper and adds validation so value operations on non-LIST tag types fail fast instead of falsely reporting success.

Changes:

  • Added ssc issue update --extend to allow adding missing values for extensible LIST custom tags during issue updates.
  • Introduced SSCCustomTagDefinitionHelper and updated related commands/mixins to use it, consolidating custom-tag create/update body construction.
  • Added explicit validation to reject --values/--add-values/--rm-values operations for non-LIST custom tags with a clearer error message.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/i18n/SSCMessages.properties Adds help text for the new --extend option.
fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue/helper/SSCIssueCustomTagHelper.java Validates tag values and extends extensible LIST tags by creating new values when --extend is used.
fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue/cli/cmd/SSCIssueUpdateCommand.java Adds --extend CLI option and passes it into custom tag processing.
fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue_template/cli/cmd/AbstractSSCIssueTemplateUpdateCommand.java Switches to the new assignment helper for resolving/updating tag descriptors.
fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/custom_tag/helper/SSCCustomTagHelper.java Removes old helper in favor of the new definition-focused helper.
fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/custom_tag/helper/SSCCustomTagDescriptor.java Adds extensible field to descriptor model.
fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/custom_tag/helper/SSCCustomTagDefinitionHelper.java New helper centralizing descriptor resolution, request-body construction, and LIST value manipulation.
fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/custom_tag/helper/SSCCustomTagAssignmentHelper.java Refactors to depend on SSCCustomTagDefinitionHelper for descriptor resolution.
fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/custom_tag/cli/mixin/SSCCustomTagResolverMixin.java Updates resolver to use SSCCustomTagDefinitionHelper.
fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/custom_tag/cli/cmd/SSCCustomTagUpdateCommand.java Uses definition helper for update-body construction + validation and for returning updated descriptor.
fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/custom_tag/cli/cmd/SSCCustomTagCreateCommand.java Uses definition helper for create-body construction.
fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/helper/SSCAppVersionCustomTagUpdater.java Switches to assignment helper for app-version custom tag updates.

Comment on lines +237 to +243
private int extendTagWithValue(CustomTagInfo tagInfo, String newValue) {
int newIndex = new SSCCustomTagDefinitionHelper(unirest).addValueToListTagById(tagInfo.getId(), newValue);
ValueListItem newItem = new ValueListItem();
newItem.setLookupIndex(newIndex);
newItem.setLookupValue(newValue);
tagInfo.getValueList().add(newItem);
return newIndex;
Comment on lines +138 to +142
public int addValueToListTagById(String tagNumericId, String newValue) {
JsonNode response = unirest.get(SSCUrls.CUSTOM_TAG(tagNumericId)).asObject(JsonNode.class).getBody();
ObjectNode body = (ObjectNode) response.get("data").deepCopy();
return addValueToListTagInternal(tagNumericId, body, newValue);
}
return;
case DATE:
if (!isUnset) {
processDateValue(tagValue, tagName);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For other cases, we call a validate function, whereas here we call a process function, which looks weird, and we're not using the return value of the processDateValue method. Instead of explicitly validating the value, we're implicitly assuming that the processDateValue performs validation (which it does, but this is a code smell).

return;
}
String hint = tagInfo.isExtensible()
? " Use --extend to add new values."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is a generic helper class that isn't aware of which fcli command it is being called from, and whether that command provides a --extend option. Maybe in the future, we call these helper methods from some other command that doesn't provide --extend option, thus showing an incorrect error message to the user.

Instead of passing a simple boolean extend, maybe better to introduce a small helper interface that provides a method like checkExtendAllowed(...) (or whatever else fits code structure); the command class would then provide an implementation that throws an appropriate error showing the actual option name.

}

boolean isUnset = tagValue == null || tagValue.isBlank();
switch (tagInfo.getValueType()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can't we just skip validation altogether if isUnset is true, instead of repeating if-statement in each case block?

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