/** * Add a repository to the site. * This will also handle the embedded keys, (as of 2.4.5). * * This contains the first step and second steps. */ public function repos_add() { $request = $this->getPageRequest(); $view = $this->getView(); $site = new UpdateSiteModel(); $form = Form::BuildFromModel($site); $form->set('action', \Core\resolve_link('/updater/repos/add')); $form->addElement('submit', array('value' => 'Next')); $view->title = 'Add Repo'; // Needed because dynamic pages do not record navigation. $view->addBreadcrumb('Repositories', 'updater/repos'); $view->assign('form', $form); if(!is_dir(GPG_HOMEDIR)){ // Try to create it? if(is_writable(dirname(GPG_HOMEDIR))){ // w00t mkdir(GPG_HOMEDIR); } else{ \Core\set_message(GPG_HOMEDIR . ' does not exist and could not be created! Please fix this before proceeding!', 'error'); $form = null; } } elseif(!is_writable(GPG_HOMEDIR)){ \Core\set_message(GPG_HOMEDIR . ' is not writable! Please fix this before proceeding!', 'error'); $form = null; } // This is the logic for step 2 (confirmation). // This is after all the template logic from step 1 because it will fallback to that form if necessary. if($request->isPost()){ $url = $request->getPost('model[url]'); $username = $request->getPost('model[username]'); $password = $request->getPost('model[password]'); // Validate and standardize this repo url. // This is because most people will simply type repo.corepl.us. if(strpos($url, '://') === false){ $url = 'http://' . $url; } // Lookup that URL first! if(UpdateSiteModel::Count(array('url' => $url)) > 0){ \Core\set_message($url . ' is already used!', 'error'); return; } // Load up a new Model, that's the easiest way to pull the repo data. $model = new UpdateSiteModel(); $model->setFromArray([ 'url' => $url, 'username' => $username, 'password' => $password, ]); // From here on out, populate the previous form with this new model. $form = Form::BuildFromModel($model); $form->set('action', \Core\resolve_link('/updater/repos/add')); $form->addElement('submit', array('value' => 'Next')); $view->assign('form', $form); /** @var \Core\Filestore\Backends\FileRemote $remote */ $remote = $model->getFile(); if($remote->requiresAuthentication()){ if(!$username){ \Core\set_message($url . ' requires authentication!', 'error'); return; } else{ \Core\set_message('Invalid credentials for ' . $url, 'error'); return; } } if(!$model->isValid()){ \Core\set_message($url . ' does not appear to be a valid repository!', 'error'); return; } $repo = new RepoXML(); $repo->loadFromFile($remote); // Make sure the keys are good if(!$repo->validateKeys()){ \Core\set_message('There were invalid/unpublished keys in the repo! Refusing to import.', 'error'); return; } // The very final bit of this logic is to look and see if there's a "confirm" present. // If there is, the user clicked accept on the second page and I need to go ahead and import the data. if($request->getPost('confirm')){ $model->set('description', $repo->getDescription()); $model->save(); $keysimported = 0; $keycount = sizeof($repo->getKeys()); $gpg = new \Core\GPG\GPG(); foreach($repo->getKeys() as $keyData){ try{ $gpg->importKey($keyData['key']); ++$keysimported; } catch(Exception $e){ \Core\set_message('Unable to import key [' . $keyData['key'] . '] from keyserver!', 'error'); } } if(!$keycount){ \Core\set_message('Added repository site successfully!', 'success'); } elseif($keycount != $keysimported){ \Core\set_message('Added repository site, but unable to import ' . ($keycount-$keysimported) . ' key(s).', 'info'); } else{ \Core\set_message('Added repository site and imported ' . $keysimported . ' key(s) successfully!', 'success'); } \core\redirect('/updater/repos'); } $view->templatename = 'pages/updater/repos_add2.tpl'; $view->assign('description', $repo->getDescription()); $view->assign('keys', $repo->getKeys()); $view->assign('url', $url); $view->assign('username', $username); $view->assign('password', $password); } }
$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){ // WOOT, a key was found and the email matches. $key = $currentkey; break; }