Skip to content

feat: Implement BruteForceAttack.drl security rules for brute force detection#8525

Merged
pethers merged 6 commits intomasterfrom
copilot/implement-bruteforceattack-rule
Apr 5, 2026
Merged

feat: Implement BruteForceAttack.drl security rules for brute force detection#8525
pethers merged 6 commits intomasterfrom
copilot/implement-bruteforceattack-rule

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 5, 2026

Description

The BruteForceAttack.drl file contained only a package declaration with zero rules — a gap in the security controls documented in SECURITY_ARCHITECTURE.md and THREAT_MODEL.md. This implements 3-tier brute force detection rules integrated with the existing Drools compliance check framework.

Rules implemented:

  • MINOR (salience 10): 5–9 failed auth attempts per session
  • MAJOR (salience 50): 10–19 failed auth attempts per session
  • CRITICAL (salience 100): 20+ failed auth attempts per session

Key changes:

  • ResourceType.java — added APPLICATION enum value
  • ApplicationComplianceCheckImpl.java — new compliance check wrapper tracking sessionId and failed auth count
  • BruteForceAttack.drl — 3 rules using mvel dialect (ECJ compiler incompatible with JDK 26), with rule names accurately reflecting non-overlapping ranges ("5 to 9", "10 to 19", "20 or more")
  • kmodule.xml — added com.hack23.cia.service.impl.rules.application package
  • RulesEngineImpl.java — queries failed AUTHENTICATION events where applicationMessage == ServiceResult.FAILURE via DataViewer.findListByProperty() in a single query, groups by session ID using Collectors.counting() for memory efficiency, and inserts compliance checks into the KIE session
  • BruteForceAttackRulesTest.java — 9 unit tests loading both kmodule.xml and BruteForceAttack.drl into KieFileSystem to validate production rule-discovery config alongside rule behavior; covers thresholds, boundaries, rule firing count verification, and property correctness
  • RiskRulesITest.java — updated ResourceType allowlist and switch to include APPLICATION, preventing integration test failures when application-level violations are produced
rule "Brute force attack detected - critical threshold, 20 or more failed login attempts in session"
	dialect "mvel"
	salience 100
    when
        $app : ApplicationComplianceCheckImpl(failedAuthenticationAttempts >= 20)
    then
    	$app.addViolation( Status.CRITICAL, "BruteForceAttack","Security",
    	    kcontext.getRule().getName(),"login.failed.threshold.critical");
end

Type of Change

Primary Changes

  • 🚀 New Feature

Political Analysis

  • 📊 Political Data Analysis
  • 📈 Analytics & Metrics
    • Risk Assessment

Technical Changes

  • 🏗️ Infrastructure
    • Performance Optimization
  • 🔒 Security & Compliance
    • Authentication
  • ✅ Testing
    • Unit Tests

Impact Analysis

Political Analysis Impact

  • Impact on data quality: No change to political data
  • Impact on analysis accuracy: N/A
  • Impact on transparency features: Adds security compliance rule violations visible through existing rule violation UI

Technical Impact

  • Performance impact: Minimal — uses a single DataViewer.findListByProperty() query to fetch only failed AUTHENTICATION events with applicationMessage=FAILURE, then groups to counts via Collectors.counting() (no full event lists retained in memory), avoiding both N+1 lazy-load overhead and unnecessary memory allocation
  • Security implications: Closes gap in brute force detection; aligns with THREAT_MODEL.md T1110 mitigation; failure detection uses ServiceResult.FAILURE in applicationMessage consistent with LoginBlockedAccessImpl
  • Dependency changes: None

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Political data validation completed
  • Security compliance verified
  • Performance testing completed

9 unit tests validate: below-threshold no-fire, all 3 severity thresholds, extreme counts, single-rule-fires verification (asserts fireAllRules() return value equals 1), boundary conditions, and property correctness. Tests load kmodule.xml into KieFileSystem to validate the production rule-discovery/config path. RiskRulesITest updated to include APPLICATION in the ResourceType allowlist and switch statement. All 38 existing service.impl tests pass.

Documentation

  • JavaDoc updated
  • README updated
  • API documentation updated
  • Package/module documentation updated
  • Political analysis documentation updated

Screenshots

N/A — backend rule engine changes only.

Related Issues

Checklist

  • Code follows project coding standards
  • Comments are clear and helpful
  • Documentation is updated
  • Tests are passing
  • Security compliance is maintained
  • Performance impact is acceptable
  • Breaking changes are documented
  • Changes are backward compatible

Additional Notes

Uses mvel dialect instead of java because the Drools ECJ (Eclipse Java Compiler) has a known NPE in moduleNotFound when running under JDK 26. MVEL handles the simple addViolation() calls identically. Unit tests load both kmodule.xml and BruteForceAttack.drl into KieFileSystem via programmatic KieBuilder API to validate production rule configuration alongside rule behavior.

Failed authentication detection uses applicationMessage == ServiceResult.FAILURE.toString() (matching the LoginBlockedAccessImpl pattern) rather than checking errorMessage, which could undercount failures where no error text is set.

DRL rule names accurately reflect non-overlapping conditions: "5 to 9", "10 to 19", and "20 or more" — since kcontext.getRule().getName() is persisted as the violation description, accuracy prevents misleading RuleViolation records.

IP information is set to "unknown" since ApplicationActionEvent does not carry IP data; the session ID serves as the primary identifier for compliance check grouping.

Committee and ministry rule packages remain absent from kmodule.xml — that's a pre-existing issue not addressed here.

Security Considerations

  • No sensitive data exposed
  • Security best practices followed
  • Compliance requirements met

Implements MITRE ATT&CK T1110 (Brute Force) detection per THREAT_MODEL.md. CodeQL scan: 0 alerts.

Release Notes

Added application-level brute force attack detection via Drools rules engine. Sessions with 5+ failed authentication attempts (identified by applicationMessage=FAILURE) now generate RuleViolation entries at MINOR/MAJOR/CRITICAL severity levels.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 5, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA a33fc8c.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

Scanned Files

None

…etection

- Add APPLICATION value to ResourceType enum
- Create ApplicationComplianceCheckImpl for session-level security analysis
- Implement 3-tier BruteForceAttack.drl rules (MINOR/MAJOR/CRITICAL)
- Update kmodule.xml to include application rules package
- Update RulesEngineImpl to insert application session data
- Add BruteForceAttackRulesTest with 9 passing unit tests

Agent-Logs-Url: https://github.com/Hack23/cia/sessions/0be4aadc-da0e-4b99-9dbc-81169915699e

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 5, 2026

📚 Javadoc Generated

The Javadoc documentation has been generated for this PR. Download the javadoc artifact from the workflow run to view the complete API documentation with UML diagrams.

…lter, remove debug output

Agent-Logs-Url: https://github.com/Hack23/cia/sessions/0be4aadc-da0e-4b99-9dbc-81169915699e

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement empty BruteForceAttack.drl security rule for detection feat: Implement BruteForceAttack.drl security rules for brute force detection Apr 5, 2026
Copilot AI requested a review from pethers April 5, 2026 11:09
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 5, 2026

📚 Javadoc Generated

The Javadoc documentation has been generated for this PR. Download the javadoc artifact from the workflow run to view the complete API documentation with UML diagrams.

@pethers pethers marked this pull request as ready for review April 5, 2026 11:24
@pethers pethers requested a review from Copilot April 5, 2026 11:24
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Implements the previously-empty BruteForceAttack.drl by introducing application-level compliance checks and Drools rules to detect brute-force login attempts, integrating with the existing rules-compliance reporting pipeline.

Changes:

  • Added APPLICATION as a new ResourceType and introduced ApplicationComplianceCheckImpl to represent session-level security signals for rules evaluation.
  • Implemented 3-tier brute force detection rules (MINOR/MAJOR/CRITICAL) in BruteForceAttack.drl (MVEL dialect) and enabled rule loading via kmodule.xml.
  • Extended RulesEngineImpl to insert application-session-derived compliance checks into the KIE session and added unit tests for the new rules.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
service.impl/src/test/java/com/hack23/cia/service/impl/rules/BruteForceAttackRulesTest.java Adds unit tests for brute force thresholds and rule firing behavior.
service.impl/src/main/resources/META-INF/kmodule.xml Registers the new application rules package so Drools loads the DRL.
service.impl/src/main/resources/com/hack23/cia/service/impl/rules/application/BruteForceAttack.drl Implements the MINOR/MAJOR/CRITICAL brute force detection rules using MVEL.
service.impl/src/main/java/com/hack23/cia/service/impl/rules/RulesEngineImpl.java Inserts application session compliance checks by counting failed auth attempts from session events.
service.impl/src/main/java/com/hack23/cia/service/impl/rules/ApplicationComplianceCheckImpl.java New compliance check wrapper holding sessionId, IP info, and failed-auth count for Drools.
model.internal.application.user.impl/src/main/java/com/hack23/cia/model/internal/application/data/rules/impl/ResourceType.java Adds APPLICATION enum value for rule violations tied to application-level resources.

import com.hack23.cia.model.internal.application.data.ministry.impl.ViewRiksdagenMinistry;
import com.hack23.cia.model.internal.application.data.party.impl.ViewRiksdagenPartySummary;
import com.hack23.cia.model.internal.application.data.politician.impl.ViewRiksdagenPolitician;
import com.hack23.cia.model.internal.application.system.impl.ApplicationActionEvent;
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

Unused import ApplicationActionEvent in this class; it isn't referenced anywhere and will fail builds that enforce no-unused-imports. Remove the import (or use the type explicitly if intended).

Suggested change
import com.hack23.cia.model.internal.application.system.impl.ApplicationActionEvent;

Copilot uses AI. Check for mistakes.
Comment on lines +276 to +279
final long failedAuthAttempts = session.getEvents().stream()
.filter(event -> ApplicationOperationType.AUTHENTICATION == event.getApplicationOperation()
&& event.getErrorMessage() != null && !event.getErrorMessage().isEmpty())
.count();
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

Failed authentication attempts are currently inferred from event.getErrorMessage() being non-empty. Elsewhere (e.g., login blocking) failures are tracked via applicationMessage == ServiceResult.FAILURE; using errorMessage risks undercounting failures where no error text is set (e.g., some AUTHENTICATION failures). Consider counting by ServiceResult.FAILURE in applicationMessage (and optionally also checking errorMessage for context).

Copilot uses AI. Check for mistakes.
Comment on lines +273 to +287
private static void insertApplicationSessions(final KieSession ksession, final List<ApplicationSession> list) {
for (final ApplicationSession session : list) {
if (session != null && session.getEvents() != null) {
final long failedAuthAttempts = session.getEvents().stream()
.filter(event -> ApplicationOperationType.AUTHENTICATION == event.getApplicationOperation()
&& event.getErrorMessage() != null && !event.getErrorMessage().isEmpty())
.count();

if (failedAuthAttempts > 0) {
final ApplicationComplianceCheckImpl check = new ApplicationComplianceCheckImpl(
session.getSessionId(),
session.getIpInformation(),
failedAuthAttempts);
ksession.insert(check);
}
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

applicationSessionDAO.getAll() + iterating session.getEvents() will typically trigger an extra query per session because events is a @OneToMany with default LAZY loading. This can become a large N+1 query pattern on systems with many sessions. Prefer a DAO/query that pre-aggregates failed AUTHENTICATION counts per session (or fetch-joins events in bulk) and only inserts checks for sessions meeting the rule threshold.

Copilot uses AI. Check for mistakes.
Comment on lines +178 to +196
/**
* Test salience ordering - highest severity wins.
* The AbstractComplianceCheckImpl keeps the highest severity violation.
*/
@Test
public void testSalienceOrderingHighestSeverityWins() {
final ApplicationComplianceCheckImpl check = new ApplicationComplianceCheckImpl(
"session-6", "192.168.0.100", 25);

kieSession.insert(check);
kieSession.fireAllRules();

final List<RuleViolation> violations = check.getRuleViolations();
assertFalse("Should have violations", violations.isEmpty());
assertEquals("Should have exactly 1 violation (highest severity wins)", 1, violations.size());

final RuleViolation violation = violations.get(0);
assertEquals("Highest severity should be CRITICAL for 25 attempts", Status.CRITICAL, violation.getStatus());
}
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

testSalienceOrderingHighestSeverityWins doesn't actually validate salience/"highest severity wins" behavior: with the current DRL conditions (5–9, 10–19, 20+), only the CRITICAL rule matches for 25 attempts, so ordering never comes into play. Either adjust the rules/test so multiple rules can fire and the map keeps the highest severity, or rename/update the test and its Javadoc to reflect what it truly asserts.

Copilot uses AI. Check for mistakes.
@pethers
Copy link
Copy Markdown
Member

pethers commented Apr 5, 2026

@copilot apply changes based on the comments in this thread

…e N+1 query, fix test name

- Remove ApplicationSessionDAO dependency; use DataViewer.findListByProperty
  to query failed AUTHENTICATION events with applicationMessage=FAILURE
  in a single query, eliminating the N+1 lazy-load pattern
- Match LoginBlockedAccessImpl pattern: check applicationMessage ==
  ServiceResult.FAILURE.toString() instead of errorMessage
- Rename testSalienceOrderingHighestSeverityWins to testOnlyCriticalRuleFires
  with accurate Javadoc (non-overlapping conditions mean only one rule fires)

Agent-Logs-Url: https://github.com/Hack23/cia/sessions/0859b5e4-d8b1-4d2c-8f66-ca8e669926f8

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 5, 2026

@copilot apply changes based on the comments in this thread

All four review comments addressed in commit b1625ef:

  1. Unused importApplicationActionEvent is now actively used in the new query approach, and the ApplicationSession import was removed along with ApplicationSessionDAO.

  2. Failure detection — Switched from errorMessage check to applicationMessage == ServiceResult.FAILURE.toString(), matching the LoginBlockedAccessImpl pattern at line 184.

  3. N+1 query — Replaced applicationSessionDAO.getAll() + lazy-load iteration with a single dataViewer.findListByProperty() query that fetches only AUTHENTICATION events with applicationMessage=FAILURE, then groups by session ID in-memory.

  4. Test name — Renamed testSalienceOrderingHighestSeverityWinstestOnlyCriticalRuleFires with Javadoc clarifying that non-overlapping conditions (5–9, 10–19, 20+) mean exactly one rule fires per input.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 5, 2026

📚 Javadoc Generated

The Javadoc documentation has been generated for this PR. Download the javadoc artifact from the workflow run to view the complete API documentation with UML diagrams.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

final long failedCount = entry.getValue().size();
if (failedCount > 0) {
final ApplicationComplianceCheckImpl check = new ApplicationComplianceCheckImpl(
entry.getKey(), entry.getKey(), failedCount);
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

ApplicationComplianceCheckImpl is constructed with ipInformation set to the sessionId (entry.getKey()), which will produce misleading names like Session:<id> IP:<id> and incorrect data in persisted RuleViolations. Either populate ipInformation from ApplicationSession.ipInformation (if available) or use a clear placeholder (e.g., "unknown") and/or rename the field to reflect what it actually contains.

Suggested change
entry.getKey(), entry.getKey(), failedCount);
entry.getKey(), "unknown", failedCount);

Copilot uses AI. Check for mistakes.
Comment on lines +276 to +281
final Map<String, List<ApplicationActionEvent>> eventsBySession = failedAuthEvents.stream()
.filter(event -> event.getSessionId() != null)
.collect(Collectors.groupingBy(ApplicationActionEvent::getSessionId));

for (final Map.Entry<String, List<ApplicationActionEvent>> entry : eventsBySession.entrySet()) {
final long failedCount = entry.getValue().size();
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

This groups all failed auth events into Map<String, List<ApplicationActionEvent>>, but only the count per session is used. Collecting full lists can waste a lot of memory for large event tables; prefer grouping directly to counts (e.g., groupingBy(sessionId, counting())) and iterate those counts.

Suggested change
final Map<String, List<ApplicationActionEvent>> eventsBySession = failedAuthEvents.stream()
.filter(event -> event.getSessionId() != null)
.collect(Collectors.groupingBy(ApplicationActionEvent::getSessionId));
for (final Map.Entry<String, List<ApplicationActionEvent>> entry : eventsBySession.entrySet()) {
final long failedCount = entry.getValue().size();
final Map<String, Long> failedCountsBySession = failedAuthEvents.stream()
.filter(event -> event.getSessionId() != null)
.collect(Collectors.groupingBy(ApplicationActionEvent::getSessionId, Collectors.counting()));
for (final Map.Entry<String, Long> entry : failedCountsBySession.entrySet()) {
final long failedCount = entry.getValue();

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +20
rule "Brute force attack detected - minor threshold, 5 or more failed login attempts in session"
dialect "mvel"
salience 10
when
$app : ApplicationComplianceCheckImpl(failedAuthenticationAttempts >= 5 && failedAuthenticationAttempts < 10)
then
$app.addViolation( Status.MINOR, "BruteForceAttack","Security", kcontext.getRule().getName(),"login.failed.threshold.minor");
end

rule "Brute force attack detected - major threshold, 10 or more failed login attempts in session"
dialect "mvel"
salience 50
when
$app : ApplicationComplianceCheckImpl(failedAuthenticationAttempts >= 10 && failedAuthenticationAttempts < 20)
then
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

The rule names say "5 or more" / "10 or more" failed attempts, but the conditions are non-overlapping ranges (5–9, 10–19). Since kcontext.getRule().getName() is persisted as the violation description, the current names will be misleading; adjust the rule names to match the actual thresholds (or change the conditions to match the wording).

Copilot uses AI. Check for mistakes.
Comment on lines +189 to +190
kieSession.fireAllRules();

Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

testOnlyCriticalRuleFires asserts a single violation, but doesn’t verify that only one rule fired (multiple rules could fire and still collapse to one violation because AbstractComplianceCheckImpl deduplicates by ruleName). Capture fireAllRules() return value and assert it is 1 to match the test’s intent and prevent regressions to overlapping conditions.

Suggested change
kieSession.fireAllRules();
final int firedRules = kieSession.fireAllRules();
assertEquals("Should have exactly 1 fired rule (only CRITICAL matches)", 1, firedRules);

Copilot uses AI. Check for mistakes.
@pethers
Copy link
Copy Markdown
Member

pethers commented Apr 5, 2026

@copilot apply changes based on the comments in this thread

… IP/rule names, strengthen test

- Use Collectors.counting() instead of collecting full event lists (memory optimization)
- Use "unknown" for ipInformation instead of duplicating sessionId
- Fix DRL rule names: "5 or more" → "5 to 9", "10 or more" → "10 to 19" to match actual non-overlapping ranges
- Assert fireAllRules() returns 1 in testOnlyCriticalRuleFires to verify exactly one rule fired

Agent-Logs-Url: https://github.com/Hack23/cia/sessions/730053c9-1251-43ae-9b93-5e9f4868edb7

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 5, 2026

@copilot apply changes based on the comments in this thread

All four review comments addressed in commit 5f338e2:

  1. IP information — Changed from duplicating sessionId to using "unknown" placeholder since ApplicationActionEvent doesn't carry IP data.

  2. Memory optimization — Replaced Collectors.groupingBy(sessionId) (collecting full event lists) with Collectors.groupingBy(sessionId, Collectors.counting()) to store only counts.

  3. DRL rule names — Fixed misleading names: "5 or more" → "5 to 9", "10 or more" → "10 to 19" to match the actual non-overlapping conditions.

  4. Test assertiontestOnlyCriticalRuleFires now captures fireAllRules() return value and asserts it equals 1, verifying exactly one rule fired (not just one violation).

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 5, 2026

📚 Javadoc Generated

The Javadoc documentation has been generated for this PR. Download the javadoc artifact from the workflow run to view the complete API documentation with UML diagrams.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Comment on lines +62 to +72
public void setUp() {
final KieServices kieServices = KieServices.Factory.get();
final KieFileSystem kfs = kieServices.newKieFileSystem();
kfs.write(ResourceFactory.newClassPathResource(
"com/hack23/cia/service/impl/rules/application/BruteForceAttack.drl"));
final KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
final Results results = kieBuilder.getResults();
assertFalse("DRL compilation should have no errors: " + results.getMessages(),
results.hasMessages(Message.Level.ERROR));
kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
kieSession = kieContainer.newKieSession();
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

This test builds a KieModule containing only BruteForceAttack.drl, so it won’t catch regressions where the real classpath kmodule.xml doesn’t include the application rules package (or where the default KieSession name differs). Consider also loading kmodule.xml into the KieFileSystem (or using the same classpath KieContainer wiring used in integration tests) so the test validates the production rule-discovery/config path as well as rule behavior.

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +269 to +284
@SuppressWarnings("unchecked")
private void insertFailedAuthenticationSessions(final KieSession ksession) {
final List<ApplicationActionEvent> failedAuthEvents = dataViewer.findListByProperty(
ApplicationActionEvent.class,
new Object[] { ApplicationOperationType.AUTHENTICATION, ServiceResult.FAILURE.toString() },
ApplicationActionEvent_.applicationOperation, ApplicationActionEvent_.applicationMessage);

final Map<String, Long> failedCountsBySession = failedAuthEvents.stream()
.filter(event -> event.getSessionId() != null)
.collect(Collectors.groupingBy(ApplicationActionEvent::getSessionId, Collectors.counting()));

for (final Map.Entry<String, Long> entry : failedCountsBySession.entrySet()) {
final long failedCount = entry.getValue();
if (failedCount > 0) {
final ApplicationComplianceCheckImpl check = new ApplicationComplianceCheckImpl(
entry.getKey(), "unknown", failedCount);
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

The @SuppressWarnings("unchecked") on this method appears redundant (DataViewer.findListByProperty is already generic; the unchecked warning is handled at the varargs declaration). Also, after groupingBy/counting(), every entry’s failedCount will be >= 1, so the if (failedCount > 0) branch is unnecessary noise.

Copilot uses AI. Check for mistakes.
Comment on lines 44 to +48
/** The minister. */
MINISTER;
MINISTER,

/** The application. */
APPLICATION;
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

Adding ResourceType.APPLICATION may require updating code/tests that validate ResourceType against a fixed allowlist. For example, service.impl/src/test/java/com/hack23/cia/service/impl/rules/RiskRulesITest currently asserts violations are only POLITICIAN/PARTY/COMMITTEE/MINISTRY; it will fail once APPLICATION violations are produced.

Copilot uses AI. Check for mistakes.
@pethers
Copy link
Copy Markdown
Member

pethers commented Apr 5, 2026

@copilot apply changes based on the comments in this thread

…kmodule.xml in test, update RiskRulesITest

- Remove redundant @SuppressWarnings("unchecked") annotation
- Remove unnecessary `if (failedCount > 0)` guard (groupingBy/counting always produces >= 1)
- Load kmodule.xml into KieFileSystem in BruteForceAttackRulesTest to validate production config
- Add ResourceType.APPLICATION to RiskRulesITest allowlist and switch statement

Agent-Logs-Url: https://github.com/Hack23/cia/sessions/0bc92915-dfbb-462c-bfff-0fb2c3b1e729

Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 5, 2026

@copilot apply changes based on the comments in this thread

All three review comments addressed in commit a33fc8c:

  1. Redundant annotation & dead code — Removed @SuppressWarnings("unchecked") (generic is already handled at the varargs declaration) and eliminated the if (failedCount > 0) guard since groupingBy/counting() always produces values ≥ 1.

  2. Test config validation — Added kfs.write(ResourceFactory.newClassPathResource("META-INF/kmodule.xml")) to BruteForceAttackRulesTest.setUp() so the test validates production rule-discovery via kmodule.xml alongside rule behavior.

  3. RiskRulesITest allowlist — Added ResourceType.APPLICATION to both the assertTrue allowlist in testViolationMetadata (line 239) and the switch in testResourceTypeCoverage (new APPLICATION case with counter).

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 5, 2026

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 5, 2026

📚 Javadoc Generated

The Javadoc documentation has been generated for this PR. Download the javadoc artifact from the workflow run to view the complete API documentation with UML diagrams.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@pethers pethers merged commit 7156a0f into master Apr 5, 2026
16 checks passed
@pethers pethers deleted the copilot/implement-bruteforceattack-rule branch April 5, 2026 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement empty BruteForceAttack.drl security rule for application-level brute force detection

3 participants