提交 5c5a8bc6 编写于 作者: S serge-rider

#3365 Password change model and UI. Oracle expired password change.

上级 68c85ec1
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
* Copyright (C) 2010-2018 Serge Rider (serge@jkiss.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -144,6 +144,7 @@ public class OracleConstants {
* Oracle error codes
*/
public static final int EC_FEATURE_NOT_SUPPORTED = 17023;
public static final int EC_PASSWORD_EXPIRED = 28001;
/**
* Connection type
......
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
* Copyright (C) 2010-2018 Serge Rider (serge@jkiss.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -24,6 +24,7 @@ import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.ModelPreferences;
import org.jkiss.dbeaver.ext.oracle.model.plan.OraclePlanAnalyser;
import org.jkiss.dbeaver.model.*;
import org.jkiss.dbeaver.model.access.DBAPasswordChangeInfo;
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
import org.jkiss.dbeaver.model.exec.*;
import org.jkiss.dbeaver.model.exec.jdbc.*;
......@@ -41,16 +42,14 @@ import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.sql.SQLConstants;
import org.jkiss.dbeaver.model.sql.SQLState;
import org.jkiss.dbeaver.model.struct.*;
import org.jkiss.dbeaver.runtime.ui.DBUserInterface;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.dbeaver.utils.GeneralUtils;
import org.jkiss.utils.CommonUtils;
import org.jkiss.utils.StandardConstants;
import java.io.PrintWriter;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Types;
import java.sql.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
......@@ -130,19 +129,69 @@ public class OracleDataSource extends JDBCDataSource
}
*/
Connection connection = super.openConnection(monitor, purpose);
try {
Connection connection = super.openConnection(monitor, purpose);
// Client name is set in connection properties
/*
OracleConnection oracleConnection = (OracleConnection)connection.getConnection();
if (!getContainer().getPreferenceStore().getBoolean(ModelPreferences.META_CLIENT_NAME_DISABLE)) {
// Provide client info
try {
connection.setClientInfo("ApplicationName", DBUtils.getClientApplicationName(getContainer(), purpose));
} catch (Throwable e) {
// just ignore
log.debug(e);
}
}
*/
try {
oracleConnection.setClientInfo("ApplicationName", DBeaverCore.getProductTitle() + " - " + purpose);
} catch (Throwable e) {
// just ignore
log.debug(e);
return connection;
} catch (DBCException e) {
if (e.getErrorCode() == OracleConstants.EC_PASSWORD_EXPIRED) {
// Here we could try to ask for expired password change
// This is supported for thin driver since Oracle 12.2
if (changeExpiredPassword(monitor)) {
// Retry
return openConnection(monitor, purpose);
}
}
throw e;
}
*/
}
return connection;
private boolean changeExpiredPassword(DBRProgressMonitor monitor) {
DBPConnectionConfiguration connectionInfo = getContainer().getActualConnectionConfiguration();
DBAPasswordChangeInfo passwordInfo = DBUserInterface.getInstance().promptUserPasswordChange("Password has expired. Set new password.", connectionInfo.getUserName(), connectionInfo.getUserPassword());
if (passwordInfo == null) {
return false;
}
// Obtain connection
try {
if (passwordInfo.getNewPassword() == null) {
throw new DBException("You can't set empty password");
}
Properties connectProps = getAllConnectionProperties(monitor, connectionInfo);
connectProps.setProperty("oracle.jdbc.newPassword", passwordInfo.getNewPassword());
final String url = getConnectionURL(connectionInfo);
monitor.subTask("Connecting for expired password change");
Driver driverInstance = getDriverInstance(monitor);
try (Connection connection = driverInstance.connect(url, connectProps)) {
if (connection == null) {
throw new DBCException("Null connection returned");
}
}
connectionInfo.setUserPassword(passwordInfo.getNewPassword());
getContainer().getConnectionConfiguration().setUserPassword(passwordInfo.getNewPassword());
getContainer().getRegistry().flushConfig();
return true;
}
catch (Exception e) {
DBUserInterface.getInstance().showError("Error changing password", "Error changing expired password", e);
return false;
}
}
protected void initializeContextState(@NotNull DBRProgressMonitor monitor, @NotNull JDBCExecutionContext context, boolean setActiveObject) throws DBCException {
......@@ -756,7 +805,7 @@ public class OracleDataSource extends JDBCDataSource
@Override
protected JDBCStatement prepareObjectsStatement(@NotNull JDBCSession session, @NotNull OracleDataSource owner) throws SQLException {
return session.prepareStatement(
"SELECT * FROM SYS.ALL_TYPES WHERE OWNER IS NULL ORDER BY TYPE_NAME");
"SELECT " + OracleUtils.getSysCatalogHint(owner.getDataSource()) + " * FROM SYS.ALL_TYPES WHERE OWNER IS NULL ORDER BY TYPE_NAME");
}
@Override
......
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2018 Serge Rider (serge@jkiss.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jkiss.dbeaver.model.access;
/**
* Password change info
*/
public class DBAPasswordChangeInfo {
private String userName;
private String oldPassword;
private String newPassword;
public DBAPasswordChangeInfo() {
}
public DBAPasswordChangeInfo(String userName, String oldPassword) {
this.userName = userName;
this.oldPassword = oldPassword;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getOldPassword() {
return oldPassword;
}
public void setOldPassword(String oldPassword) {
this.oldPassword = oldPassword;
}
public String getNewPassword() {
return newPassword;
}
public void setNewPassword(String newPassword) {
this.newPassword = newPassword;
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
* Copyright (C) 2010-2018 Serge Rider (serge@jkiss.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -127,35 +127,8 @@ public abstract class JDBCDataSource
}
DBPConnectionConfiguration connectionInfo = container.getActualConnectionConfiguration();
Properties connectProps = getAllConnectionProperties(monitor, connectionInfo);
// Set properties
Properties connectProps = new Properties();
{
// Use properties defined by datasource itself
Map<String,String> internalProps = getInternalConnectionProperties(monitor, purpose, connectionInfo);
if (internalProps != null) {
connectProps.putAll(internalProps);
}
}
{
// Use driver properties
final Map<Object, Object> driverProperties = container.getDriver().getConnectionProperties();
for (Map.Entry<Object,Object> prop : driverProperties.entrySet()) {
connectProps.setProperty(CommonUtils.toString(prop.getKey()), CommonUtils.toString(prop.getValue()));
}
}
for (Map.Entry<String, String> prop : connectionInfo.getProperties().entrySet()) {
connectProps.setProperty(CommonUtils.toString(prop.getKey()), CommonUtils.toString(prop.getValue()));
}
if (!CommonUtils.isEmpty(connectionInfo.getUserName())) {
connectProps.put(DBConstants.DATA_SOURCE_PROPERTY_USER, getConnectionUserName(connectionInfo));
}
if (!CommonUtils.isEmpty(connectionInfo.getUserPassword())) {
connectProps.put(DBConstants.DATA_SOURCE_PROPERTY_PASSWORD, getConnectionUserPassword(connectionInfo));
}
// Obtain connection
try {
final String url = getConnectionURL(connectionInfo);
......@@ -198,6 +171,38 @@ public abstract class JDBCDataSource
}
}
protected Properties getAllConnectionProperties(@NotNull DBRProgressMonitor monitor, DBPConnectionConfiguration connectionInfo) throws DBCException {
// Set properties
Properties connectProps = new Properties();
{
// Use properties defined by datasource itself
Map<String,String> internalProps = getInternalConnectionProperties(monitor, "Get connection prop[erties", connectionInfo);
if (internalProps != null) {
connectProps.putAll(internalProps);
}
}
{
// Use driver properties
final Map<Object, Object> driverProperties = container.getDriver().getConnectionProperties();
for (Map.Entry<Object,Object> prop : driverProperties.entrySet()) {
connectProps.setProperty(CommonUtils.toString(prop.getKey()), CommonUtils.toString(prop.getValue()));
}
}
for (Map.Entry<String, String> prop : connectionInfo.getProperties().entrySet()) {
connectProps.setProperty(CommonUtils.toString(prop.getKey()), CommonUtils.toString(prop.getValue()));
}
if (!CommonUtils.isEmpty(connectionInfo.getUserName())) {
connectProps.put(DBConstants.DATA_SOURCE_PROPERTY_USER, getConnectionUserName(connectionInfo));
}
if (!CommonUtils.isEmpty(connectionInfo.getUserPassword())) {
connectProps.put(DBConstants.DATA_SOURCE_PROPERTY_PASSWORD, getConnectionUserPassword(connectionInfo));
}
return connectProps;
}
protected String getConnectionURL(DBPConnectionConfiguration connectionInfo) {
String url = connectionInfo.getUrl();
if (CommonUtils.isEmpty(url)) {
......
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
* Copyright (C) 2010-2018 Serge Rider (serge@jkiss.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -21,6 +21,7 @@ import org.eclipse.core.runtime.IStatus;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.model.access.DBAAuthInfo;
import org.jkiss.dbeaver.model.access.DBAPasswordChangeInfo;
import org.jkiss.dbeaver.model.runtime.DBRProcessDescriptor;
/**
......@@ -40,8 +41,16 @@ public interface DBPPlatformUI {
UserResponse showError(@NotNull final String title, @Nullable final String message, @NotNull final Throwable e);
UserResponse showError(@NotNull final String title, @Nullable final String message);
/**
* Asks for user credentials. Returns null if user canceled this action.
*/
DBAAuthInfo promptUserCredentials(String prompt, String userName, String userPassword, boolean passwordOnly);
/**
* Asks for password change. Returns null if user canceled this action.
*/
DBAPasswordChangeInfo promptUserPasswordChange(String prompt, @Nullable String userName, @Nullable String oldPassword);
void executeProcess(DBRProcessDescriptor processDescriptor);
void executeInUI(Runnable runnable);
......
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
* Copyright (C) 2010-2018 Serge Rider (serge@jkiss.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -22,6 +22,7 @@ import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.access.DBAAuthInfo;
import org.jkiss.dbeaver.model.access.DBAPasswordChangeInfo;
import org.jkiss.dbeaver.model.runtime.DBRProcessDescriptor;
/**
......@@ -66,6 +67,11 @@ public class DBUserInterface {
return null;
}
@Override
public DBAPasswordChangeInfo promptUserPasswordChange(String prompt, String userName, String oldPassword) {
return null;
}
@Override
public void executeProcess(DBRProcessDescriptor processDescriptor) {
try {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册