Commit Graph
1003 Commits
Author SHA1 Message Date
pnoker d18bf4d03d style: fix table alignment and whitespace in README files 2026-06-26 13:17:38 +08:00
pnoker a6c63a9c3d style: fix formatting in Java source files and tests 2026-06-26 13:17:33 +08:00
pnoker 8b507b313d fix(auth,gateway): mark OAuth2.1/MCP protocol endpoints @PublicEndpoint to pass controller permission audit
These OAuth2.1 authorization-server endpoints (metadata, jwks, register, authorize, token, revoke) and the MCP gateway endpoints (protected-resource metadata, JSON-RPC mcp) authenticate via OAuth (PKCE / client credentials / bearer-token introspection), not the internal @PreAuthorize RBAC. Marking them @PublicEndpoint — consistent with TokenController pre-login endpoints — makes their public security posture explicit and satisfies the controller permission audit (337 endpoints: 326 guarded + 11 public).
2026-06-24 19:29:31 +08:00
pnoker 9aa5a6bdb9 security(driver): bind jdbc write value as a parameter to prevent sql injection
The shared JDBC driver base interpolated the point value into the write SQL via
writeQuery.replace("${value}", ...), allowing a crafted write command value to
alter the statement. Bind the value with PreparedStatement#setString against a
single ? placeholder instead. Update the mysql/oracle/postgresql/sqlserver
writeQuery attribute docs to the ? convention and add the module's first test.
2026-06-22 17:59:50 +08:00
pnoker 98f0ac3128 docs(readme): add READMEs for previously undocumented modules
Document 31 modules that had no README: dc3-center-agentic, dc3-e2e,
common modules (agentic, sql, test, resource-registrar) and the facade
subsystem (api/grpc/local-auth/local-data/local-manager), plus 21
drivers. Content is grounded in each module's pom/yaml/source; WIP
skeleton drivers (can, dlms, ethernet-ip, iec104, lwm2m, zigbee) are
flagged as such.
2026-06-22 16:50:08 +08:00
pnoker 49892923bd docs(common): fix thread and mqtt configuration examples
thread: document the three JDK executor beans and the real dc3.thread
keys (the @Async claim was wrong). mqtt: correct the dc3.driver.mqtt
prefix/keys and the Spring Integration + Paho component roles.
2026-06-22 16:49:19 +08:00
pnoker bf8f8fefe9 refactor(manager): move @EnableAsync to ManagerInitRunner auto-config
@EnableAsync was on the business component MetadataEventPublisher; move
it to the module's @AutoConfiguration entry (ManagerInitRunner) so the
async switch lives with config, not a bean. Scope is unchanged.
2026-06-22 16:48:43 +08:00
pnoker c2c9a690a4 fix(common): correctly convert PEM certificates and keys in X509Util
Replace the unsafe (T) cast of PemReader.readPemObject() — which threw
ClassCastException at runtime — with explicit conversion: X.509 certs via
CertificateFactory and private keys (PKCS#1/PKCS#8, encrypted or plain) via
BouncyCastle's PEMParser. Add the bcpkix dependency and unit tests covering
the encrypted-key path used by MQTT TLS.
2026-06-22 16:09:50 +08:00
pnoker f74d16b385 docs(common): fill or drop empty comment placeholders and add missing auth javadoc
Replace bare `//` placeholders with concise intent comments where a
non-obvious reason exists (metadata-event publishing, referential-integrity
delete guards, gRPC registration steps), and remove the rest as leftover
field-group dividers or redundant restatements. Add class-level Javadoc to
12 auth Mapper/Manager/ManagerImpl interfaces to match the repository
convention. Comment-only change across manager, auth, and data modules.
2026-06-22 14:56:57 +08:00
pnoker 5df7998d41 docs(common): tighten javadoc and drop redundant comments across modules
Part of the x-dc3-ai annotation-standard rollout. Complete method/param javadoc (TokenService, RepositoryService, RuleEngine, ...), flag work-in-progress utilities and drivers (X509Util, MQTT/CAN/DLMS/... ) with explicit WARNING notes, and remove redundant inline comments / blank lines from query/VO/ext/constant classes plus mapper indentation. Comment/doc only, no behavior change.
2026-06-22 12:08:11 +08:00
pnoker 141297ddb2 refactor(auth): accept domain BO on oauth write paths
createConnection and registerClient now take an enum-typed BO instead of a VO, so the service layer no longer parses wire strings. McpConnectionAddBO / OAuthClientRegistrationBO (enum principalType/grantType/clientType) are built from the request VO via McpConnectionBuilder.buildBOByAddVO / OAuthClientBuilder.buildBOByRequestVO; the controllers do the VO->BO conversion. The *Record projections stay String/Byte (untouched).

createConnection keeps creator stamping and every client_credentials check (service-account principal, client-SA binding, tenant match). The original 'unsupported client_type' guard is preserved: OAuthClientBuilder.isUnknownClientType lets both register controllers reject a non-blank but unrecognized client_type instead of silently defaulting to PUBLIC.
2026-06-22 11:21:38 +08:00
pnoker e7ff516abd refactor(auth): use domain enums for oauth/mcp VO fields
Replace bare String fields with domain enums on the read-response VOs and in service-internal comparisons, removing scattered McpConstant string literals. Five value-typed enums (OAuthGrantType/OAuthClientType/McpRiskLevel/McpAuditStatus/McpConfirmationStatus) land in common-constant with @EnumValue + @JsonValue + ofValue, registered in IndexedEnumContractTest.

VO fields: McpConnectionVO{principalType,grantType}, McpToolVO.riskLevel, McpAuditVO{principalType,riskLevel,status}, OAuthClientVO.clientType. Builders convert via @AfterMapping (Enum.ofValue); the *Record projections keep String/Byte untouched (OAuthMcpMapper custom-SQL resultType boundary). Service compares/assigns via enum.getValue(); Confirmation.DECISION_* kept (gateway-shared). common-constant gains jackson-annotations because grantType's wire value is lowercase and must serialize via @JsonValue, not the uppercase enum name.
2026-06-22 10:47:43 +08:00
pnoker 43d9175746 fix(auth): manage client_credentials MCP connections by creator
client_credentials connections store the service account as principal_id, but the management ops (list/replace/revoke/listToolIds) authorized on principal_id == caller. The caller is the USER who built the connection while principal_id is the SERVICE_ACCOUNT, so they never matched — the connection's own creator could not list it, set its tool whitelist, or revoke it ("MCP connection does not exist").

Stamp creator_id (the acting user) in createConnection and key the management path on creator_id; the MCP runtime path (service-account bearer token) stays on principal_id. authorization_code connections are unaffected (creator == principal == USER).
2026-06-22 10:25:12 +08:00
pnoker 9e7fd1ca5c feat(auth): add principal list_by_ids endpoint for name resolution
Batch-resolve principals by id (selectBatchIds) returning PrincipalVO with principalName/displayName, so frontend lists can render principalId references as human-readable names instead of raw ids.
2026-06-19 21:26:50 +08:00
pnoker af0f23ad13 fix(auth): make audit log queries postgres-compatible
Replace the (#{x} IS NULL OR ...) optional-filter pattern with MyBatis <if> dynamic SQL in IdentityAuditLogMapper and OAuthMcpMapper. PostgreSQL cannot infer the placeholder type in '? IS NULL', which returned 500 on the identity-audit and mcp-audit list endpoints.
2026-06-19 21:26:50 +08:00
Vickey 5131b37568 build(deploy): add postgres/rabbitmq dependency assets and regenerate openapi snapshots 2026-06-19 16:49:01 +08:00
Vickey 3738ba9e97 fix(auth): read oauth token/revoke form via ServerWebExchange, not @RequestBody
WebFlux does not bind application/x-www-form-urlencoded to
@RequestBody Mono<MultiValueMap> — every token and revocation request
returned 415 Unsupported Media Type, so no MCP client could obtain a bearer
token. Read the form with exchange.getFormData() instead (the canonical WebFlux
form API). Verified end-to-end: client_credentials token issuance now succeeds.
2026-06-19 11:15:29 +08:00
Vickey 5cead0fad7 chore(auth): regenerate openapi snapshots with x-dc3-ai for all 334 endpoints
Regenerate the static openapi-{auth,manager,data,agentic}.json snapshots from
the running dev stack so the auth MCP catalog refresh reads the full
x-dc3-ai quality (riskLevel/destructive/idempotent/openWorld/hidden) for every
endpoint: manager 148, auth 91, data 75, agentic 20 (334/334 annotated).
2026-06-19 09:45:05 +08:00
Vickey c2b4e42855 refactor(auth): reclassify oauth client registration dto as vo
OAuthClientRegistration request/response are REST controller bodies
(@RequestBody and Mono<R<...>> on POST /client/register) that never cross
a gRPC or messaging boundary, so the DTO suffix was misplaced. Move them
into auth.entity.vo (project VO convention is per-module) and drop the
suffix. Kept as plain Serializable rather than extending BaseVO to avoid
injecting audit fields into the OAuth-spec wire payload.
2026-06-19 09:43:56 +08:00
Vickey 1dc0e6b21d chore(model): remove dead CmdParameterDTO
Unreferenced outside its own declaration; duplicates the existing
PointCommandWriteBO write-path input (deviceId/pointId/value fields).
2026-06-19 09:43:56 +08:00
Vickey 74feecdaf4 feat(auth): annotate all endpoints with x-dc3-ai and add ratchet annotation gate 2026-06-19 09:05:59 +08:00
pnoker 56562d485f refactor(auth): move mcp/oauth request payloads to vo/query with mapstruct builders
Replace the McpConnectionToolsReplace/McpToolCatalogList request DTOs (in
dc3-common-model) with McpConnectionToolsReplaceVO/McpToolCatalogQueryVO and a
full set of Mcp/OAuth VOs in dc3-common-auth, wired through MapStruct builders
for VO<->BO mapping, per the project DO/BO/VO convention. Update the
PointValueMapper WindowAggregateRequest reference to WindowAggregateQuery.
2026-06-19 08:51:58 +08:00
pnoker d828b57a03 feat(agentic): annotate all endpoints with x-dc3-ai and add ratchet annotation gate 2026-06-19 08:39:52 +08:00
pnoker 44fa6ac4da feat(data): annotate all endpoints with x-dc3-ai and add ratchet annotation gate 2026-06-19 08:33:08 +08:00
pnoker 04313eb9f8 feat(manager): annotate all endpoints with x-dc3-ai and add ratchet annotation gate 2026-06-19 08:22:07 +08:00
pnoker 27f477abfe docs(auth): clarify toolChanged covers quality columns not identity columns 2026-06-19 08:01:20 +08:00
pnoker e7fc8cf2cb refactor(auth): remove dead inputSchemasByApiCode superseded by toolQualityByApiCode 2026-06-19 07:55:42 +08:00
pnoker b83ccc831a fix(auth): re-catalog mcp tools on quality-only edits in refresh change-detection 2026-06-19 07:52:43 +08:00
pnoker 12d611d315 feat(registrar): add controller annotation gate and make target 2026-06-19 07:48:42 +08:00
pnoker ed589109b3 feat(registrar): validate request body and param descriptions in annotation validator 2026-06-19 07:44:38 +08:00
pnoker 7e103e1db1 refactor(auth): reorganize MCP tool quality mapping and annotation validation 2026-06-19 07:00:49 +08:00
pnoker 2623ace889 fix(auth): persist enable_flag on mcp tool catalog update so hidden toggle applies 2026-06-19 01:24:31 +08:00
pnoker fb84a539e4 feat(manager): annotate list-drivers with x-dc3-ai as path-b canary 2026-06-19 01:18:37 +08:00
pnoker 9d93fd3b9b feat(registrar): add build-time x-dc3-ai annotation validator 2026-06-19 01:11:10 +08:00
pnoker b80909565e refactor(auth): remove legacy scanner-sourced x-dc3-ai path end-to-end 2026-06-19 01:07:13 +08:00
pnoker c6de71beef refactor(auth): drop api_ext ai reads and heuristics from tool candidate sql 2026-06-19 01:00:51 +08:00
pnoker ef2e192cde feat(auth): source mcp tool quality from openapi json at catalog refresh 2026-06-19 00:57:53 +08:00
pnoker 69ada6aabc test(auth): guard api_code format consistency across json and db sides 2026-06-19 00:39:53 +08:00
pnoker 069829f602 feat(auth): parse x-dc3-ai and operation text into ToolQuality 2026-06-19 00:37:20 +08:00
Vickey d8d1367de3 feat(auth): add ToolQuality holder for openapi-sourced tool metadata 2026-06-19 00:34:35 +08:00
Vickey 1ec51b3aff test(auth): tighten x-dc3-ai proof to annotation conversion only
Remove the misleading hand-built model segment that adds extensions then asserts
the serialized JSON. That pattern proves nothing about swagger-core's annotation
pipeline (you're asserting a map you just inserted by hand).

Keep the focused test: read @Operation annotation via reflection, call
AnnotationsUtils.getExtensions(...) which IS swagger-core's real annotation→map
conversion, and assert both the x-dc3-ai key and its riskLevel=HIGH content.

End-to-end emission into /v3/api-docs is verified separately (Task 8).
2026-06-19 00:27:52 +08:00
Vickey 8658d65038 test(auth): prove swagger-core emits x-dc3-ai extension
Use AnnotationsUtils.getExtensions() (swagger-core-jakarta 2.2.47) to convert
@Extension(name="x-dc3-ai") annotation to a map, then serialize to JSON via
Json.pretty(). Proves the full annotation->map->JSON pipeline that McpOpenApiAggregator
will rely on. jaxrs2 Reader is not on the module classpath; this fallback gives the
same assurance without adding new dependencies.
2026-06-19 00:22:13 +08:00
Vickey 3c812a2eee style(data): align javadoc params and license headers
Whitespace-only cleanup (javadoc @param alignment, license header escaping,
import ordering) across the dashboard/window-aggregate data services, repository
query and mcp gateway controller. No behaviour change.
2026-06-19 00:01:41 +08:00
Vickey 1355e6a588 style(auth): fix import order and @Operation summary spacing
Whitespace-only cleanup (import ordering, a missing space after summary=, license
header) in OAuthController, LocalCredentialVO and ServiceAccountServiceImpl.
No behaviour change.
2026-06-19 00:01:32 +08:00
Vickey f21ec89b1f style(agentic): normalize import order and constructor indentation
Whitespace-only cleanup (import ordering, parameter indentation, license header)
in the agentic chat controllers, builders and services. No behaviour change.
2026-06-19 00:01:25 +08:00
Vickey d2c897846c refactor(common): split ResponseEnum into SuccessCode/ErrorCode and align body code with HTTP status
Replace the mixed-purpose ResponseEnum with a ResponseCode interface implemented
by SuccessCode (OK/ADD/DELETE/UPDATE) and ErrorCode (NOT_FOUND/UNAUTHORIZED/
TOKEN_INVALID/IP_INVALID/FORBIDDEN/PASSWORD_*/VALIDATION/OUT_OF_RANGE/FAILURE),
each carrying its HTTP status so the envelope body code and transport status no
longer diverge.

- Introduce abstract BusinessException carrying an ErrorCode; all 23 business
  exceptions extend it and bind a fixed code. ExceptionConfig reads the carried
  code to set both body code and HTTP status (404->R404, 401->R401, 422->R422).
- Add GrpcRFactory (ok/fail/notFound) and remove the hand-written GrpcR builder
  boilerplate across 19 gRPC servers.
- Drop the dead @EnumValue index and ofIndex/ofCode/ofName lookups; OUT_OF_RANGE
  is now carried by OutRangeException.
- Update R factory methods to accept ResponseCode; migrate 90+ controllers,
  11 gRPC facades, OpenAPI specs and README to the split enums.

Also fix several pre-existing red tests surfaced by the full suite:
- OAuthMcpRuntimeServiceImplTest: setUp set @Value fields refactored into
  OAuthProperties; inject the properties object instead.
- DriverReadServiceImplTest: reset leaked ConnectionBackoff static state via a
  new clear() in @BeforeEach.
- modbus-rtu/tcp: make the static modbusFactory non-final so tests can swap it.
- ble: override no-arg health() to report OFFLINE before initialization.
- PlcS7/facade-local tests: expect the thrown exception / use the single-arg
  overload matching production behaviour.
- Remove a duplicate dc3-common-constant dependency in dc3-common-data/pom.xml.
2026-06-18 23:53:41 +08:00
Vickey 8f18652629 refactor(constant): move WindowModeEnum to dc3-common-constant 2026-06-18 22:08:33 +08:00
Vickey 694ebad0ba refactor(repository): replace WindowAggregateRequest with WindowAggregateQuery
- Add WindowAggregateFunction enum and WindowAggregateQuery to repository module
- Remove WindowAggregateRequest, update RepositoryService signatures
- Adapt PointValueMapper, PostgresRepositoryServiceImpl, and related tests
2026-06-18 22:08:30 +08:00
Vickey da601b12a0 refactor(agentic): rename Response classes to VO 2026-06-18 22:08:24 +08:00
Vickey 2f646bf3ea docs(gateway): add openapi operations and javadoc to mcp gateway
Add @Operation to the MCP gateway endpoints (protected-resource metadata, JSON-RPC handler) and behavior-accurate method JavaDoc. Docs only, no logic changes.
2026-06-18 20:14:16 +08:00