public function indexAction() { $this->view->headLink()->appendStylesheet("/css/template/form.css"); $this->view->headLink()->appendStylesheet("/css/template/table.css"); $this->view->headLink()->appendStylesheet("/css/pages/project_settings.css"); $projects = new GD_Model_ProjectsMapper(); $project_slug = $this->_getParam("project"); if ($project_slug != "new") { $this->view->headTitle('Edit Project'); $project = $projects->getProjectBySlug($project_slug); $new_project = false; } else { $this->view->headTitle('Add Project'); $project = new GD_Model_Project(); $project->setName("New Project"); $project->setDeploymentBranch('master'); // Usually default for git // Load the ssh key $ssh_keys_map = new GD_Model_SSHKeysMapper(); $ssh_keys = new GD_Model_SSHKey(); $ssh_keys_map->find(1, $ssh_keys); $project->setSSHKey($ssh_keys); $new_project = true; } $this->view->project = $project; $this->view->new_project = $new_project; // Populate list of servers for this project if ($project->getId() > 0) { $servers = new GD_Model_ServersMapper(); $this->view->servers = $servers->getServersByProject($project->getId()); } $form = new GDApp_Form_ProjectSettings($project, null, $new_project); $this->view->form = $form; if ($this->getRequest()->isPost()) { if ($form->isValid($this->getRequest()->getParams())) { $result = $this->saveProject($projects, $project, $new_project, $this->_getParam("errored") == "true"); if ($result !== true) { $form->repositoryUrl->addError("Could not clone the git repository [" . $result . "]. Please check the URL is correct and try again."); } else { $this->_redirect($this->getFrontController()->getBaseUrl() . "project/" . $project->getSlug() . '/settings'); } } } else { if (!$new_project) { $git = new GD_Git($project); try { $git->checkValidRepository(); $this->view->valid_repository = true; } catch (GD_Exception $ex) { $this->view->valid_repository = false; $form->repositoryUrl->addError("Check this git repository URL - is it correct?"); GD_Debug::Log("Reclone required for {$project->getName()} (project settings)", GD_Debug::DEBUG_BASIC); } } $data = array('name' => $project->getName(), 'repositoryUrl' => $project->getRepositoryUrl(), 'deploymentBranch' => $project->getDeploymentBranch(), 'publicKey' => $project->getSSHKey()->getPublicKey()); $form->populate($data); } }
/** * Overwrite the default SSH command that git uses so we can tell it to use * our own ssh key * * @throws GD_Exception */ private function sshKeys() { if ($this->_repotype == self::GIT_REPOTYPE_SSH) { // Write the id_rsa key to the gitcache $id_rsa = $this->_project->getSSHKey()->getPrivateKey(); $project_id = $this->_project->getId(); $this->_ssh_key = $this->_base_gitdir . "id_rsa." . $project_id; if (file_exists($this->_ssh_key)) { unlink($this->_ssh_key); } file_put_contents($this->_ssh_key, $id_rsa); chmod($this->_ssh_key, 0600); // Get the hostname part of the URL $x = strrchr($this->_url, ':'); $host = substr($this->_url, 0, -strlen($x)); $host = preg_replace("/[^@0-9a-zA-Z-_.]/", "", $host); $ssh_cmd = "ssh -T -o StrictHostKeyChecking=no -i {$this->_ssh_key} -o UserKnownHostsFile=/dev/null "; // Use a script file $script = "#!/bin/sh\n\n{$ssh_cmd} \$*\n"; $this->_ssh_script = $this->_base_gitdir . "ssh." . $project_id . ".sh"; file_put_contents($this->_ssh_script, $script); chmod($this->_ssh_script, 0755); putenv("GIT_SSH={$this->_ssh_script}"); // Test the connection $this->runShell("\$GIT_SSH -T -o StrictHostKeyChecking=no {$host}", false); if ($this->_last_errno != 0) { // First check if we're a Github sort of repo // Github returns: Hi [USER]! You've successfully authenticated, but GitHub does not provide shell access. // Codebase returns: You've successfully uploaded your public key to Codebase and authenticated. $valid_string = "You've successfully"; $is_valid = false; foreach ($this->_last_output as $o) { if (strpos($o, $valid_string) !== false) { return; } } if (in_array("ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment.", $this->_last_output)) { /* * This is actually a correct response - default gitosis setup will serve up one of these: * * PTY allocation request failed on channel 0 * ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment. * * or just * * ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment. * */ return; } else { if (strpos($this->_last_output[0], "Could not resolve hostname") !== false || isset($this->_last_output[1]) && strpos($this->_last_output[1], "Could not resolve hostname") !== false) { throw new GD_Exception("Could not resolve hostname '{$host}'", 0, self::GIT_SSH_ERROR_HOSTNME); } else { $final_error = end($this->_last_output); throw new GD_Exception("Tried setting up SSH authentication but failed. Final error was: {$final_error}", 0, self::GIT_SSH_ERROR_UNKNOWN); } } } } }
/** * Generate a new GD_Git instance based on a GD_Model_Project object * * @param GD_Model_Project $project * @return GD_Git */ public static function FromProject(GD_Model_Project $project) { return new GD_Git($project->getId(), $project->getRepositoryUrl(), $project->getDeploymentBranch(), $project->getSSHKey()->getPrivateKey()); }