Imported Upstream version 15.0.0
[platform/upstream/libzypp.git] / zypp / RepoManager.cc
index f8e7f9a..d9ce8bf 100644 (file)
@@ -64,76 +64,6 @@ namespace zypp
   ///////////////////////////////////////////////////////////////////
   namespace
   {
-    ///////////////////////////////////////////////////////////////////
-    /// \class UrlCredentialExtractor
-    /// \brief Extract credentials in \ref Url authority and store them via \ref CredentialManager.
-    ///
-    /// Lazy init CredentialManager and save collected credentials when
-    /// going out of scope.
-    ///
-    /// Methods return whether a password has been collected/extracted.
-    ///
-    /// \code
-    /// UrlCredentialExtractor( "/rootdir" ).collect( oneUrlOrUrlContainer );
-    /// \endcode
-    /// \code
-    /// {
-    ///   UrlCredentialExtractor extractCredentials;
-    ///   extractCredentials.collect( oneUrlOrUrlContainer );
-    ///   extractCredentials.extract( oneMoreUrlOrUrlContainer );
-    ///   ....
-    /// }
-    /// \endcode
-    ///
-    class UrlCredentialExtractor
-    {
-    public:
-      UrlCredentialExtractor( Pathname & root_r )
-      : _root( root_r )
-      {}
-
-      ~UrlCredentialExtractor()
-      { if ( _cmPtr ) _cmPtr->save(); }
-
-      /** Remember credentials stored in URL authority leaving the password in \a url_r. */
-      bool collect( const Url & url_r )
-      {
-       bool ret = url_r.hasCredentialsInAuthority();
-       if ( ret )
-       {
-         if ( !_cmPtr ) _cmPtr.reset( new media::CredentialManager( _root ) );
-         _cmPtr->addUserCred( url_r );
-       }
-       return ret;
-      }
-      /** \overload operating on Url container */
-      template<class TContainer>
-      bool collect( const TContainer & urls_r )
-      {        bool ret = false; for ( const Url & url : urls_r ) { if ( collect( url ) && !ret ) ret = true; } return ret; }
-
-      /** Remember credentials stored in URL authority stripping the passowrd from \a url_r. */
-      bool extract( Url & url_r )
-      {
-       bool ret = collect( url_r );
-       if ( ret )
-         url_r.setPassword( std::string() );
-       return ret;
-      }
-      /** \overload operating on Url container */
-      template<class TContainer>
-      bool extract( TContainer & urls_r )
-      {        bool ret = false; for ( Url & url : urls_r ) { if ( extract( url ) && !ret ) ret = true; } return ret; }
-
-    private:
-      const Pathname & _root;
-      scoped_ptr<media::CredentialManager> _cmPtr;
-    };
-  } // namespace
-  ///////////////////////////////////////////////////////////////////
-
-  ///////////////////////////////////////////////////////////////////
-  namespace
-  {
     /** Simple media mounter to access non-downloading URLs e.g. for non-local plaindir repos.
      * \ingroup g_RAII
      */
@@ -590,7 +520,6 @@ namespace zypp
     void buildCache( const RepoInfo & info, CacheBuildPolicy policy, OPT_PROGRESS );
 
     repo::RepoType probe( const Url & url, const Pathname & path = Pathname() ) const;
-    repo::RepoType probeCache( const Pathname & path_r ) const;
 
     void cleanCacheDirGarbage( OPT_PROGRESS );
 
@@ -883,7 +812,7 @@ namespace zypp
     RepoType repokind = info.type();
     // If unknown, probe the local metadata
     if ( repokind == RepoType::NONE )
-      repokind = probeCache( productdatapath );
+      repokind = probe( productdatapath.asUrl() );
 
     RepoStatus status;
     switch ( repokind.toEnum() )
@@ -917,7 +846,7 @@ namespace zypp
     RepoType repokind = info.type();
     if ( repokind.toEnum() == RepoType::NONE_e )
       // unknown, probe the local metadata
-      repokind = probeCache( productdatapath );
+      repokind = probe( productdatapath.asUrl() );
     // if still unknown, just return
     if (repokind == RepoType::NONE_e)
       return;
@@ -1201,9 +1130,6 @@ namespace zypp
         // cause of the problem of the first URL remembered
         if (it == info.baseUrlsBegin())
           rexception.remember(e);
-       else
-         rexception.addHistory(  e.asUserString() );
-
       }
     } // for every url
     ERR << "No more urls..." << endl;
@@ -1309,7 +1235,7 @@ namespace zypp
     {
       case RepoType::NONE_e:
         // unknown, probe the local metadata
-        repokind = probeCache( productdatapath );
+        repokind = probe( productdatapath.asUrl() );
       break;
       default:
       break;
@@ -1381,13 +1307,6 @@ namespace zypp
 
   ////////////////////////////////////////////////////////////////////////////
 
-
-  /** Probe the metadata type of a repository located at \c url.
-   * Urls here may be rewritten by \ref MediaSetAccess to reflect the correct media number.
-   *
-   * \note Metadata in local cache directories must be probed using \ref probeCache as
-   * a cache path must not be rewritten (bnc#946129)
-   */
   repo::RepoType RepoManager::Impl::probe( const Url & url, const Pathname & path  ) const
   {
     MIL << "going to probe the repo type at " << url << " (" << path << ")" << endl;
@@ -1472,28 +1391,6 @@ namespace zypp
     return repo::RepoType::NONE;
   }
 
-  /** Probe Metadata in a local cache directory
-   *
-   * \note Metadata in local cache directories must not be probed using \ref probe as
-   * a cache path must not be rewritten (bnc#946129)
-   */
-  repo::RepoType RepoManager::Impl::probeCache( const Pathname & path_r ) const
-  {
-    MIL << "going to probe the cached repo at " << path_r << endl;
-
-    repo::RepoType ret = repo::RepoType::NONE;
-
-    if ( PathInfo(path_r/"/repodata/repomd.xml").isFile() )
-    { ret = repo::RepoType::RPMMD; }
-    else if ( PathInfo(path_r/"/content").isFile() )
-    { ret = repo::RepoType::YAST2; }
-    else if ( PathInfo(path_r).isDir() )
-    { ret = repo::RepoType::RPMPLAINDIR; }
-
-    MIL << "Probed cached type " << ret << " at " << path_r << endl;
-    return ret;
-  }
-
   ////////////////////////////////////////////////////////////////////////////
 
   void RepoManager::Impl::cleanCacheDirGarbage( const ProgressData::ReceiverFnc & progressrcv )
@@ -1662,9 +1559,26 @@ namespace zypp
     progress.set(90);
 
     // check for credentials in Urls
-    UrlCredentialExtractor( _options.rootDir ).collect( tosave.baseUrls() );
+    bool havePasswords = false;
+    for_( urlit, tosave.baseUrlsBegin(), tosave.baseUrlsEnd() )
+      if ( urlit->hasCredentialsInAuthority() )
+      {
+        havePasswords = true;
+        break;
+      }
+    // save the credentials
+    if ( havePasswords )
+    {
+      media::CredentialManager cm(
+          media::CredManagerOptions(_options.rootDir) );
+
+      for_(urlit, tosave.baseUrlsBegin(), tosave.baseUrlsEnd())
+        if (urlit->hasCredentialsInAuthority())
+          //! \todo use a method calling UI callbacks to ask where to save creds?
+          cm.saveInUser(media::AuthData(*urlit));
+    }
 
-    HistoryLog(_options.rootDir).addRepository(tosave);
+    HistoryLog().addRepository(tosave);
 
     progress.toMax();
     MIL << "done" << endl;
@@ -1758,12 +1672,10 @@ namespace zypp
       {
         // figure how many repos are there in the file:
         std::list<RepoInfo> filerepos = repositories_in_file(todelete.filepath());
-        if ( filerepos.size() == 0     // bsc#984494: file may have already been deleted
-         ||(filerepos.size() == 1 && filerepos.front().alias() == todelete.alias() ) )
+        if ( (filerepos.size() == 1) && ( filerepos.front().alias() == todelete.alias() ) )
         {
-          // easy: file does not exist, contains no or only the repo to delete: delete the file
-         int ret = filesystem::unlink( todelete.filepath() );
-          if ( ! ( ret == 0 || ret == ENOENT ) )
+          // easy, only this one, just delete the file
+          if ( filesystem::unlink(todelete.filepath()) != 0 )
           {
             // TranslatorExplanation '%s' is a filename
             ZYPP_THROW(RepoException( todelete, str::form( _("Can't delete '%s'"), todelete.filepath().c_str() )));
@@ -1866,8 +1778,6 @@ namespace zypp
       newinfo.setFilepath(toedit.filepath());
       reposManip().erase(toedit);
       reposManip().insert(newinfo);
-      // check for credentials in Urls
-      UrlCredentialExtractor( _options.rootDir ).collect( newinfo.baseUrls() );
       HistoryLog(_options.rootDir).modifyRepository(toedit, newinfo);
       MIL << "repo " << alias << " modified" << endl;
     }
@@ -1921,8 +1831,15 @@ namespace zypp
     saveService( toSave );
     _services.insert( toSave );
 
-    // check for credentials in Url
-    UrlCredentialExtractor( _options.rootDir ).collect( toSave.url() );
+    // check for credentials in Url (username:password, not ?credentials param)
+    if ( toSave.url().hasCredentialsInAuthority() )
+    {
+      media::CredentialManager cm(
+          media::CredManagerOptions(_options.rootDir) );
+
+      //! \todo use a method calling UI callbacks to ask where to save creds?
+      cm.saveInUser(media::AuthData(toSave.url()));
+    }
 
     MIL << "added service " << toSave.alias() << endl;
   }
@@ -2062,41 +1979,34 @@ namespace zypp
     {
       // First of all: Prepend service alias:
       it->setAlias( str::form( "%s:%s", service.alias().c_str(), it->alias().c_str() ) );
-      // set reference to the parent service
+      // set refrence to the parent service
       it->setService( service.alias() );
 
       // remember the new parsed repo state
       newRepoStates[it->alias()] = *it;
 
-      // - If the repo url was not set by the repoindex parser, set service's url.
-      // - Libzypp currently has problem with separate url + path handling so just
-      //   append a path, if set, to the baseurls
-      // - Credentials in the url authority will be extracted later, either if the
-      //   repository is added or if we check for changed urls.
-      Pathname path;
-      if ( !it->path().empty() )
-      {
-       if ( it->path() != "/" )
-         path = it->path();
-       it->setPath("");
-      }
-
+      // if the repo url was not set by the repoindex parser, set service's url
+      Url url;
       if ( it->baseUrlsEmpty() )
+        url = service.rawUrl();
+      else
       {
-       Url url( service.rawUrl() );
-       if ( !path.empty() )
-         url.setPathName( url.getPathName() / path );
-       it->setBaseUrl( std::move(url) );
+        // service repo can contain only one URL now, so no need to iterate.
+        url = it->rawUrl();    // raw!
       }
-      else if ( !path.empty() )
+
+      // libzypp currently has problem with separate url + path handling
+      // so just append the path to the baseurl
+      if ( !it->path().empty() )
       {
-       RepoInfo::url_set urls( it->rawBaseUrls() );
-       for ( Url & url : urls )
-       {
-         url.setPathName( url.getPathName() / path );
-       }
-       it->setBaseUrls( std::move(urls) );
+        Pathname path(url.getPathName());
+        path /= it->path();
+        url.setPathName( path.asString() );
+        it->setPath("");
       }
+
+      // save the url
+      it->setBaseUrl( url );
     }
 
     ////////////////////////////////////////////////////////////////////////////
@@ -2132,8 +2042,7 @@ namespace zypp
     }
 
     ////////////////////////////////////////////////////////////////////////////
-    // create missing repositories and modify existing ones if needed...
-    UrlCredentialExtractor urlCredentialExtractor( _options.rootDir ); // To collect any credentials stored in repo URLs
+    // create missing repositories and modify exising ones if needed...
     for_( it, collector.repos.begin(), collector.repos.end() )
     {
       // User explicitly requested the repo being enabled?
@@ -2258,37 +2167,13 @@ namespace zypp
        }
 
         // changed url?
+        // service repo can contain only one URL now, so no need to iterate.
+        if ( oldRepo->rawUrl() != it->rawUrl() )
         {
-         RepoInfo::url_set newUrls( it->rawBaseUrls() );
-         urlCredentialExtractor.extract( newUrls );    // Extract! to prevent passwds from disturbing the comparison below
-         if ( oldRepo->rawBaseUrls() != newUrls )
-         {
-           DBG << "Service repo " << it->alias() << " gets new URLs " << newUrls << endl;
-           oldRepo->setBaseUrls( std::move(newUrls) );
-           oldRepoModified = true;
-         }
-       }
-
-        // changed gpg check settings?
-       // ATM only plugin services can set GPG values.
-       if ( service.type() == ServiceType::PLUGIN )
-       {
-         TriBool ogpg[3];      // Gpg RepoGpg PkgGpg
-         TriBool ngpg[3];
-         oldRepo->getRawGpgChecks( ogpg[0], ogpg[1], ogpg[2] );
-         it->     getRawGpgChecks( ngpg[0], ngpg[1], ngpg[2] );
-#define Z_CHKGPG(I,N)                                                                          \
-         if ( ! sameTriboolState( ogpg[I], ngpg[I] ) )                                         \
-         {                                                                                     \
-           DBG << "Service repo " << it->alias() << " gets new "#N"Check " << ngpg[I] << endl; \
-           oldRepo->set##N##Check( ngpg[I] );                                                  \
-           oldRepoModified = true;                                                             \
-         }
-         Z_CHKGPG( 0, Gpg );
-         Z_CHKGPG( 1, RepoGpg );
-         Z_CHKGPG( 2, PkgGpg );
-#undef Z_CHKGPG
-       }
+          DBG << "Service repo " << it->alias() << " gets new URL " << it->rawUrl() << endl;
+          oldRepo->setBaseUrl( it->rawUrl() );
+          oldRepoModified = true;
+        }
 
         // save if modified:
         if ( oldRepoModified )
@@ -2366,9 +2251,6 @@ namespace zypp
 
     _services.erase(oldAlias);
     _services.insert(service);
-    // check for credentials in Urls
-    UrlCredentialExtractor( _options.rootDir ).collect( service.url() );
-
 
     // changed properties affecting also repositories
     if ( oldAlias != service.alias()                   // changed alias