/** * Validate the interconnection in the form. */ public function clean() { $conf = new IDF_Conf(); $conf->setProject($this->project); $onemax = array(); foreach (explode(',', $conf->getVal('labels_download_one_max', IDF_Form_UploadConf::init_one_max)) as $class) { if (trim($class) != '') { $onemax[] = mb_strtolower(trim($class)); } } $count = array(); for ($i = 1; $i < 7; $i++) { $this->cleaned_data['label' . $i] = trim($this->cleaned_data['label' . $i]); if (strpos($this->cleaned_data['label' . $i], ':') !== false) { list($class, $name) = explode(':', $this->cleaned_data['label' . $i], 2); list($class, $name) = array(mb_strtolower(trim($class)), trim($name)); } else { $class = 'other'; $name = $this->cleaned_data['label' . $i]; } if (!isset($count[$class])) { $count[$class] = 1; } else { $count[$class] += 1; } if (in_array($class, $onemax) and $count[$class] > 1) { if (!isset($this->errors['label' . $i])) { $this->errors['label' . $i] = array(); } $this->errors['label' . $i][] = sprintf(__('You cannot provide more than label from the %s class to an issue.'), $class); throw new Pluf_Form_Invalid(__('You provided an invalid label.')); } } return $this->cleaned_data; }
public function adminWiki($request, $match) { $prj = $request->project; $title = sprintf(__('%s Documentation Configuration'), (string) $prj); $conf = new IDF_Conf(); $conf->setProject($prj); if ($request->method == 'POST') { $form = new IDF_Form_WikiConf($request->POST); if ($form->isValid()) { foreach ($form->cleaned_data as $key => $val) { $conf->setVal($key, $val); } $request->user->setMessage(__('The documentation configuration has been saved.')); $url = Pluf_HTTP_URL_urlForView('IDF_Views_Project::adminWiki', array($prj->shortname)); return new Pluf_HTTP_Response_Redirect($url); } } else { $params = array(); $keys = array('labels_wiki_predefined', 'labels_wiki_one_max'); foreach ($keys as $key) { $_val = $conf->getVal($key, false); if ($_val !== false) { $params[$key] = $_val; } } if (count($params) == 0) { $params = null; //Nothing in the db, so new form. } $form = new IDF_Form_WikiConf($params); } return Pluf_Shortcuts_RenderToResponse('idf/admin/wiki.html', array('page_title' => $title, 'form' => $form), $request); }
/** * Generate the hgrc file */ function SyncAccess($project) { $shortname = $project->shortname; $hgrc_file = Pluf::f('idf_plugin_syncmercurial_path') . sprintf('/%s/.hg/hgrc', $shortname); // Get allow_push list $allow_push = ''; $mem = $project->getMembershipData(); foreach ($mem['owners'] as $v) { $allow_push .= $v->login . ' '; } foreach ($mem['members'] as $v) { $allow_push .= $v->login . ' '; } // Generate hgrc content if (is_file($hgrc_file)) { $tmp_content = parse_ini_file($hgrc_file, true); $tmp_content['web']['allow_push'] = $allow_push; } else { $tmp_content = Pluf::f('idf_plugin_syncmercurial_hgrc'); $tmp_content['web']['allow_push'] = $allow_push; } $fcontent = ''; foreach ($tmp_content as $key => $elem) { $fcontent .= '[' . $key . "]\n"; foreach ($elem as $key2 => $elem2) { $fcontent .= $key2 . ' = ' . $elem2 . "\n"; } } file_put_contents($hgrc_file, $fcontent, LOCK_EX); // Generate private repository config file $private_file = Pluf::f('idf_plugin_syncmercurial_private_include'); $notify_file = Pluf::f('idf_plugin_syncmercurial_private_notify'); $fcontent = ''; foreach (Pluf::factory('IDF_Project')->getList() as $project) { $conf = new IDF_Conf(); $conf->setProject($project); if ($project->private == true) { $mem = $project->getMembershipData(); $user = ''; foreach ($mem['owners'] as $v) { $user .= $v->login . ' '; } foreach ($mem['members'] as $v) { $user .= $v->login . ' '; } foreach ($mem['authorized'] as $v) { $user .= $v->login . ' '; } $fcontent .= '<Location ' . sprintf(Pluf::f('idf_plugin_syncmercurial_private_url'), $project->shortname) . '>' . "\n"; $fcontent .= 'AuthType Basic' . "\n"; $fcontent .= 'AuthName "Restricted"' . "\n"; $fcontent .= sprintf('AuthUserFile %s', Pluf::f('idf_plugin_syncmercurial_passwd_file')) . "\n"; $fcontent .= sprintf('Require user %s', $user) . "\n"; $fcontent .= '</Location>' . "\n\n"; } } file_put_contents($private_file, $fcontent, LOCK_EX); file_put_contents($notify_file, ' ', LOCK_EX); return true; }
/** * Create the autocomplete arrays for the little AJAX stuff. */ public static function autoCompleteArrays($project) { $conf = new IDF_Conf(); $conf->setProject($project); $auto = array('auto_status' => '', 'auto_labels' => ''); $auto_raw = array('auto_status' => '', 'auto_labels' => ''); $st = $conf->getVal('labels_issue_open', IDF_Form_IssueTrackingConf::init_open); $st .= "\n" . $conf->getVal('labels_issue_closed', IDF_Form_IssueTrackingConf::init_closed); $auto_raw['auto_status'] = $st; $auto_raw['auto_labels'] = $conf->getVal('labels_issue_predefined', IDF_Form_IssueTrackingConf::init_predefined); foreach ($auto_raw as $key => $st) { $st = preg_split("/\r\n|\r|\n/", $st, -1, PREG_SPLIT_NO_EMPTY); foreach ($st as $s) { $v = ''; $d = ''; $_s = explode('=', $s, 2); if (count($_s) > 1) { $v = trim($_s[0]); $d = trim($_s[1]); } else { $v = trim($_s[0]); } $auto[$key] .= sprintf('{ name: "%s", to: "%s" }, ', Pluf_esc($d), Pluf_esc($v)); } $auto[$key] = substr($auto[$key], 0, -2); } // Get the members/owners $m = $project->getMembershipData(); $auto['_auto_owner'] = $m['members']; $auto['auto_owner'] = ''; foreach ($m['owners'] as $owner) { if (!Pluf_Model_InArray($owner, $auto['_auto_owner'])) { $auto['_auto_owner'][] = $owner; } } foreach ($auto['_auto_owner'] as $owner) { $auto['auto_owner'] .= sprintf('{ name: "%s", to: "%s" }, ', Pluf_esc($owner), Pluf_esc($owner->login)); } $auto['auto_owner'] = substr($auto['auto_owner'], 0, -2); unset($auto['_auto_owner']); return $auto; }
/** * Validate the interconnection in the form. */ public function clean() { // We need to check that no label with the 'Status' class is // given. if (!$this->show_full) { return $this->cleaned_data; } $conf = new IDF_Conf(); $conf->setProject($this->project); $onemax = array(); foreach (explode(',', $conf->getVal('labels_issue_one_max', IDF_Form_IssueTrackingConf::init_one_max)) as $class) { if (trim($class) != '') { $onemax[] = mb_strtolower(trim($class)); } } $count = array(); for ($i = 1; $i < 7; $i++) { $this->cleaned_data['label' . $i] = trim($this->cleaned_data['label' . $i]); if (strpos($this->cleaned_data['label' . $i], ':') !== false) { list($class, $name) = explode(':', $this->cleaned_data['label' . $i], 2); list($class, $name) = array(mb_strtolower(trim($class)), trim($name)); } else { $class = 'other'; $name = $this->cleaned_data['label' . $i]; } if ($class == 'status') { if (!isset($this->errors['label' . $i])) { $this->errors['label' . $i] = array(); } $this->errors['label' . $i][] = __('You cannot add a label with the "Status" prefix to an issue.'); throw new Pluf_Form_Invalid(__('You provided an invalid label.')); } if (!isset($count[$class])) { $count[$class] = 1; } else { $count[$class] += 1; } if (in_array($class, $onemax) and $count[$class] > 1) { if (!isset($this->errors['label' . $i])) { $this->errors['label' . $i] = array(); } $this->errors['label' . $i][] = sprintf(__('You cannot provide more than label from the %s class to an issue.'), $class); throw new Pluf_Form_Invalid(__('You provided an invalid label.')); } } return $this->cleaned_data; }
/** * Removes the (monotone) key from all monotone projects of this forge * where the user of the key has write access to */ public function processKeyDelete($key) { try { if ($key->getType() != 'mtn') { return; } } catch (Exception $e) { // bad key type, skip it. return; } if (Pluf::f('mtn_db_access', 'local') == 'local') { return; } foreach (Pluf::factory('IDF_Project')->getList() as $project) { $conf = new IDF_Conf(); $conf->setProject($project); $scm = $conf->getVal('scm', 'mtn'); if ($scm != 'mtn') { continue; } $projectpath = self::_get_project_path($project); $auth_ids = self::_get_authorized_user_ids($project); if (!in_array($key->user, $auth_ids)) { continue; } $mtn_key_id = $key->getMtnId(); // if the project is not defined as private, all people have // read access already, so we don't need to write anything // and we currently do not check if read-permissions really // contains // pattern "*" // allow "*" // which is the default for non-private projects if ($project->private) { $read_perms = file_get_contents($projectpath . '/read-permissions'); $parsed_read_perms = array(); try { $parsed_read_perms = IDF_Scm_Monotone_BasicIO::parse($read_perms); } catch (Exception $e) { throw new IDF_Scm_Exception(sprintf(__('Could not parse read-permissions for project "%s": %s'), $shortname, $e->getMessage())); } // while we add new keys only to an existing wild-card entry // we remove dropped keys from all sections since the key // should be simply unavailable for all of them for ($h = 0; $h < count($parsed_read_perms); ++$h) { for ($i = 0; $i < count($parsed_read_perms[$h]); ++$i) { if ($parsed_read_perms[$h][$i]['key'] == 'allow' && $parsed_read_perms[$h][$i]['values'][0] == $mtn_key_id) { unset($parsed_read_perms[$h][$i]); continue; } } } $read_perms = IDF_Scm_Monotone_BasicIO::compile($parsed_read_perms); if (file_put_contents($projectpath . '/read-permissions', $read_perms, LOCK_EX) === false) { throw new IDF_Scm_Exception(sprintf(__('Could not write read-permissions for project "%s"'), $shortname)); } } $write_perms = file_get_contents($projectpath . '/write-permissions'); $lines = preg_split("/(\n|\r\n)/", $write_perms, -1, PREG_SPLIT_NO_EMPTY); for ($i = 0; $i < count($lines); ++$i) { if ($lines[$i] == $mtn_key_id) { unset($lines[$i]); // the key should actually only exist once in the // file, but we're paranoid continue; } } if (file_put_contents($projectpath . '/write-permissions', implode("\n", $lines) . "\n", LOCK_EX) === false) { throw new IDF_Scm_Exception(sprintf(__('Could not write write-permissions file for project "%s"'), $shortname)); } $mtn = IDF_Scm_Monotone::factory($project); $stdio = $mtn->getStdio(); // if the public key did not sign any revisions, drop it from // the database as well try { if (strlen($stdio->exec(array('select', 'k:' . $mtn_key_id))) == 0) { $stdio->exec(array('drop_public_key', $mtn_key_id)); } } catch (IDF_Scm_Exception $e) { if (strpos($e->getMessage(), 'there is no key named') === false) { throw $e; } } } }
/** * Set the git export value. * * @param string Relative path of the repository (not .git) * @param string Full path of the repository with .git */ public function setGitExport($relpath, $fullpath) { $sql = new Pluf_SQL('shortname=%s', array($relpath)); $projects = Pluf::factory('IDF_Project')->getList(array('filter' => $sql->gen())); if ($projects->count() != 1 and file_exists($fullpath)) { return $this->gitExportDeny($fullpath); } $project = $projects[0]; $conf = new IDF_Conf(); $conf->setProject($project); $scm = $conf->getVal('scm', 'git'); if ($scm == 'git' and !file_exists($fullpath)) { // No repository yet, just skip return false; } if ($scm != 'git' or $project->private) { return $this->gitExportDeny($fullpath); } if ('all' == $conf->getVal('source_access_rights', 'all')) { return $this->gitExportAllow($fullpath); } return $this->gitExportDeny($fullpath); }
/** * Create the autocomplete arrays for the little AJAX stuff. */ public static function autoCompleteArrays($project) { $conf = new IDF_Conf(); $conf->setProject($project); $st = preg_split("/\r\n|\r|\n/", $conf->getVal('labels_download_predefined', IDF_Form_UploadConf::init_predefined), -1, PREG_SPLIT_NO_EMPTY); $auto = ''; foreach ($st as $s) { $v = ''; $d = ''; $_s = explode('=', $s, 2); if (count($_s) > 1) { $v = trim($_s[0]); $d = trim($_s[1]); } else { $v = trim($_s[0]); } $auto .= sprintf('{ name: "%s", to: "%s" }, ', Pluf_esc($d), Pluf_esc($v)); } return substr($auto, 0, -2); }
/** * Generate the dav_svn.authz file * * We rebuild the complete file each time. This is just to be sure * not to bork the rights when trying to just edit part of the * file. * * @param IDF_Project Possibly exclude a project (null) */ function SyncAccess($exclude = null) { $authz_file = Pluf::f('idf_plugin_syncsvn_authz_file'); $access_owners = Pluf::f('idf_plugin_syncsvn_access_owners', 'rw'); $access_members = Pluf::f('idf_plugin_syncsvn_access_members', 'rw'); $access_extra = Pluf::f('idf_plugin_syncsvn_access_extra', 'r'); $access_public = Pluf::f('idf_plugin_syncsvn_access_public', 'r'); $access_public_priv = Pluf::f('idf_plugin_syncsvn_access_private', ''); if (!file_exists($authz_file) or !is_writable($authz_file)) { return false; } $fcontent = ''; foreach (Pluf::factory('IDF_Project')->getList() as $project) { if ($exclude and $exclude->id == $project->id) { continue; } $conf = new IDF_Conf(); $conf->setProject($project); if ($conf->getVal('scm') != 'svn' or strlen($conf->getVal('svn_remote_url')) > 0) { continue; } $mem = $project->getMembershipData(); // [shortname:/] $fcontent .= '[' . $project->shortname . ':/]' . "\n"; foreach ($mem['owners'] as $v) { $fcontent .= $v->login . ' = ' . $access_owners . "\n"; } foreach ($mem['members'] as $v) { $fcontent .= $v->login . ' = ' . $access_members . "\n"; } // access for all users if ($project->private == true) { foreach ($mem['authorized'] as $v) { $fcontent .= $v->login . ' = ' . $access_extra . "\n"; } $fcontent .= '* = ' . $access_public_priv . "\n"; } else { $fcontent .= '* = ' . $access_public . "\n"; } $fcontent .= "\n"; } file_put_contents($authz_file, $fcontent, LOCK_EX); return true; }
public function save($commit = true) { if (!$this->isValid()) { throw new Exception(__('Cannot save the model from an invalid form.')); } $project = new IDF_Project(); $project->name = $this->cleaned_data['name']; $project->shortname = $this->cleaned_data['shortname']; $project->private = $this->cleaned_data['private_project']; $project->description = __('Click on the Project Management tab to set the description of your project.'); $project->create(); $conf = new IDF_Conf(); $conf->setProject($project); $keys = array('scm', 'svn_remote_url', 'svn_username', 'svn_password'); foreach ($keys as $key) { $this->cleaned_data[$key] = !empty($this->cleaned_data[$key]) ? $this->cleaned_data[$key] : ''; $conf->setVal($key, $this->cleaned_data[$key]); } $project->created(); IDF_Form_MembersConf::updateMemberships($project, $this->cleaned_data); $project->membershipsUpdated(); return $project; }
public function save($commit = true) { if (!$this->isValid()) { throw new Exception(__('Cannot save the model from an invalid form.')); } $project = new IDF_Project(); $project->name = $this->cleaned_data['name']; $project->shortname = $this->cleaned_data['shortname']; $project->shortdesc = $this->cleaned_data['shortdesc']; if ($this->cleaned_data['template'] != '--') { // Find the template project $sql = new Pluf_SQL('shortname=%s', array($this->cleaned_data['template'])); $tmpl = Pluf::factory('IDF_Project')->getOne(array('filter' => $sql->gen())); $project->private = $tmpl->private; $project->description = $tmpl->description; } else { $project->private = $this->cleaned_data['private_project']; $project->description = __('Click on the Project Management tab to set the description of your project.'); } $project->create(); $conf = new IDF_Conf(); $conf->setProject($project); $keys = array('scm', 'svn_remote_url', 'svn_username', 'svn_password', 'mtn_master_branch'); foreach ($keys as $key) { $this->cleaned_data[$key] = !empty($this->cleaned_data[$key]) ? $this->cleaned_data[$key] : ''; $conf->setVal($key, $this->cleaned_data[$key]); } if ($this->cleaned_data['template'] != '--') { $tmplconf = new IDF_Conf(); $tmplconf->setProject($tmpl); // We need to get all the configuration variables we want from // the old project and put them into the new project. $props = array('labels_download_predefined' => IDF_Form_UploadConf::init_predefined, 'labels_download_one_max' => IDF_Form_UploadConf::init_one_max, 'labels_wiki_predefined' => IDF_Form_WikiConf::init_predefined, 'labels_wiki_one_max' => IDF_Form_WikiConf::init_one_max, 'labels_issue_template' => IDF_Form_IssueTrackingConf::init_template, 'labels_issue_open' => IDF_Form_IssueTrackingConf::init_open, 'labels_issue_closed' => IDF_Form_IssueTrackingConf::init_closed, 'labels_issue_predefined' => IDF_Form_IssueTrackingConf::init_predefined, 'labels_issue_one_max' => IDF_Form_IssueTrackingConf::init_one_max, 'webhook_url' => '', 'downloads_access_rights' => 'all', 'review_access_rights' => 'all', 'wiki_access_rights' => 'all', 'source_access_rights' => 'all', 'issues_access_rights' => 'all', 'downloads_notification_email' => '', 'review_notification_email' => '', 'wiki_notification_email' => '', 'source_notification_email' => '', 'issues_notification_email' => ''); foreach ($props as $prop => $def) { $conf->setVal($prop, $tmplconf->getVal($prop, $def)); } } $project->created(); if ($this->cleaned_data['template'] == '--') { IDF_Form_MembersConf::updateMemberships($project, $this->cleaned_data); } else { // Get the membership of the template $tmpl IDF_Form_MembersConf::updateMemberships($project, $tmpl->getMembershipData('string')); } $project->membershipsUpdated(); return $project; }