Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ https:
**/data-kafka-data
**/data-zoo-data
**/data-zoo-logs

run-cyborg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4109,4 +4109,66 @@ public void setTestingRunResultId(String testingRunResultId) {
public void setUrlType(String urlType) {
this.urlType = urlType;
}

// Fields for fetchMCPThreatProtectionTemplates API
private List<YamlTemplate> mcpThreatProtectionTemplates;
private Integer updatedAfter;

public List<YamlTemplate> getMcpThreatProtectionTemplates() {
return mcpThreatProtectionTemplates;
}

public void setMcpThreatProtectionTemplates(List<YamlTemplate> mcpThreatProtectionTemplates) {
this.mcpThreatProtectionTemplates = mcpThreatProtectionTemplates;
}

public Integer getUpdatedAfter() {
return updatedAfter;
}

public void setUpdatedAfter(Integer updatedAfter) {
this.updatedAfter = updatedAfter;
}

public String fetchMCPThreatProtectionTemplates() {
try {
loggerMaker.infoAndAddToDb("Fetching MCP threat protection templates with updatedAfter: " + updatedAfter, LogDb.DB_ABS);
this.mcpThreatProtectionTemplates = DbLayer.fetchMCPThreatProtectionTemplates(updatedAfter);
} catch (Exception e) {
loggerMaker.errorAndAddToDb(e, "Error in fetchMCPThreatProtectionTemplates: " + e.toString());
return Action.ERROR.toUpperCase();
}
return Action.SUCCESS.toUpperCase();
}

// Fields for fetchMcpAuditInfo API
private List<McpAuditInfo> mcpAuditInfoList;
private List<String> remarksList;

public List<McpAuditInfo> getMcpAuditInfoList() {
return mcpAuditInfoList;
}

public void setMcpAuditInfoList(List<McpAuditInfo> mcpAuditInfoList) {
this.mcpAuditInfoList = mcpAuditInfoList;
}

public List<String> getRemarksList() {
return remarksList;
}

public void setRemarksList(List<String> remarksList) {
this.remarksList = remarksList;
}

public String fetchMcpAuditInfo() {
try {
loggerMaker.infoAndAddToDb("Fetching MCP audit info with updatedAfter: " + updatedAfter + ", remarksList: " + remarksList, LogDb.DB_ABS);
this.mcpAuditInfoList = DbLayer.fetchMcpAuditInfo(updatedAfter, remarksList);
} catch (Exception e) {
loggerMaker.errorAndAddToDb(e, "Error in fetchMcpAuditInfo: " + e.toString());
return Action.ERROR.toUpperCase();
}
return Action.SUCCESS.toUpperCase();
}
}
26 changes: 26 additions & 0 deletions apps/database-abstractor/src/main/resources/struts.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1793,6 +1793,32 @@
</result>
</action>

<action name="api/fetchMCPThreatProtectionTemplates" class="com.akto.action.DbAction" method="fetchMCPThreatProtectionTemplates">
<interceptor-ref name="json"/>
<interceptor-ref name="defaultStack" />
<result name="SUCCESS" type="json">
<param name="includeProperties">^mcpThreatProtectionTemplates.*</param>
</result>
<result name="ERROR" type="json">
<param name="statusCode">422</param>
<param name="ignoreHierarchy">false</param>
<param name="includeProperties">^actionErrors.*</param>
</result>
</action>

<action name="api/fetchMcpAuditInfo" class="com.akto.action.DbAction" method="fetchMcpAuditInfo">
<interceptor-ref name="json"/>
<interceptor-ref name="defaultStack" />
<result name="SUCCESS" type="json">
<param name="includeProperties">^mcpAuditInfoList.*</param>
</result>
<result name="ERROR" type="json">
<param name="statusCode">422</param>
<param name="ignoreHierarchy">false</param>
<param name="includeProperties">^actionErrors.*</param>
</result>
</action>

</package>

</struts>
69 changes: 69 additions & 0 deletions libs/utils/src/main/java/com/akto/data_actor/ClientActor.java
Original file line number Diff line number Diff line change
Expand Up @@ -4201,4 +4201,73 @@ public void storeMcpReconResultsBatch(List<McpReconResult> serverDataList) {
}
}

public List<YamlTemplate> fetchMCPThreatProtectionTemplates(Integer updatedAfter) {
List<YamlTemplate> templates = new ArrayList<>();

Map<String, List<String>> headers = buildHeaders();
BasicDBObject obj = new BasicDBObject();
if (updatedAfter != null) {
obj.put("updatedAfter", updatedAfter);
}
OriginalHttpRequest request = new OriginalHttpRequest(url + "/fetchMCPThreatProtectionTemplates", "", "POST", obj.toString(), headers, "");
try {
OriginalHttpResponse response = ApiExecutor.sendRequest(request, true, null, false, null);
String responsePayload = response.getBody();
if (response.getStatusCode() != 200 || responsePayload == null) {
loggerMaker.errorAndAddToDb("invalid response in fetchMCPThreatProtectionTemplates", LoggerMaker.LogDb.RUNTIME);
return templates;
}
BasicDBObject payloadObj;
try {
payloadObj = BasicDBObject.parse(responsePayload);
BasicDBList objList = (BasicDBList) payloadObj.get("mcpThreatProtectionTemplates");
for (Object obj2: objList) {
BasicDBObject templateObj = (BasicDBObject) obj2;
templates.add(objectMapper.readValue(templateObj.toJson(), YamlTemplate.class));
}
} catch(Exception e) {
loggerMaker.errorAndAddToDb("error extracting response in fetchMCPThreatProtectionTemplates" + e, LoggerMaker.LogDb.RUNTIME);
}
} catch (Exception e) {
loggerMaker.errorAndAddToDb("error in fetchMCPThreatProtectionTemplates" + e, LoggerMaker.LogDb.RUNTIME);
}
return templates;
}

public List<McpAuditInfo> fetchMcpAuditInfo(Integer updatedAfter, List<String> remarksList) {
List<McpAuditInfo> mcpAuditInfoList = new ArrayList<>();

Map<String, List<String>> headers = buildHeaders();
BasicDBObject obj = new BasicDBObject();
if (updatedAfter != null) {
obj.put("updatedAfter", updatedAfter);
}
if (remarksList != null && !remarksList.isEmpty()) {
obj.put("remarksList", remarksList);
}
OriginalHttpRequest request = new OriginalHttpRequest(url + "/fetchMcpAuditInfo", "", "POST", obj.toString(), headers, "");
try {
OriginalHttpResponse response = ApiExecutor.sendRequest(request, true, null, false, null);
String responsePayload = response.getBody();
if (response.getStatusCode() != 200 || responsePayload == null) {
loggerMaker.errorAndAddToDb("invalid response in fetchMcpAuditInfo", LoggerMaker.LogDb.RUNTIME);
return mcpAuditInfoList;
}
BasicDBObject payloadObj;
try {
payloadObj = BasicDBObject.parse(responsePayload);
BasicDBList objList = (BasicDBList) payloadObj.get("mcpAuditInfoList");
for (Object obj2: objList) {
BasicDBObject auditInfoObj = (BasicDBObject) obj2;
mcpAuditInfoList.add(objectMapper.readValue(auditInfoObj.toJson(), McpAuditInfo.class));
}
} catch(Exception e) {
loggerMaker.errorAndAddToDb("error extracting response in fetchMcpAuditInfo" + e, LoggerMaker.LogDb.RUNTIME);
}
} catch (Exception e) {
loggerMaker.errorAndAddToDb("error in fetchMcpAuditInfo" + e, LoggerMaker.LogDb.RUNTIME);
}
return mcpAuditInfoList;
}

}
4 changes: 4 additions & 0 deletions libs/utils/src/main/java/com/akto/data_actor/DataActor.java
Original file line number Diff line number Diff line change
Expand Up @@ -378,4 +378,8 @@ public void updateNewNodesInBatches(List<SvcToSvcGraphNode> updateNodes) {

public abstract void storeMcpReconResultsBatch(List<McpReconResult> serverDataList);

public abstract List<YamlTemplate> fetchMCPThreatProtectionTemplates(Integer updatedAfter);

public abstract List<McpAuditInfo> fetchMcpAuditInfo(Integer updatedAfter, List<String> remarksList);

}
8 changes: 8 additions & 0 deletions libs/utils/src/main/java/com/akto/data_actor/DbActor.java
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,14 @@ public void storeMcpReconResultsBatch(List<McpReconResult> serverDataList) {
DbLayer.storeMcpReconResultsBatch(serverDataList);
}

public List<YamlTemplate> fetchMCPThreatProtectionTemplates(Integer updatedAfter) {
return DbLayer.fetchMCPThreatProtectionTemplates(updatedAfter);
}

public List<McpAuditInfo> fetchMcpAuditInfo(Integer updatedAfter, List<String> remarksList) {
return DbLayer.fetchMcpAuditInfo(updatedAfter, remarksList);
}

public List<SlackWebhook> fetchSlackWebhooks() {
return DbLayer.fetchSlackWebhooks();
}
Expand Down
63 changes: 63 additions & 0 deletions libs/utils/src/main/java/com/akto/data_actor/DbLayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -1813,4 +1813,67 @@ public static void storeMcpReconResultsBatch(List<McpReconResult> serverDataList
// Batch store MCP server discovery results using DAO
McpReconResultDao.instance.insertMany(serverDataList);
}

public static List<YamlTemplate> fetchMCPThreatProtectionTemplates(Integer updatedAfter) {
try {
// Use regex filter for case-insensitive "contains" match of "mcp" in content field
Bson contentFilter = Filters.regex(YamlTemplate.CONTENT, "mcp", "i");

// Build filter based on whether updatedAfter is specified
Bson filter;
if (updatedAfter != null && updatedAfter > 0) {
// Combine content filter with updatedAt filter (greater than specified timestamp)
Bson updatedAtFilter = Filters.gt(YamlTemplate.UPDATED_AT, updatedAfter);
filter = Filters.and(contentFilter, updatedAtFilter);
} else {
// Only content filter
filter = contentFilter;
}

// Fetch templates matching the filter
List<YamlTemplate> mcpTemplates = FilterYamlTemplateDao.instance.findAll(filter);

return mcpTemplates;
} catch (Exception e) {
loggerMaker.errorAndAddToDb(e, "Error in fetchMCPThreatProtectionTemplates: " + e.getMessage());
return new ArrayList<>();
}
}

public static List<McpAuditInfo> fetchMcpAuditInfo(Integer updatedAfter, List<String> remarksList) {
try {
List<Bson> filters = new ArrayList<>();

// Add updatedTimestamp filter if specified
if (updatedAfter != null && updatedAfter > 0) {
filters.add(Filters.gt("updatedTimestamp", updatedAfter));
}

// Add remarks filter if specified (exact match any of the values, case-insensitive)
if (remarksList != null && !remarksList.isEmpty()) {
List<Bson> remarksFilters = new ArrayList<>();
for (String remark : remarksList) {
if (remark != null && !remark.isEmpty()) {
// Using ^...$ for exact match with case-insensitive flag
remarksFilters.add(Filters.regex("remarks", "^" + remark + "$", "i"));
}
}
// If we have any remarks filters, combine them with OR
if (!remarksFilters.isEmpty()) {
filters.add(Filters.or(remarksFilters));
}
}

// Combine filters with AND (handles 0, 1, or multiple filters)
Bson finalFilter = filters.isEmpty() ? Filters.empty() : Filters.and(filters);

// Fetch MCP audit info matching the filter
List<McpAuditInfo> mcpAuditInfoList = McpAuditInfoDao.instance.findAll(finalFilter);

return mcpAuditInfoList;
} catch (Exception e) {
loggerMaker.errorAndAddToDb(e, "Error in fetchMcpAuditInfo: " + e.getMessage());
return new ArrayList<>();
}
}
}
Loading