Imported Upstream version 17.23.2
[platform/upstream/libzypp.git] / zypp / media / CredentialManager.cc
index eb50cc0..639bd6c 100644 (file)
@@ -6,12 +6,13 @@
 |                         /_____||_| |_| |_|                           |
 |                                                                      |
 \---------------------------------------------------------------------*/
-/** \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 ) const
+  {
+    static const url::ViewOption vopt = url::ViewOption::DEFAULTS
+                                     - url::ViewOption::WITH_USERNAME
+                                     - url::ViewOption::WITH_PASSWORD
+                                     - url::ViewOption::WITH_QUERY_STR;
+    // std::less semantic!
+    int cmp = lhs->url().asString(vopt).compare( rhs->url().asString(vopt) );
+    if ( ! cmp )
+      cmp = lhs->username().compare( rhs->username() );
+    return( cmp < 0 );
+  }
 
   //////////////////////////////////////////////////////////////////////
   //
-  // 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)
@@ -53,7 +70,7 @@ namespace zypp
 
   //////////////////////////////////////////////////////////////////////
   //
-  // CLASS NAME : CredentialManager::Impl 
+  // CLASS NAME : CredentialManager::Impl
   //
   struct CredentialManager::Impl
   {
@@ -61,7 +78,7 @@ namespace zypp
 
     ~Impl()
     {}
-    
+
     void init_globalCredentials();
     void init_userCredentials();
 
@@ -87,7 +104,7 @@ namespace zypp
 
   //////////////////////////////////////////////////////////////////////
   //
-  // CLASS NAME : CredentialManager::Impl 
+  // CLASS NAME : CredentialManager::Impl
   //
   //////////////////////////////////////////////////////////////////////
 
@@ -180,12 +197,11 @@ namespace zypp
     // 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
-        - url::ViewOption::WITH_QUERY_STR;
+    vopt = vopt
+      - url::ViewOption::WITH_USERNAME
+      - url::ViewOption::WITH_PASSWORD
+      - url::ViewOption::WITH_QUERY_STR;
 
     // search in global credentials
     result = findIn(_credsGlobal, url, vopt);
@@ -206,7 +222,7 @@ namespace zypp
   AuthData_Ptr CredentialManager::Impl::getCredFromFile(const Pathname & file)
   {
     AuthData_Ptr result;
-    
+
     Pathname credfile;
     if (file.absolute())
       // get from that file
@@ -264,7 +280,7 @@ namespace zypp
 
   //////////////////////////////////////////////////////////////////////
   //
-  // CLASS NAME : CredentialManager 
+  // CLASS NAME : CredentialManager
   //
   //////////////////////////////////////////////////////////////////////
 
@@ -288,8 +304,12 @@ namespace zypp
 
   void CredentialManager::addCred(const AuthData & cred)
   {
-#warning addCred(const AuthData & cred) not implemented
-    // add with user callbacks
+    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);
   }
 
 
@@ -297,8 +317,15 @@ namespace zypp
   {
     AuthData_Ptr c_ptr;
     c_ptr.reset(new AuthData(cred)); // FIX for child classes if needed
-    if (_pimpl->_credsGlobal.insert(c_ptr).second)
+    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;
+    }
   }
 
 
@@ -306,8 +333,15 @@ namespace zypp
   {
     AuthData_Ptr c_ptr;
     c_ptr.reset(new AuthData(cred)); // FIX for child classes if needed
-    if (_pimpl->_credsUser.insert(c_ptr).second)
+    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;
+    }
   }
 
 
@@ -340,6 +374,7 @@ namespace zypp
   {
     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);