index_dir($routed, $remainder); } /** * Handle POSTing a new user, or GETing the index. */ public function index_dir($routed, $remainder) { $method = $_SERVER['REQUEST_METHOD']; switch ($method) { case 'POST': // We're POSTing a new user. if ($this->registrationOpen()) { $this->create_user(); } else { $this->showView('users/new-locked', array()); exit(); } break; case 'HEAD': // fall-through to GET case 'GET': // We're GETing the index. $this->show_index($routed, $remainder); break; } } /** * Handle PUTing an updated user index, or GETing the index. */ public function index_file($routed, $remainder) { $method = $_SERVER['REQUEST_METHOD']; switch ($method) { case 'PUT': $_POST = $_PUT; case 'POST': // We're PUTing an updated user index. $this->update_users(); break; } $this->show_index($routed, $remainder); } // Other Views /////////////////////////////////////////////// /** * Handle GETing the new user form. * * I would have named this `new', but that's a keyword. */ public function new_user($routed, $vars) { // since there will never be a remainder to `users/new', we can // use that parameter to pass in some data. if (Login::isLoggedIn()) { $this->showView('users/new-logged-in', array()); exit(); } if (!$this->registrationOpen()) { $this->showView('users/new-locked', array()); exit(); } if (!isset($vars['errors'])) $vars['errors'] = array(); global $mm; $pm = $mm->pluginManager(); $vars['antispam_html'] = $pm->callHook('antispam_html'); $this->showView('users/new', $vars); } public function individual($routed, $remainder) { $username = implode('/', $remainder); global $mm; // also used for pluginmanager $db = $mm->database(); $uid = $db->getUID($username); $user = Auth::getObj($uid); if ($user->isGroup()) $uid = false; // ignore groups. if ($uid===false) { $this->http404($routed, $remainder); } else { if (!$user->canRead()) { $this->http401($routed, $remainder); exit(); } $vars = array(); $method = $_SERVER['REQUEST_METHOD']; switch ($method) { case 'PUT': $_POST = $_PUT; case 'POST': // We're PUTing updated user info. if ($user->canEdit()) { $vars = $this->update_user($user); } break; } $config_options = array(); $mm->pluginManager()->callHook('userConfig', &$config_options); $vars['config_options'] = $config_options; $vars['user'] = $user; $vars['groups'] = $db->listGroupNames(); require_once('ContactMethod.class.php'); $this->showView('users/individual', $vars); } } public function http404($routed, $remainder) { $username = implode('/', $remainder); $this->showView('users/404', array('username'=>$username)); } public function http401($routed, $remainder) { $this->showView('users/401', array('uid'=>Login::isLoggedIn())); } // Other Functions /////////////////////////////////////////// /** * This will parse POST data to create a new user. * If successfull it will show a message saying so. * If not successfull, it will re-show the new-user form with errors * explained. */ private function create_user() { global $mm; $db = $mm->database(); $pm = $mm->pluginManager(); $vars = array(); @$vars['username' ] = $_POST['auth_name']; @$vars['password1'] = $_POST['auth_password' ]; @$vars['password2'] = $_POST['auth_password_verify']; @$vars['email'] = $_POST['user_email']; $vars['errors'] = array(); if ($db->getUID($vars['username'])!==false) $vars['errors'][] = 'user exists'; if (!Auth::isNameLegal($vars['username'])) $vars['errors'][] = 'illegal name'; $matches = ($vars['password1'] == $vars['password2']); if (!$matches) { $vars['errors'][] = 'pw mixmatch'; } if ($matches && $vars['password2'] == '') { $vars['errors'][] = 'no pw'; } if ($vars['email'] == '') { $vars['errors'][] = 'no email'; } foreach ($pm->callHook('antispam_verify') as $plugin=>$valid) { if (!$valid) $vars['errors'][] = 'plugin_'.$plugin; } if (count($vars['errors']) > 0) { $this->new_user($routed, $vars); } else { $username = $vars['username']; $password = $vars['password1']; $uid = $db->addUser($username, $password); if ($uid===false) { $this->showView('users/500'); } else { Login::login($username, $password); $this->setConf($uid, 'email', $vars['email']); $this->showView('users/created', array('username'=>$username)); } } } /** * This will parse POST (really, PUT) data to update a single user */ private function update_user($user) { $vars = array(); $username = $user->getName(); // Change the username ///////////////////////////////////////// if (isset($_POST['auth_name'])) { $new_name = $_POST['auth_name']; if ($new_name != $username) { $changed_name = $user->setName($new_name); $username = $user->getName(); $vars['changed name'] = $changed_name; } } // Change the password ///////////////////////////////////////// @$password1 = $_POST['auth_password' ]; @$password2 = $_POST['auth_password'.'_verify']; // Check the verify box, not main box, so that we don't get // tripped by browsers annoyingly autocompleting the password. $is_set = ($password2 != ''); if ($is_set) { $matches = ( $password1 == $password2 ); if ($matches) { $user->setPassword($password1); $vars['pw updated'] = true; } else { $vars['pw mixmatch'] = true; } } // Change information ////////////////////////////////////////// $config_options = array(); global $mm; $mm->pluginManager()->callHook('userConfig', &$config_options); foreach ($config_options as $group=>$options) { foreach ($options as $option) { $this->confText($user, $option[0]); } } // Change contact info ///////////////////////////////////////// global $CONTACT_METHODS; foreach ($CONTACT_METHODS as $method) { $this->confText($user, $method->addr_slug); } $this->confArray($user, 'use'); // Change groups /////////////////////////////////////////////// $this->confArray($user, 'groups'); return $vars; } private function confArray($user, $key) { if (isset($_POST[$key]) && is_array($_POST[$key])) { $user->setConfArray($key, $_POST[$key]); } } private function confText($user, $name) { if (isset($_POST["user_$name"])) { $user->setConf($name, $_POST["user_$name"]); } } /** * This will parse POST (really, PUT) data to update multiple users. */ private function update_users() { $attribs = $this->getIndexAttribs(); foreach ($attribs as $attrib) { $key = $attrib['key']; if (isset($_POST[$key]) && is_array($_POST[$key])) { $old = $_POST['_old'][$key]; foreach ($_POST[$key] as $uid => $value) { $doit = true; $forked = false; $have_old = isset($old[$uid]); if ($have_old) { @$value_base = $old[$uid]; $we_changed_it = $value_base != $value; if ($we_changed_it) { $user = Auth::getObj($uid); $value_fork = $this->getConf($user,$key); $value_fork = $value_fork['value']; if ($value_fork===false) $value_fork = 'false'; if ($value_fork===true) $value_fork = 'true'; $someone_else_changed_it = $value_fork != $value_base; if ($someone_else_changed_it) { if ($value == $value_fork) { // we might as well not have $we_changed_it = false; } else { $forked = true; } } } if (!$we_changed_it) { $doit = false;// nothing to do } } if ($doit) { $this->setConf($uid, $key, $value); } if ($forked) { echo "
\n";
						echo "Error: Value changed elsewhere, and I don't have real handling for this yet.\n";
						echo "UID: $uid\n";
						echo "Name: ".$user->getName()."\n";
						echo "Key: $key\n";
						echo "Value: Original  : "; var_dump($value_base);
						echo "Value: Other edit: "; var_dump($value_fork);
						echo "Value: This edit : "; var_dump($value);
						echo "
"; } } } } } /** * This will show the user index. */ private function show_index($routed, $remainder) { global $mm; $db = $mm->database(); $logged_in_user = Auth::getObj(Login::isLoggedIn()); if (!$logged_in_user->isUser()) { $this->http401($routed, $remainder); exit(); } $vars = array(); $vars['attribs'] = $this->getIndexAttribs(); $vars['users'] = array(); $uids = $db->listUsers(); foreach ($uids as $uid) { $user = Auth::getObj($uid); $vars['users'][$uid] = array(); foreach ($vars['attribs'] as $attrib) { $key = $attrib['key']; $props = $this->getConf($user, $key); $vars['users'][$uid][$key] = $props; } } $this->showView('users/index', $vars); } private function getConf($user, $key) { $logged_in_user = Auth::getObj(Login::isLoggedIn()); $uid = $user->getUID(); $post_key = $key."[$uid]"; @$value = $_POST[$post_key]; $editable = $user->canEdit(); switch ($key) { case 'auth_name': $value = $user->getName(); break; case 'auth_user': $editable = $editable && $logged_in_user->isAdmin(); $value = $user->isUser(); break; case 'auth_admin': $editable = $editable && $logged_in_user->isAdmin(); $value = $user->isAdmin(); break; case 'auth_delete': $editable = $editable && $logged_in_user->isAdmin(); $value = false; break; default: $value = $user->getConf($key); if ($value===false) $value=''; break; } return array('value'=>$value, 'post_key'=>$post_key, 'editable'=>$editable); } private function setConf($uid, $key, $value) { // So, this rocks because we don't have to check permissions, // the User object does that. $user = Auth::getObj($uid); switch ($key) { case 'auth_name': $user->setName($value); break; case 'auth_user': $user->setUser($value=='true'); break; case 'auth_admin': $user->setAdmin($value=='true'); break; case 'auth_delete': if ($value=='true') $user->delete(); default: $user->setConf($key, $value); break; } } function attrib($key, $name) { return array('key'=>$key, 'name'=>$name); } private function getIndexAttribs() { $attribs = array(); $attribs[] = $this->attrib('auth_user', 'Active'); if (Auth::getObj(Login::isLoggedIn())->isAdmin()) { $attribs[] = $this->attrib('auth_admin', 'Admin'); $attribs[] = $this->attrib('auth_delete', 'Delete'); } $attribs[] = $this->attrib('lastname','Last'); $attribs[] = $this->attrib('firstname','First'); $attribs[] = $this->attrib('hsclass','Class of'); $attribs[] = $this->attrib('phone','Phone number'); $attribs[] = $this->attrib('email','Email'); $attribs[] = $this->attrib('auth_name', 'Username'); return $attribs; } private function registrationOpen() { global $mm; $db = $mm->database(); $val = $db->getSysConf('registration_open'); switch ($val) { case 'true': return true; case 'false': return false; default: return true; } } }