///////////////////////////////////////////////////////////////////
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
*/
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 );
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() )
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;
// 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;
{
case RepoType::NONE_e:
// unknown, probe the local metadata
- repokind = probeCache( productdatapath );
+ repokind = probe( productdatapath.asUrl() );
break;
default:
break;
////////////////////////////////////////////////////////////////////////////
-
- /** 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;
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 )
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;
{
// 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() )));
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;
}
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;
}
{
// 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 );
}
////////////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////
- // 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?
}
// 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 )
_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