mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-21 09:10:48 +00:00
Merge pull request #2293 from proller/fix19
`clickhouse-client`: option --ask-password for interactively ask for credentials #1044
This commit is contained in:
commit
2b581ed2c3
11
CHANGELOG.draft.md
Normal file
11
CHANGELOG.draft.md
Normal file
@ -0,0 +1,11 @@
|
||||
en:
|
||||
|
||||
## Improvements:
|
||||
* `clickhouse-client`: option --ask-password for interactively ask for credentials #1044
|
||||
|
||||
|
||||
|
||||
ru:
|
||||
|
||||
## Улучшения:
|
||||
* `clickhouse-client`: опция --ask-password для интерактивного ввода пароля #1044
|
@ -15,6 +15,7 @@
|
||||
#include <Poco/Util/Application.h>
|
||||
#include <common/readline_use.h>
|
||||
#include <common/find_first_symbols.h>
|
||||
#include <common/SetTerminalEcho.h>
|
||||
#include <Common/ClickHouseRevision.h>
|
||||
#include <Common/Stopwatch.h>
|
||||
#include <Common/Exception.h>
|
||||
@ -52,6 +53,7 @@
|
||||
#include "InterruptListener.h"
|
||||
#include <Functions/registerFunctions.h>
|
||||
#include <AggregateFunctions/registerAggregateFunctions.h>
|
||||
#include <ext/scope_guard.h>
|
||||
|
||||
|
||||
/// http://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
@ -197,7 +199,25 @@ private:
|
||||
|
||||
default_database = config.getString("database", "");
|
||||
user = config.getString("user", "");
|
||||
|
||||
if (config.getBool("ask-password", false))
|
||||
{
|
||||
if (config.has("password"))
|
||||
throw Exception("Specified both --password and --ask-password. Remove one of them", ErrorCodes::BAD_ARGUMENTS);
|
||||
|
||||
std::cout << "Password for user " << user << ": ";
|
||||
SetTerminalEcho(false);
|
||||
|
||||
SCOPE_EXIT({
|
||||
SetTerminalEcho(true);
|
||||
});
|
||||
std::getline(std::cin, password);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
password = config.getString("password", "");
|
||||
}
|
||||
|
||||
compression = config.getBool("compression", true)
|
||||
? Protocol::Compression::Enable
|
||||
@ -1375,8 +1395,9 @@ public:
|
||||
("host,h", boost::program_options::value<std::string>()->default_value("localhost"), "server host")
|
||||
("port", boost::program_options::value<int>()->default_value(9000), "server port")
|
||||
("secure,s", "secure")
|
||||
("user,u", boost::program_options::value<std::string>(), "user")
|
||||
("user,u", boost::program_options::value<std::string>()->default_value("default"), "user")
|
||||
("password", boost::program_options::value<std::string>(), "password")
|
||||
("ask-password", "ask-password")
|
||||
("query_id", boost::program_options::value<std::string>(), "query_id")
|
||||
("query,q", boost::program_options::value<std::string>(), "query")
|
||||
("database,d", boost::program_options::value<std::string>(), "database")
|
||||
@ -1483,7 +1504,8 @@ public:
|
||||
config().setString("user", options["user"].as<std::string>());
|
||||
if (options.count("password"))
|
||||
config().setString("password", options["password"].as<std::string>());
|
||||
|
||||
if (options.count("ask-password"))
|
||||
config().setBool("ask-password", true);
|
||||
if (options.count("multiline"))
|
||||
config().setBool("multiline", true);
|
||||
if (options.count("multiquery"))
|
||||
|
@ -27,6 +27,7 @@ add_library (common ${SPLIT_SHARED}
|
||||
src/getMemoryAmount.cpp
|
||||
src/ThreadPool.cpp
|
||||
src/demangle.cpp
|
||||
src/SetTerminalEcho.cpp
|
||||
|
||||
include/common/Types.h
|
||||
include/common/DateLUT.h
|
||||
@ -46,6 +47,7 @@ add_library (common ${SPLIT_SHARED}
|
||||
include/common/getMemoryAmount.h
|
||||
include/common/ThreadPool.h
|
||||
include/common/demangle.h
|
||||
include/common/SetTerminalEcho.h
|
||||
|
||||
include/ext/bit_cast.h
|
||||
include/ext/collection_cast.h
|
||||
|
4
libs/libcommon/include/common/SetTerminalEcho.h
Normal file
4
libs/libcommon/include/common/SetTerminalEcho.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
/// Enable or disable echoing of typed characters. Throws std::runtime_error on error.
|
||||
void SetTerminalEcho(bool enable);
|
42
libs/libcommon/src/SetTerminalEcho.cpp
Normal file
42
libs/libcommon/src/SetTerminalEcho.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
// https://stackoverflow.com/questions/1413445/reading-a-password-from-stdcin
|
||||
|
||||
#include <common/SetTerminalEcho.h>
|
||||
#include <stdexcept>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
void SetTerminalEcho(bool enable)
|
||||
{
|
||||
#ifdef WIN32
|
||||
auto handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
DWORD mode;
|
||||
if (!GetConsoleMode(handle, &mode))
|
||||
throw std::runtime_error(std::string("SetTerminalEcho failed get: ") + std::to_string(GetLastError()));
|
||||
|
||||
if (!enable)
|
||||
mode &= ~ENABLE_ECHO_INPUT;
|
||||
else
|
||||
mode |= ENABLE_ECHO_INPUT;
|
||||
|
||||
if (!SetConsoleMode(handle, mode))
|
||||
throw std::runtime_error(std::string("SetTerminalEcho failed set: ") + std::to_string(GetLastError()));
|
||||
#else
|
||||
struct termios tty;
|
||||
if (tcgetattr(STDIN_FILENO, &tty))
|
||||
throw std::runtime_error(std::string("SetTerminalEcho failed get: ") + strerror(errno));
|
||||
if (!enable)
|
||||
tty.c_lflag &= ~ECHO;
|
||||
else
|
||||
tty.c_lflag |= ECHO;
|
||||
|
||||
auto ret = tcsetattr(STDIN_FILENO, TCSANOW, &tty);
|
||||
if (ret)
|
||||
throw std::runtime_error(std::string("SetTerminalEcho failed set: ") + strerror(errno));
|
||||
#endif
|
||||
}
|
Loading…
Reference in New Issue
Block a user