SyncConfig: simplify password API

In practice, the methods are always called for a specific SyncConfig.
Passing that allows removing several other parameters and, more
importantly, also grants access to the config and through that other
configs. This will be needed for the indirect credential lookup.
This commit is contained in:
Patrick Ohly 2013-07-26 11:56:18 +02:00
parent c1808f72aa
commit 37b03d5e8d
6 changed files with 71 additions and 106 deletions

View File

@ -180,7 +180,7 @@ void ReadOperations::getNamedConfig(const std::string &configName,
//try to check password and read password from gnome keyring if possible
ConfigPropertyRegistry& registry = SyncConfig::getRegistry();
BOOST_FOREACH(const ConfigProperty *prop, registry) {
prop->checkPassword(ui, configName, *dbusConfig->getProperties());
prop->checkPassword(ui, *dbusConfig);
}
list<string> configuredSources = dbusConfig->getSyncSources();
BOOST_FOREACH(const string &sourceName, configuredSources) {
@ -188,8 +188,7 @@ void ReadOperations::getNamedConfig(const std::string &configName,
SyncSourceNodes sourceNodes = dbusConfig->getSyncSourceNodes(sourceName);
BOOST_FOREACH(const ConfigProperty *prop, registry) {
prop->checkPassword(ui, configName, *dbusConfig->getProperties(),
sourceName, sourceNodes.getProperties());
prop->checkPassword(ui, *dbusConfig, sourceName);
}
}
syncConfig = dbusConfig.get();

View File

@ -658,23 +658,16 @@ void Cmdline::checkSyncPasswords(SyncContext &context)
{
ConfigPropertyRegistry& registry = SyncConfig::getRegistry();
BOOST_FOREACH(const ConfigProperty *prop, registry) {
prop->checkPassword(context.getUserInterfaceNonNull(),
context.getConfigName(),
*context.getProperties());
prop->checkPassword(context.getUserInterfaceNonNull(), context);
}
}
void Cmdline::checkSourcePasswords(SyncContext &context,
const std::string &sourceName,
SyncSourceNodes &nodes)
const std::string &sourceName)
{
ConfigPropertyRegistry &registry = SyncSourceConfig::getRegistry();
BOOST_FOREACH(const ConfigProperty *prop, registry) {
prop->checkPassword(context.getUserInterfaceNonNull(),
context.getConfigName(),
*context.getProperties(),
sourceName,
nodes.getProperties());
prop->checkPassword(context.getUserInterfaceNonNull(), context, sourceName);
}
}
@ -831,7 +824,7 @@ bool Cmdline::run() {
if (!m_server.empty() && nodes) {
// ensure that we have passwords for this config
checkSyncPasswords(*context);
checkSourcePasswords(*context, sourceName, *nodes);
checkSourcePasswords(*context, sourceName);
}
(this->*operation)(source.get(), header);
} else {
@ -1385,7 +1378,7 @@ bool Cmdline::run() {
#define CHECK_ERROR(_op) if (err) { SE_THROW_EXCEPTION_STATUS(StatusException, string(source->getName()) + ": " + (_op), SyncMLStatus(err)); }
checkSyncPasswords(*context);
checkSourcePasswords(*context, source->getName(), sourceNodes);
checkSourcePasswords(*context, source->getName());
source->setNeedChanges(false);
source->open();
const SyncSource::Operations &ops = source->getOperations();

View File

@ -337,8 +337,7 @@ protected:
static void checkSyncPasswords(SyncContext &context);
static void checkSourcePasswords(SyncContext &context,
const std::string &sourceName,
SyncSourceNodes &nodes);
const std::string &sourceName);
};

View File

@ -945,7 +945,7 @@ void SyncConfig::preFlush(UserInterface &ui)
/* save password in the global config node */
ConfigPropertyRegistry& registry = getRegistry();
BOOST_FOREACH(const ConfigProperty *prop, registry) {
prop->savePassword(ui, m_peer, *getProperties());
prop->savePassword(ui, *this);
}
/** grep each source and save their password */
@ -956,8 +956,7 @@ void SyncConfig::preFlush(UserInterface &ui)
SyncSourceNodes sourceNodes = getSyncSourceNodes(sourceName);
BOOST_FOREACH(const ConfigProperty *prop, registry) {
prop->savePassword(ui, m_peer, *getProperties(),
sourceName, sourceNodes.getProperties());
prop->savePassword(ui, *this, sourceName);
}
}
}
@ -1234,18 +1233,11 @@ public:
" ask : password = -\n"
" env variable: password = ${<name of environment variable>}\n")
{}
virtual void checkPassword(UserInterface &ui,
const std::string &serverName,
FilterConfigNode &globalConfigNode,
const std::string &sourceName,
const boost::shared_ptr<FilterConfigNode> &sourceConfigNode) const {
PasswordConfigProperty::checkPassword(ui,
syncPropUsername,
serverName,
globalConfigNode,
sourceName,
sourceConfigNode);
SyncConfig &config,
const std::string &sourceName = "") const {
PasswordConfigProperty::checkPassword(ui, config, syncPropUsername, sourceName);
}
ConfigPasswordKey getPasswordKey(const string &descr,
@ -1318,18 +1310,11 @@ public:
* before retrieving proxy password
*/
virtual void checkPassword(UserInterface &ui,
const std::string &serverName,
FilterConfigNode &globalConfigNode,
const std::string &sourceName,
const boost::shared_ptr<FilterConfigNode> &sourceConfigNode) const {
SyncConfig &config,
const std::string &sourceName = std::string()) const {
/* if useProxy is set 'true', then check proxypassword */
if(syncPropUseProxy.getPropertyValue(globalConfigNode)) {
PasswordConfigProperty::checkPassword(ui,
syncPropProxyUsername,
serverName,
globalConfigNode,
sourceName,
sourceConfigNode);
if (config.getUseProxy()) {
PasswordConfigProperty::checkPassword(ui, config, syncPropProxyUsername, sourceName);
}
}
virtual ConfigPasswordKey getPasswordKey(const std::string &descr,
@ -1855,13 +1840,21 @@ InitStateString SyncConfig::getSyncPassword() const {
return syncPropPassword.getProperty(*getNode(syncPropPassword));
}
void PasswordConfigProperty::checkPassword(UserInterface &ui,
SyncConfig &config,
const ConfigProperty &usernameProperty,
const string &serverName,
FilterConfigNode &globalConfigNode,
const string &sourceName,
const boost::shared_ptr<FilterConfigNode> &sourceConfigNode) const
const std::string &sourceName) const
{
InitStateString username = usernameProperty.getProperty(sourceConfigNode ? *sourceConfigNode : globalConfigNode);
std::string serverName = config.getConfigName();
boost::shared_ptr<FilterConfigNode> globalConfigNode = config.getProperties();
boost::shared_ptr<FilterConfigNode> sourceConfigNode;
if (!sourceName.empty()) {
sourceConfigNode = config.getSyncSourceNodes(sourceName).getNode(*this);
}
InitStateString username = usernameProperty.getProperty(sourceConfigNode ? *sourceConfigNode : *globalConfigNode);
SE_LOG_DEBUG(NULL, "checking password property '%s' in config '%s' with user identity '%s'",
getMainName().c_str(),
serverName.c_str(),
username.c_str());
UserIdentity identity(UserIdentity::fromString(username));
if (identity.m_provider == USER_IDENTITY_SYNC_CONFIG) {
@ -1879,14 +1872,14 @@ void PasswordConfigProperty::checkPassword(UserInterface &ui,
string password, passwordSave;
/* if no source config node, then it should only be password in the global config node */
if(sourceConfigNode.get() == NULL) {
password = getProperty(globalConfigNode);
password = getProperty(*globalConfigNode);
} else {
password = getProperty(*sourceConfigNode);
}
string descr = getDescr(serverName,globalConfigNode,sourceName,sourceConfigNode);
string descr = getDescr(serverName,*globalConfigNode,sourceName,sourceConfigNode);
if (password == "-") {
ConfigPasswordKey key = getPasswordKey(descr,serverName,globalConfigNode,sourceName,sourceConfigNode);
ConfigPasswordKey key = getPasswordKey(descr,serverName,*globalConfigNode,sourceName,sourceConfigNode);
passwordSave = ui.askPassword(getMainName(),descr, key);
} else if(boost::starts_with(password, "${") &&
boost::ends_with(password, "}")) {
@ -1906,7 +1899,7 @@ void PasswordConfigProperty::checkPassword(UserInterface &ui,
* Previous impl use temp string to store them, this is not good for expansion in the backend */
if(!passwordSave.empty()) {
if(sourceConfigNode.get() == NULL) {
globalConfigNode.addFilter(getMainName(), InitStateString(passwordSave, true));
globalConfigNode->addFilter(getMainName(), InitStateString(passwordSave, true));
} else {
sourceConfigNode->addFilter(getMainName(), InitStateString(passwordSave, true));
}
@ -1922,17 +1915,22 @@ std::string PasswordConfigProperty::getUsername(const ConfigProperty &usernamePr
}
void PasswordConfigProperty::savePassword(UserInterface &ui,
const string &serverName,
FilterConfigNode &globalConfigNode,
const string &sourceName,
const boost::shared_ptr<FilterConfigNode> &sourceConfigNode) const
SyncConfig &config,
const std::string &sourceName) const
{
std::string serverName = config.getConfigName();
boost::shared_ptr<FilterConfigNode> globalConfigNode = config.getProperties();
boost::shared_ptr<FilterConfigNode> sourceConfigNode;
if (!sourceName.empty()) {
sourceConfigNode = config.getSyncSourceNodes(sourceName).getNode(*this);
}
// TODO: support identities
/** here we don't invoke askPassword for this function has different logic from it */
string password;
if(sourceConfigNode.get() == NULL) {
password = getProperty(globalConfigNode);
password = getProperty(*globalConfigNode);
} else {
password = getProperty(*sourceConfigNode);
}
@ -1945,12 +1943,12 @@ void PasswordConfigProperty::savePassword(UserInterface &ui,
* it might be changed in the sync time. */
return;
}
string descr = getDescr(serverName,globalConfigNode,sourceName,sourceConfigNode);
ConfigPasswordKey key = getPasswordKey(descr,serverName,globalConfigNode,sourceName,sourceConfigNode);
string descr = getDescr(serverName,*globalConfigNode,sourceName,sourceConfigNode);
ConfigPasswordKey key = getPasswordKey(descr,serverName,*globalConfigNode,sourceName,sourceConfigNode);
if(ui.savePassword(getMainName(), password, key)) {
string value = "-";
if(sourceConfigNode.get() == NULL) {
setProperty(globalConfigNode, value);
setProperty(*globalConfigNode, value);
} else {
setProperty(*sourceConfigNode,value);
}
@ -2599,16 +2597,9 @@ public:
{}
virtual void checkPassword(UserInterface &ui,
const std::string &serverName,
FilterConfigNode &globalConfigNode,
const std::string &sourceName,
const boost::shared_ptr<FilterConfigNode> &sourceConfigNode) const {
PasswordConfigProperty::checkPassword(ui,
sourcePropUser,
serverName,
globalConfigNode,
sourceName,
sourceConfigNode);
SyncConfig &config,
const std::string &sourceName) const {
PasswordConfigProperty::checkPassword(ui, config, sourcePropUser, sourceName);
}
virtual ConfigPasswordKey getPasswordKey(const std::string &descr,

View File

@ -128,6 +128,7 @@ class ConfigTree;
class UserInterface;
class SyncSourceNodes;
class ConstSyncSourceNodes;
class SyncConfig;
struct ConfigPasswordKey;
/** name of the per-source admin data property */
@ -336,16 +337,12 @@ class ConfigProperty {
* sourceName and sourceConfigNode might be not set by caller. They only affect
* when checking password for syncsourceconfig
* @param ui user interface
* @param serverName server name
* @param globalConfigNode the sync global config node for a server
* @param sourceName the source name used for source config properties
* @param sourceConfigNode the config node for the source
* @param config the peer config in which we are checking the password
* @param sourceName the source name for which we need the password, empty if checking a peer password
*/
virtual void checkPassword(UserInterface &ui,
const std::string &serverName,
FilterConfigNode &globalConfigNode,
const std::string &sourceName = std::string(),
const boost::shared_ptr<FilterConfigNode> &sourceConfigNode = boost::shared_ptr<FilterConfigNode>()) const {}
SyncConfig &config,
const std::string &sourceName = std::string()) const {}
/**
* Try to save password if a config property wants.
@ -353,10 +350,8 @@ class ConfigProperty {
* function to save the password if necessary
*/
virtual void savePassword(UserInterface &ui,
const std::string &serverName,
FilterConfigNode &globalConfigNode,
const std::string &sourceName = std::string(),
const boost::shared_ptr<FilterConfigNode> &sourceConfigNode = boost::shared_ptr<FilterConfigNode>()) const {}
SyncConfig &config,
const std::string &sourceName = std::string()) const {}
/**
* This is used to generate description dynamically according to the context information
@ -737,25 +732,20 @@ class PasswordConfigProperty : public ConfigProperty {
{}
/**
* Check the password and cache the result.
* Check the password and cache the result. Accessed via base
* ConfigProperty class, must be implemented in derived classes.
*/
virtual void checkPassword(UserInterface &ui,
const std::string &serverName,
FilterConfigNode &globalConfigNode,
const std::string &sourceName = "",
const boost::shared_ptr<FilterConfigNode> &sourceConfigNode =
boost::shared_ptr<FilterConfigNode>()) const = 0;
SyncConfig &config,
const std::string &sourceName = std::string()) const = 0;
/**
* It firstly check password and then invoke ui's savePassword
* function to save the password if necessary
*/
virtual void savePassword(UserInterface &ui,
const std::string &serverName,
FilterConfigNode &globalConfigNode,
const std::string &sourceName = "",
const boost::shared_ptr<FilterConfigNode> &sourceConfigNode =
boost::shared_ptr<FilterConfigNode>()) const;
SyncConfig &config,
const std::string &sourceName = std::string()) const;
protected:
@ -764,12 +754,9 @@ class PasswordConfigProperty : public ConfigProperty {
* provided by derived classes.
*/
void checkPassword(UserInterface &ui,
SyncConfig &config,
const ConfigProperty &usernameProperty,
const std::string &serverName,
FilterConfigNode &globalConfigNode,
const std::string &sourceName = "",
const boost::shared_ptr<FilterConfigNode> &sourceConfigNode =
boost::shared_ptr<FilterConfigNode>()) const;
const std::string &sourceName = std::string()) const;
/**
* Get password lookup key for storing or retrieving passwords.

View File

@ -3315,7 +3315,7 @@ SyncMLStatus SyncContext::sync(SyncReport *report)
ConfigPropertyRegistry& registry = SyncConfig::getRegistry();
BOOST_FOREACH(const ConfigProperty *prop, registry) {
SE_LOG_DEBUG(NULL, "checking sync password %s", prop->getMainName().c_str());
prop->checkPassword(getUserInterfaceNonNull(), m_server, *getProperties());
prop->checkPassword(getUserInterfaceNonNull(), *this);
}
BOOST_FOREACH(SyncSource *source, sourceList) {
ConfigPropertyRegistry& registry = SyncSourceConfig::getRegistry();
@ -3323,8 +3323,7 @@ SyncMLStatus SyncContext::sync(SyncReport *report)
SE_LOG_DEBUG(NULL, "checking source %s password %s",
source->getName().c_str(),
prop->getMainName().c_str());
prop->checkPassword(getUserInterfaceNonNull(), m_server, *getProperties(),
source->getName(), source->getProperties());
prop->checkPassword(getUserInterfaceNonNull(), *this, source->getName());
}
}
@ -4304,8 +4303,7 @@ void SyncContext::status()
BOOST_FOREACH(SyncSource *source, sourceList) {
ConfigPropertyRegistry& registry = SyncSourceConfig::getRegistry();
BOOST_FOREACH(const ConfigProperty *prop, registry) {
prop->checkPassword(getUserInterfaceNonNull(), m_server, *getProperties(),
source->getName(), source->getProperties());
prop->checkPassword(getUserInterfaceNonNull(), *this, source->getName());
}
}
BOOST_FOREACH(SyncSource *source, sourceList) {
@ -4356,8 +4354,7 @@ void SyncContext::checkStatus(SyncReport &report)
BOOST_FOREACH(SyncSource *source, sourceList) {
ConfigPropertyRegistry& registry = SyncSourceConfig::getRegistry();
BOOST_FOREACH(const ConfigProperty *prop, registry) {
prop->checkPassword(getUserInterfaceNonNull(), m_server, *getProperties(),
source->getName(), source->getProperties());
prop->checkPassword(getUserInterfaceNonNull(), *this, source->getName());
}
}
BOOST_FOREACH(SyncSource *source, sourceList) {
@ -4438,8 +4435,7 @@ void SyncContext::restore(const string &dirname, RestoreDatabase database)
BOOST_FOREACH(SyncSource *source, sourceList) {
ConfigPropertyRegistry& registry = SyncSourceConfig::getRegistry();
BOOST_FOREACH(const ConfigProperty *prop, registry) {
prop->checkPassword(getUserInterfaceNonNull(), m_server, *getProperties(),
source->getName(), source->getProperties());
prop->checkPassword(getUserInterfaceNonNull(), *this, source->getName());
}
}