dbeaver/cloudbeaver#4564 change db user password - #4586
Conversation
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Duplication | 0 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
|
Hello @TobyTheHutt Thanks for the contribution. |
There was a problem hiding this comment.
Pull request overview
Adds database-user password changes for editable connections, gated by server configuration.
Changes:
- Adds the connection security menu and password dialog.
- Adds the GraphQL mutation, driver-adapter dispatch, persistence, and audit events.
- Adds an administrator-controlled feature flag.
Reviewed changes
Copilot reviewed 26 out of 28 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
webapp/yarn.lock |
Updates a local package checksum. |
webapp/packages/plugin-connections/src/locales/en.ts |
Adds password-dialog strings. |
webapp/packages/plugin-connections/src/ContextMenu/MENU_CONNECTION_SECURITY.ts |
Defines the Security submenu. |
webapp/packages/plugin-connections/src/ContextMenu/ConnectionMenuBootstrap.ts |
Registers the menu action and dialog. |
webapp/packages/plugin-connections/src/ContextMenu/ChangeDatabasePasswordDialog/ChangeDatabasePasswordDialog.tsx |
Implements the password form and mutation call. |
webapp/packages/plugin-connections/src/ContextMenu/Actions/ACTION_CONNECTION_CHANGE_DB_PASSWORD.ts |
Defines the password-change action. |
webapp/packages/plugin-administration/src/locales/en.ts |
Adds administration labels. |
webapp/packages/plugin-administration/src/ConfigurationWizard/ServerConfiguration/ServerConfigurationFormPart.ts |
Loads the feature flag state. |
webapp/packages/plugin-administration/src/ConfigurationWizard/ServerConfiguration/IServerConfigurationFormPartState.ts |
Extends configuration validation. |
webapp/packages/plugin-administration/src/ConfigurationWizard/ServerConfiguration/Form/ServerConfigurationSecurityForm.tsx |
Adds the security toggle. |
webapp/packages/core-sdk/src/queries/fragments/ServerConfig/ServerConfig.gql |
Queries the feature flag. |
webapp/packages/core-sdk/src/queries/connections/changeConnectionUserPassword.gql |
Defines the client mutation. |
webapp/packages/core-root/src/ServerConfigResource.ts |
Exposes the feature flag. |
server/bundles/io.cloudbeaver.service.admin/schema/service.admin.graphqls |
Extends admin configuration input. |
server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java |
Binds the mutation resolver. |
server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java |
Implements password changes and auditing. |
server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/DBWServiceCore.java |
Declares the secured service method. |
server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSSecurityAuditEventHandler.java |
Logs audit events. |
server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSSecurityAuditEvent.java |
Defines audit payloads. |
server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebServerConfig.java |
Publishes the feature flag. |
server/bundles/io.cloudbeaver.server/schema/service.core.graphqls |
Adds the flag and mutation schema. |
server/bundles/io.cloudbeaver.server/plugin.xml |
Registers the audit handler. |
server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBServerConfigurationMapper.java |
Maps the flag into application configuration. |
server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBServerConfigurationController.java |
Persists the flag. |
server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/model/config/AdminServerConfig.java |
Models the admin flag. |
server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/WebConnectionInfo.java |
Removes trailing whitespace. |
server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/config/CBAppConfig.java |
Stores the feature flag. |
server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/WebAppConfiguration.java |
Adds the configuration interface default. |
Suppressed comments (1)
server/bundles/io.cloudbeaver.server/schema/service.core.graphqls:918
- This new public mutation is missing the required
@sincedirective.
): Boolean!
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
I looked at the Copilot feedback and commented or reacted to it based on my personal judgement. I'll provide a follow-up commit after the human maintainer review and further instructions. This PR should not directly close the linked issue. It only covers the DB user password change. It does not yet cover the password-change prompt upon an expired DB user password, which was the original intent of the linked issue. If any rephrasing or re-specification of the issue is desired, let me know and I'll be on it. |
| import org.jkiss.code.Nullable; | ||
| import org.jkiss.dbeaver.model.websocket.event.WSAbstractEvent; | ||
|
|
||
| public class WSSecurityAuditEvent extends WSAbstractEvent { |
There was a problem hiding this comment.
Do we need that class? I think it would be better just write logs as usual by using Log.getLog(Class.class)
There was a problem hiding this comment.
The WSSecurityAuditEventHandler writes a structured log line and prints machine readable fields like kind, reasonCode, connectionId, driverId or errorClass, rather than just plaintext. It also adds the capability for future WebSocket subscriptions and ensures consistend vocabulary with other CB EventBus consumers.
log.info does not provide this, which is why I decided for this approach and continue to recommend it. Let me know if you concur of whether you want me to fall back to log.info anyway.
| import org.jkiss.dbeaver.Log; | ||
| import org.jkiss.dbeaver.model.websocket.WSEventHandler; | ||
|
|
||
| public class WSSecurityAuditEventHandler implements WSEventHandler<WSSecurityAuditEvent> { |
There was a problem hiding this comment.
See #4586 (comment). Please confirm you really don't want it, before I just fall back.
| // ASCII space (0x20) is the first printable character. Anything below is a control character. | ||
| private static final int FIRST_PRINTABLE_ASCII = 0x20; | ||
|
|
||
| private static boolean containsBlockedPasswordChar(String password) { |
There was a problem hiding this comment.
Not sure we need this kind of validation. Moreover, there are also non-printable characters above 0x20.
There was a problem hiding this comment.
This is a potential security concern because some DBs parse those control sequences. There are indeed other non-printable characters above these values, but they are not parsed the same way. Especially NUL (0x00) and characters that could cause JDBC driver string truncation or or SQL injection via control sequences are of concern here.
The risk is low and I can drop it. I just decided to add it because it's a low-cost hardening. Please confirm how I should proceed here.
| return false; | ||
| } | ||
|
|
||
| private void emitPasswordChangeAudit( |
There was a problem hiding this comment.
Relates to #4586 (comment). This is the helper that dispatches WSSecurityAuditEvent. I'll act upon your comment depending on how the other discussions are resolved.
| ensureConnected(webSession, container, projectId, connectionId); | ||
| DBAUserPasswordManager manager = resolveUserPasswordManager(webSession, container, projectId, connectionId); | ||
| String userName = resolveUserName(webSession, container, projectId, connectionId); | ||
| applyPasswordChange(webSession, container, projectId, connectionId, manager, userName, oldPassword, newPassword); |
There was a problem hiding this comment.
Not sure we need to use an approach like this. Usually, we try to reuse code that already exists in the DBeaver repository. For example, in this case, it would be better to use DBAuthUtils#promptAndChangePasswordForCurrentUser with some adjustments.
There was a problem hiding this comment.
I'd have to add it to the classpath, which is feasible. Please confirm that this is what you meant by "some adjustments" and I'll be on it.
|
@yagudin10, @devnaumov I closed some conversations and added some comments to others, in which I need clarifications or a confirmation. Please check my actions and review my comments. I'll wait for your feedback and prepare the other code changes in the meantime. |
Signed-off-by: Tobias Harnickell <tobias.harnickell@bedag.ch>
Signed-off-by: Tobias Harnickell <tobias.harnickell@bedag.ch>
68c1bf5 to
33dce9d
Compare
|
@yagudin10 committed the feedback where I was confident about what change is required. Update me on the open comments and I'll do the rest. |
Summary
Relates to #4564
Adds a
Security > Change database passwordcontext-menu action on connections. The action opens a modal dialog and calls a new GraphQL mutation that invokes the DBeaver coreDBAUserPasswordManageradapter of the connected driver.Design
dbUserPasswordChangeEnabledgates the mutation server-wide. Default isfalse. Persistence goes throughCBAppConfig,AdminServerConfig,CBServerConfigurationController,CBServerConfigurationMapper, andWebServerConfig. Admin toggle lives in Configuration Wizard > Security.changeConnectionUserPassword(projectId: ID, connectionId: ID!, oldPassword: String!, newPassword: String!): Boolean!. Guard:@WebProjectAction(requireProjectPermissions = {PERMISSION_PROJECT_DATASOURCES_EDIT}). Both password parameters carry@WebParameterSecureto keep them out of logs.DBWebExceptionwrapping the driver's exception. Callers receive the original SQL state, message, and cause chain.connection.canEditis true. Backend re-checks the project permission on every call.cb_security_audittopic with kindsATTEMPTED,SUCCEEDED,FAILED, andGATE_REJECTED. Payload carriessessionId,userId,projectId,connectionId,driverId,kind,reasonCode,errorClass. No plaintext passwords.Screenshots:
Details
PW-Reset Flag:
PW-Change navigation:
PW-Change dialog:
PW-Change confirmation:

Engine coverage
Dispatch runs through the DBeaver core
DBAUserPasswordManageradapter. Verified against Oracle 21c XE, PostgreSQL 16, and SQL Server 2022. Engines whose driver ships an adapter (Greenplum, CockroachDB, Exasol, Vertica) inherit support without further code changes. Drivers without an adapter (H2, MySQL) returnGATE_REJECTED reasonCode=DIALECT_UNSUPPORTEDin the audit trail andThis driver does not support password change from CloudBeaver.in the notification.Out of scope
ORA-28001, MySQL1820, SQL Server18488).Test plan
Enable database user password changein Configuration Wizard or Server Administration > Security.Security > Change database password. Submitoldpw,newpw,newpw. Reconnect withnewpwsucceeds. Reconnect witholdpwreturnsSQLSTATE 28P01or technology equivalent.Securitysubmenu is absent.datasources-editon the project sees no menu. Direct GraphQL mutation returns a permission-denied response.ORA-28008: invalid old password. On SQL Server:Msg 15116.This driver does not support password change from CloudBeaver.. Audit linekind=GATE_REJECTED reasonCode=DIALECT_UNSUPPORTED.docker logs cloudbeaver-dev | grep cb_security_auditshows oneATTEMPTED+ oneSUCCEEDEDper successful change,ATTEMPTED+FAILEDwitherrorClasson driver rejection, and no plaintext passwords.