| /_____||_| |_| |_| |
| |
\---------------------------------------------------------------------*/
-/** \file zypp/media/CredentialManager.h
+/** \file zypp/media/CredentialManager.cc
*
*/
#include <iostream>
#include <fstream>
+#include "zypp/ZConfig.h"
#include "zypp/base/Function.h"
#include "zypp/base/Logger.h"
#include "zypp/base/Easy.h"
#include "zypp/media/CredentialManager.h"
-#define CUSTOM_CREDENTIALS_FILE_DIR "/etc/zypp/credentials.d"
-#define GLOBAL_CREDENTIALS_FILE "/etc/zypp/credentials.cat"
-#define USER_CREDENTIALS_FILE ".zypp/credentials.cat"
+#define USER_CREDENTIALS_FILE ".zypp/credentials.cat"
using namespace std;
//////////////////////////////////////////////////////////////////////
-namespace zypp
+namespace zypp
{ ////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
namespace media
{ ////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : AuthDataComparator
+ //
+ //////////////////////////////////////////////////////////////////////
+
+ bool
+ AuthDataComparator::operator()(
+ const AuthData_Ptr & lhs, const AuthData_Ptr & rhs)
+ {
+ static const url::ViewOption vopt =
+ url::ViewOption::DEFAULTS
+ - url::ViewOption::WITH_USERNAME
+ - url::ViewOption::WITH_PASSWORD
+ - url::ViewOption::WITH_QUERY_STR;
+
+ if (lhs->username() != rhs->username())
+ return true;
+
+ if (lhs->url().asString(vopt) != rhs->url().asString(vopt))
+ return true;
+
+ return false;
+ }
//////////////////////////////////////////////////////////////////////
//
- // CLASS NAME : CredManagerOptions
+ // CLASS NAME : CredManagerOptions
//
//////////////////////////////////////////////////////////////////////
CredManagerOptions::CredManagerOptions(const Pathname & rootdir)
- : globalCredFilePath(rootdir / GLOBAL_CREDENTIALS_FILE)
- , customCredFileDir(rootdir / CUSTOM_CREDENTIALS_FILE_DIR)
+ : globalCredFilePath(rootdir / ZConfig::instance().credentialsGlobalFile())
+ , customCredFileDir(rootdir / ZConfig::instance().credentialsGlobalDir())
{
char * homedir = getenv("HOME");
if (homedir)
//////////////////////////////////////////////////////////////////////
//
- // CLASS NAME : CredentialManager::Impl
+ // CLASS NAME : CredentialManager::Impl
//
struct CredentialManager::Impl
{
~Impl()
{}
-
+
void init_globalCredentials();
void init_userCredentials();
CredentialSet _credsGlobal;
CredentialSet _credsUser;
CredentialSet _credsTmp;
+
+ bool _globalDirty;
+ bool _userDirty;
};
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
- // CLASS NAME : CredentialManager::Impl
+ // CLASS NAME : CredentialManager::Impl
//
//////////////////////////////////////////////////////////////////////
CredentialManager::Impl::Impl(const CredManagerOptions & options)
: _options(options)
+ , _globalDirty(false)
+ , _userDirty(false)
{
init_globalCredentials();
init_userCredentials();
bind(&Impl::processCredentials, this, _1));
}
else
- DBG << "user cred file does not exist";
+ DBG << "user cred file does not exist" << endl;
_credsUser = _credsTmp; _credsTmp.clear();
DBG << "Got " << _credsUser.size() << " user records." << endl;
const Url & url,
url::ViewOption vopt)
{
+ const string & username = url.getUsername();
for(CredentialManager::CredentialIterator it = set.begin(); it != set.end(); ++it)
{
- if (url.asString(vopt) == (*it)->url().asString(vopt))
- return *it;
+ // this ignores url params - not sure if it is good or bad...
+ if (url.asString(vopt).find((*it)->url().asString(vopt)) == 0)
+ {
+ if (username.empty() || username == (*it)->username())
+ return *it;
+ }
}
-
+
return AuthData_Ptr();
}
// default url::ViewOption will take care of that.
// operator==(Url,Url) compares the whole Url
- // if the wanted URL does not contain username, ignore that, too
url::ViewOption vopt;
-// if (url.getUsername().empty())
- vopt = vopt - url::ViewOption::WITH_USERNAME;
+ vopt = vopt
+ - url::ViewOption::WITH_USERNAME
+ - url::ViewOption::WITH_PASSWORD
+ - url::ViewOption::WITH_QUERY_STR;
// search in global credentials
result = findIn(_credsGlobal, url, vopt);
AuthData_Ptr CredentialManager::Impl::getCredFromFile(const Pathname & file)
{
AuthData_Ptr result;
-
+
Pathname credfile;
if (file.absolute())
// get from that file
credfile = file;
else
- // get from /etc/zypp/credentials.d
- credfile = _options.customCredFileDir / file;
+ // get from /etc/zypp/credentials.d, delete the leading path
+ credfile = _options.customCredFileDir / file.basename();
CredentialFileReader(credfile, bind(&Impl::processCredentials, this, _1));
if (_credsTmp.empty())
//////////////////////////////////////////////////////////////////////
//
- // CLASS NAME : CredentialManager
+ // CLASS NAME : CredentialManager
//
//////////////////////////////////////////////////////////////////////
AuthData_Ptr CredentialManager::getCred(const Url & url)
- { return _pimpl->getCred(url); }
+ {
+ string credfile = url.getQueryParam("credentials");
+ if (credfile.empty())
+ return _pimpl->getCred(url);
+ return _pimpl->getCredFromFile(credfile);
+ }
AuthData_Ptr CredentialManager::getCredFromFile(const Pathname & file)
{ return _pimpl->getCredFromFile(file); }
- void CredentialManager::save(const AuthData & cred, bool global)
- { global ? saveInGlobal(cred) : saveInUser(cred); }
+ void CredentialManager::addCred(const AuthData & cred)
+ {
+ Pathname credfile = cred.url().getQueryParam("credentials");
+ if (credfile.empty())
+ //! \todo ask user where to store these creds. saving to user creds for now
+ addUserCred(cred);
+ else
+ saveInFile(cred, credfile);
+ }
- void CredentialManager::saveInGlobal(const AuthData & cred)
+ void CredentialManager::addGlobalCred(const AuthData & cred)
{
AuthData_Ptr c_ptr;
c_ptr.reset(new AuthData(cred)); // FIX for child classes if needed
- _pimpl->_credsGlobal.insert(c_ptr); //! \todo avoid adding duplicates
- _pimpl->saveGlobalCredentials();
+ pair<CredentialIterator, bool> ret = _pimpl->_credsGlobal.insert(c_ptr);
+ if (ret.second)
+ _pimpl->_globalDirty = true;
+ else if ((*ret.first)->password() != cred.password())
+ {
+ _pimpl->_credsGlobal.erase(ret.first);
+ _pimpl->_credsGlobal.insert(c_ptr);
+ _pimpl->_globalDirty = true;
+ }
}
- void CredentialManager::saveInUser(const AuthData & cred)
+ void CredentialManager::addUserCred(const AuthData & cred)
{
AuthData_Ptr c_ptr;
c_ptr.reset(new AuthData(cred)); // FIX for child classes if needed
- _pimpl->_credsUser.insert(c_ptr); //! \todo avoid adding duplicates
- _pimpl->saveUserCredentials();
+ pair<CredentialIterator, bool> ret = _pimpl->_credsUser.insert(c_ptr);
+ if (ret.second)
+ _pimpl->_userDirty = true;
+ else if ((*ret.first)->password() != cred.password())
+ {
+ _pimpl->_credsUser.erase(ret.first);
+ _pimpl->_credsUser.insert(c_ptr);
+ _pimpl->_userDirty = true;
+ }
+ }
+
+
+ void CredentialManager::save()
+ {
+ if (_pimpl->_globalDirty)
+ _pimpl->saveGlobalCredentials();
+ if (_pimpl->_userDirty)
+ _pimpl->saveUserCredentials();
+ _pimpl->_globalDirty = false;
+ _pimpl->_userDirty = false;
+ }
+
+
+ void CredentialManager::saveInGlobal(const AuthData & cred)
+ {
+ addGlobalCred(cred);
+ save();
+ }
+
+
+ void CredentialManager::saveInUser(const AuthData & cred)
+ {
+ addUserCred(cred);
+ save();
}
- void CredentialManager::saveIn(const AuthData & cred, const Pathname & credFile)
+ void CredentialManager::saveInFile(const AuthData & cred, const Pathname & credFile)
{
AuthData_Ptr c_ptr;
c_ptr.reset(new AuthData(cred)); // FIX for child classes if needed
+ c_ptr->setUrl(Url()); // don't save url in custom creds file
CredentialManager::CredentialSet creds;
creds.insert(c_ptr);