/** * Get the repository XML as a string that can be returned to the browser or cached for future use. * * @param string|null $serverid The server ID making the request, or null for anonymous. * @param string|null $limitPackager Limit the packager returned to at least version X.Y. * * @return RepoXML */ public static function GetAsRepoXML($serverid, $limitPackager) { $repo = new RepoXML(); $repo->setDescription(ConfigHandler::Get('/package_repository/description')); $gpg = new Core\GPG\GPG(); $keysfound = []; $where = []; if ($limitPackager) { $where[] = 'packager LIKE ' . $limitPackager . '%'; } $packages = PackageRepositoryPackageModel::Find($where, null, 'type DESC, key ASC, version'); foreach ($packages as $pkg) { /** @var PackageRepositoryPackageModel $pkg */ $package = new PackageXML(null); $package->setType($pkg->get('type')); $package->setName($pkg->get('name')); $package->setVersion($pkg->get('version')); $package->setPackager($pkg->get('packager')); $package->setDescription($pkg->get('description')); $package->setKey($pkg->get('gpg_key')); if (!in_array($pkg->get('gpg_key'), $keysfound)) { $keysfound[] = $pkg->get('gpg_key'); } $package->setFileLocation(\Core\resolve_link('/packagerepository/download?file=' . $pkg->get('file'))); $upgrades = $pkg->get('requires'); foreach ($upgrades as $dat) { $package->setRequire($dat['type'], $dat['name'], $dat['version'], $dat['operation']); } $upgrades = $pkg->get('provides'); foreach ($upgrades as $dat) { $package->setProvide($dat['type'], $dat['name'], $dat['version']); } $upgrades = $pkg->get('upgrades'); foreach ($upgrades as $dat) { $package->setUpgrade($dat['from'], $dat['to']); } $screens = $pkg->get('screenshots'); foreach ($screens as $dat) { $f = \Core\Filestore\Factory::File($dat); $package->setScreenshot($f->getURL()); } $package->setChangelog($pkg->get('changelog')); $repo->addPackage($package); } return $repo; }
/** * Get the repository XML as a string that can be returned to the browser or cached for future use. * * @return string */ private function _getRepoXML() { $repo = new RepoXML(); $repo->setDescription(ConfigHandler::Get('/package_repository/description')); $dir = Factory::Directory(\ConfigHandler::Get('/package_repository/base_directory')); $coredir = $dir->getPath() . 'core/'; $componentdir = $dir->getPath() . 'components/'; $themedir = $dir->getPath() . 'themes/'; $tmpdir = Factory::Directory('tmp/exports/'); $gpg = new Core\GPG\GPG(); $keysfound = []; $private = ConfigHandler::Get('/package_repository/is_private') || strpos($dir->getPath(), ROOT_PDIR) !== 0; $addedpackages = 0; $failedpackages = 0; $iterator = new \Core\Filestore\DirectoryIterator($dir); // Only find signed packages. $iterator->findExtensions = ['asc']; // Recurse into sub directories $iterator->recursive = true; // No directories $iterator->findDirectories = false; // Just files $iterator->findFiles = true; // And sort them by their filename to make things easy. $iterator->sortBy('filename'); // Ensure that the necessary temp directory exists. $tmpdir->mkdir(); foreach ($iterator as $file) { /** @var \Core\Filestore\File $file */ $fullpath = $file->getFilename(); // Used in the XML file. if ($private) { $relpath = \Core\resolve_link('/packagerepository/download?file=' . substr($file->getFilename(), strlen($dir->getPath()))); } else { $relpath = $file->getFilename(ROOT_PDIR); } // Drop the .asc extension. $basename = $file->getBasename(true); // Tarball of the temporary package $tgz = Factory::File($tmpdir->getPath() . $basename); $output = []; // I need to 1) retrieve and 2) verify the key for this package. try { $signature = $gpg->verifyFileSignature($fullpath); if (!in_array($signature->keyID, $keysfound)) { $repo->addKey($signature->keyID, null, null); $keysfound[] = $signature->keyID; } } catch (\Exception $e) { trigger_error($fullpath . ' was not able to be verified as authentic, (probably because the GPG public key was not available)'); $failedpackages++; continue; } // decode and untar it in a temp directory to get the package.xml file. exec('gpg --homedir "' . GPG_HOMEDIR . '" -q -d "' . $fullpath . '" > "' . $tgz->getFilename() . '" 2>/dev/null', $output, $ret); if ($ret) { trigger_error('Decryption of file ' . $fullpath . ' failed!'); $failedpackages++; continue; } exec('tar -xzf "' . $tgz->getFilename() . '" -C "' . $tmpdir->getPath() . '" ./package.xml', $output, $ret); if ($ret) { trigger_error('Unable to extract package.xml from' . $tgz->getFilename()); unlink($tmpdir->getPath() . $basename); $failedpackages++; continue; } // Read in that package file and append it to the repo xml. $package = new PackageXML($tmpdir->getPath() . 'package.xml'); $package->getRootDOM()->setAttribute('key', $signature->keyID); $package->setFileLocation($relpath); $repo->addPackage($package); $addedpackages++; // But I can still cleanup! unlink($tmpdir->getPath() . 'package.xml'); $tgz->delete(); } return $repo->asPrettyXML(); }
if(file_exists($destdir . 'repo.xml')){ // w00t, load it up and import the info! $repo = new RepoXML($destdir . 'repo.xml'); // Don't forget to remove any previous components! $repo->clearPackages(); } else{ // Just a new one works... $repo = new RepoXML(); } // Prompt the user if there's not information already set on the necessary ones. if(!$repo->getDescription()){ $desc = \Core\CLI\CLI::PromptUser('Please enter a short description for this repo.', 'textarea'); $repo->setDescription($desc); } // Load in the keys if not set. if(!sizeof($repo->getKeys())){ // Find and use the package maintainer's key. $out = array(); exec('gpg --homedir "' . GPG_HOMEDIR . '" --no-permission-warning --list-secret-keys', $out); $key = null; $currentkey = null; foreach($out as $line){ if(strpos($line, 'sec') === 0){ // Remember this ID for the next line, it may be the email. $currentkey = preg_replace('#^.*/([A-F0-9]*).*$#', '$1', $line); } elseif($currentkey && strpos($line, 'uid') === 0 && strpos($line, $packageremail) !== false){