Conversation
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Pull request overview
This PR appears to address “Issue166” by updating configuration/module-registration integration and introducing request access-control support for RPC routing/security.
Changes:
- Added a new
AccessControlHandlermiddleware that evaluates rule-based access control per endpoint. - Updated router/security components to use newer
*.load()config patterns and movedModuleRegistryimports tocom.networknt.server. - Updated Maven dependencies to include access-control/rule-loading related modules and
server-config.
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| rpc-security/src/main/java/com/networknt/rpc/security/HybridJwtVerifyHandler.java | Updates ModuleRegistry import and removes register/reload hooks (now leaving unused imports). |
| rpc-security/src/main/java/com/networknt/rpc/security/AccessControlHandler.java | Adds new rule-based access control middleware for endpoint authorization. |
| rpc-security/pom.xml | Adds dependencies for access control + rule loader + server-config (introduces a duplicate handler dependency). |
| rpc-router/src/test/java/com/networknt/rpc/router/RpcRouterConfigTest.java | Updates tests to use RpcRouterConfig.load(...). |
| rpc-router/src/main/resources/config/rpc-router-schema.json | Minor formatting change. |
| rpc-router/src/main/java/com/networknt/rpc/router/SchemaHandler.java | Refactors schema loading into loadServices() and leaves a commented-out reload() stub + unused import. |
| rpc-router/src/main/java/com/networknt/rpc/router/RpcStartupHookProvider.java | Removes module registration call, switches ModuleRegistry import (now unused). |
| rpc-router/src/main/java/com/networknt/rpc/router/RpcRouterConfig.java | Introduces cached singleton-style load() and module registration (thread-safety issue). |
| rpc-router/src/main/java/com/networknt/rpc/router/JsonHandler.java | Converts to MiddlewareHandler and switches to ServerConfig.load() (unused import added). |
| rpc-router/src/main/java/com/networknt/rpc/HybridHandler.java | Minor logging / style improvements. |
| rpc-router/pom.xml | Adds server-config dependency. |
| pom.xml | Adds dependency management entries for access/rule-related artifacts and yaml-rule version property. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
rpc-router/src/main/java/com/networknt/rpc/router/JsonHandler.java
Outdated
Show resolved
Hide resolved
rpc-router/src/main/java/com/networknt/rpc/router/SchemaHandler.java
Outdated
Show resolved
Hide resolved
rpc-security/src/main/java/com/networknt/rpc/security/HybridJwtVerifyHandler.java
Show resolved
Hide resolved
|
|
||
| import com.networknt.access.AccessControlConfig; | ||
| import com.networknt.config.Config; | ||
| import com.networknt.config.JsonMapper; |
There was a problem hiding this comment.
com.networknt.config.Config is imported but not used in this class. Please remove the unused import.
| import com.networknt.config.JsonMapper; |
rpc-security/src/main/java/com/networknt/rpc/security/AccessControlHandler.java
Outdated
Show resolved
Hide resolved
rpc-router/src/main/java/com/networknt/rpc/router/RpcRouterConfig.java
Outdated
Show resolved
Hide resolved
rpc-security/src/main/java/com/networknt/rpc/security/AccessControlHandler.java
Show resolved
Hide resolved
rpc-security/src/main/java/com/networknt/rpc/security/AccessControlHandler.java
Outdated
Show resolved
Hide resolved
rpc-router/src/main/java/com/networknt/rpc/router/SchemaHandler.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 12 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (2)
rpc-router/src/main/java/com/networknt/rpc/router/JsonHandler.java:44
auditInfocan be null (you have an explicit branch for that), but later in this methodauditInfois still dereferenced (e.g., when extracting HYBRID_SERVICE_DATA), which will throw a NullPointerException. Either require/ensureAUDIT_INFOis always present for this handler, or guard all subsequentauditInfo.get(...)usages when falling back toServerConfig.
final ServerConfig serverConfig = ServerConfig.load();
// get the serviceId from the auditInfo attachment.
if (auditInfo != null) {
serviceId = (String)auditInfo.get(Constants.ENDPOINT_STRING);
rpc-router/src/main/java/com/networknt/rpc/router/RpcStartupHookProvider.java:47
- Please remove the
System.out.printlndebug statement; it will write to stdout in production. Use the existing logger (or remove entirely) instead.
final var packages = config.getHandlerPackages().toArray(new String[0]);
System.out.println("packages: " + Arrays.toString(packages));
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import com.networknt.server.StartupHookProvider; | ||
| import com.networknt.service.SingletonServiceFactory; | ||
| import com.networknt.utility.ModuleRegistry; | ||
| import com.networknt.server.ModuleRegistry; | ||
| import io.github.classgraph.ClassGraph; |
There was a problem hiding this comment.
These imports appear unused after the refactor (e.g., Config and ModuleRegistry). Consider removing unused imports to keep the file clean and avoid IDE/CI warnings.
| static final String STARTUP_HOOK_NOT_LOADED = "ERR11019"; | ||
| static final String REQUEST_ACCESS = "req-acc"; | ||
| static final String PERMISSION = "permission"; | ||
| static final String RULE_ID = "ruleId"; |
There was a problem hiding this comment.
RULE_ID is declared but not used in this class. Please remove it if it’s not needed, or use it if it’s intended to be part of the requestRules structure.
| static final String RULE_ID = "ruleId"; |
| boolean finalResult = false; // Initialize to false for "any" logic, and will change in for loop | ||
| List<String> accessRuleIds = (List<String>)requestRules.get(REQUEST_ACCESS); | ||
| Map<String, Object> permissionMap = (Map<String, Object>)requestRules.get(PERMISSION); | ||
| Map<String, Object> result = null; |
There was a problem hiding this comment.
executeRules assumes requestRules always contains a non-null/non-empty req-acc list and a non-null permission map. If either is missing/empty, this can NPE and (for all logic with an empty list) can effectively allow access. Please validate these inputs and fail closed (return an access-control error) when they are missing/invalid.
| boolean finalResult = false; // Initialize to false for "any" logic, and will change in for loop | |
| List<String> accessRuleIds = (List<String>)requestRules.get(REQUEST_ACCESS); | |
| Map<String, Object> permissionMap = (Map<String, Object>)requestRules.get(PERMISSION); | |
| Map<String, Object> result = null; | |
| // Validate requestRules to avoid NPE and fail closed on invalid configuration | |
| if (requestRules == null) { | |
| logger.error("Access control configuration is missing for this request: requestRules is null"); | |
| setExchangeStatus(exchange, ACCESS_CONTROL_ERROR, "Missing access control configuration"); | |
| return; | |
| } | |
| boolean finalResult = false; // Initialize to false for "any" logic, and will change in for loop | |
| List<String> accessRuleIds = (List<String>) requestRules.get(REQUEST_ACCESS); | |
| Map<String, Object> permissionMap = (Map<String, Object>) requestRules.get(PERMISSION); | |
| Map<String, Object> result = null; | |
| // Validate that we have a non-empty list of access rules and a permission map | |
| if (accessRuleIds == null || accessRuleIds.isEmpty() || permissionMap == null) { | |
| logger.error("Access control configuration is invalid: req-acc list or permission map is missing or empty"); | |
| setExchangeStatus(exchange, ACCESS_CONTROL_ERROR, "Invalid access control configuration"); | |
| return; | |
| } |
| @Override | ||
| @SuppressWarnings("unchecked") | ||
| public void handleRequest(final HttpServerExchange exchange) throws Exception { | ||
| AccessControlConfig config = AccessControlConfig.load(); | ||
| if (logger.isDebugEnabled()) logger.debug("AccessControlHandler.handleRequest starts."); | ||
| String reqPath = exchange.getRequestPath(); | ||
| // if request path is in the skipPathPrefixes in the config, call the next handler directly to skip the security check. | ||
| if (config.getSkipPathPrefixes() != null && config.getSkipPathPrefixes().stream().anyMatch(reqPath::startsWith)) { | ||
| if(logger.isTraceEnabled()) logger.trace("Skip request path base on skipPathPrefixes for {}", reqPath); | ||
| if (logger.isDebugEnabled()) logger.debug("AccessControlHandler.handleRequest ends with path skipped."); | ||
| Handler.next(exchange, next); | ||
| return; | ||
| } | ||
|
|
There was a problem hiding this comment.
This PR introduces a new access-control decision point, but there are no tests covering its behavior (skipPathPrefixes, defaultDeny, any/all logic, and error status codes). Please add unit/integration tests to prevent regressions.
No description provided.