/** * Logs the user out * * @param \thebuggenie\core\framework\Request $request * * @return bool */ public function runLogout(framework\Request $request) { if ($this->getUser() instanceof entities\User) { framework\Logging::log('Setting user logout state'); $this->getUser()->setOffline(); } framework\Context::logout(); if ($request->isAjaxCall()) { return $this->renderJSON(array('status' => 'logout ok', 'url' => framework\Context::getRouting()->generate(framework\Settings::getLogoutReturnRoute()))); } $this->forward(framework\Context::getRouting()->generate(framework\Settings::getLogoutReturnRoute())); }
/** * Returns a list of changed items with a specified class * * @param string $class The class name * * @return array */ public static function getChangedItems($class) { $retarr = array(); if (isset($_SESSION['changeableitems'][$class]) && is_array($_SESSION['changeableitems'][$class])) { foreach ($_SESSION['changeableitems'][$class] as $id => $changes) { if ($changes) { try { $retarr[$id] = $class::getB2DBTable()->selectById($id); } catch (\Exception $e) { \thebuggenie\core\framework\Logging::log("Changed item of type {$class}, id {$id} is invalid - unsetting", 'main', \thebuggenie\core\framework\Logging::LEVEL_NOTICE); unset($_SESSION['changeableitems'][$class][$id]); } } else { unset($_SESSION['changeableitems'][$class][$id]); } } } return $retarr; }
/** * Send a test email * * @Route(url="/mailing/test") * @param \thebuggenie\core\framework\Request $request */ public function runTestEmail(framework\Request $request) { if ($email_to = $request['test_email_to']) { try { if (framework\Context::getModule('mailing')->sendTestEmail($email_to)) { framework\Context::setMessage('module_message', framework\Context::getI18n()->__('The email was successfully accepted for delivery')); } else { framework\Context::setMessage('module_error', framework\Context::getI18n()->__('The email was not sent')); framework\Context::setMessage('module_error_details', framework\Logging::getMessagesForCategory('mailing', framework\Logging::LEVEL_NOTICE)); } } catch (\Exception $e) { framework\Context::setMessage('module_error', framework\Context::getI18n()->__('The email was not sent')); framework\Context::setMessage('module_error_details', $e->getMessage()); } } else { framework\Context::setMessage('module_error', framework\Context::getI18n()->__('Please specify an email address')); } $this->forward(framework\Context::getRouting()->generate('configure_module', array('config_module' => 'mailing'))); }
public function runTransitionIssues(framework\Request $request) { try { try { $transition = entities\WorkflowTransition::getB2DBTable()->selectById($request['transition_id']); } catch (\Exception $e) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => $this->getI18n()->__('This is not a valid transition'))); } $issue_ids = $request['issue_ids']; $status = null; $closed = false; foreach ($issue_ids as $issue_id) { $issue = entities\Issue::getB2DBTable()->selectById((int) $issue_id); if (!$issue->isWorkflowTransitionsAvailable() || !$transition->validateFromRequest($request)) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => framework\Context::getI18n()->__('The transition could not be applied to issue %issue_number because of %errors', array('%issue_number' => $issue->getFormattedIssueNo(), '%errors' => join(', ', $transition->getValidationErrors()))))); } try { $transition->transitionIssueToOutgoingStepFromRequest($issue, $request); } catch (\Exception $e) { $this->getResponse()->setHttpStatus(400); framework\Logging::log(framework\Logging::LEVEL_WARNING, 'Transition ' . $transition->getID() . ' failed for issue ' . $issue_id); framework\Logging::log(framework\Logging::LEVEL_WARNING, $e->getMessage()); return $this->renderJSON(array('error' => $this->getI18n()->__('The transition failed because of an error in the workflow. Check your workflow configuration.'))); } if ($status === null) { $status = $issue->getStatus(); } $closed = $issue->isClosed(); } framework\Context::loadLibrary('common'); $options = array('issue_ids' => array_keys($issue_ids), 'last_updated' => tbg_formatTime(time(), 20), 'closed' => $closed); $options['status'] = array('color' => $status->getColor(), 'name' => $status->getName(), 'id' => $status->getID()); if ($request->hasParameter('milestone_id')) { $milestone = new entities\Milestone($request['milestone_id']); $options['milestone_id'] = $milestone->getID(); $options['milestone_name'] = $milestone->getName(); } foreach (array('resolution', 'priority', 'category', 'severity') as $item) { $class = "\\thebuggenie\\core\\entities\\" . ucfirst($item); if ($request->hasParameter($item . '_id')) { if ($item_id = $request[$item . '_id']) { $itemobject = new $class($item_id); $itemname = $itemobject->getName(); } else { $item_id = 0; $itemname = '-'; } $options[$item] = array('name' => $itemname, 'id' => $item_id); } else { $method = 'get' . ucfirst($item); $itemname = $issue->{$method}() instanceof $class ? $issue->{$method}()->getName() : '-'; $item_id = $issue->{$method}() instanceof $class ? $issue->{$method}()->getID() : 0; $options[$item] = array('name' => $itemname, 'id' => $item_id); } } return $this->renderJSON($options); } catch (\Exception $e) { $this->getResponse()->setHttpStatus(400); framework\Logging::log(framework\Logging::LEVEL_WARNING, $e->getMessage()); return $this->renderJSON(array('error' => $this->getI18n()->__('An error occured when trying to apply the transition'))); } }
public function doLogin($username, $password, $mode = 1) { $validgroups = $this->getSetting('groups'); $base_dn = $this->getSetting('b_dn'); $dn_attr = $this->escape($this->getSetting('dn_attr')); $username_attr = $this->escape($this->getSetting('u_attr')); $fullname_attr = $this->escape($this->getSetting('f_attr')); $buddyname_attr = $this->escape($this->getSetting('b_attr')); $email_attr = $this->escape($this->getSetting('e_attr')); $groups_members_attr = $this->escape($this->getSetting('g_attr')); $user_class = framework\Context::getModule('auth_ldap')->getSetting('u_type'); $group_class = framework\Context::getModule('auth_ldap')->getSetting('g_type'); $email = null; $integrated_auth = $this->getSetting('integrated_auth'); /* * Do the LDAP check here. * * If a connection error or something, throw an exception and log * * If we can, set $mail and $realname to correct values from LDAP * otherwise don't touch those variables. * * To log do: * framework\Logging::log('error goes here', 'ldap', framework\Logging::LEVEL_FATAL); */ try { /* * First job is to connect to our control user (may be an anonymous bind) * so we can find the user we want to log in as/validate. */ $connection = $this->connect(); $control_user = $this->getSetting('control_user'); $control_password = $this->getSetting('control_pass'); $this->bind($connection, $control_user, $control_password); // Assume bind successful, otherwise we would have had an exception /* * Search for a user with the username specified. We search in the base_dn, so we can * find users in multiple parts of the directory, and only return users of a specific * class (default person). * * We want exactly 1 user to be returned. We get the user's full name, email, cn * and dn. */ $fields = array($fullname_attr, $buddyname_attr, $email_attr, 'cn', $dn_attr); $filter = '(&(objectClass=' . $this->escape($user_class) . ')(' . $username_attr . '=' . $this->escape($username) . '))'; $results = ldap_search($connection, $base_dn, $filter, $fields); if (!$results) { framework\Logging::log('failed to search for user: '******'ldap', framework\Logging::LEVEL_FATAL); throw new \Exception(framework\Context::geti18n()->__('Search failed: ') . ldap_error($connection)); } $data = ldap_get_entries($connection, $results); // User does not exist if ($data['count'] == 0) { framework\Logging::log('could not find user ' . $username . ', class ' . $user_class . ', attribute ' . $username_attr, 'ldap', framework\Logging::LEVEL_FATAL); throw new \Exception(framework\Context::geti18n()->__('User does not exist in the directory')); } // If we have more than 1 user, something is seriously messed up... if ($data['count'] > 1) { framework\Logging::log('too many users for ' . $username . ', class ' . $user_class . ', attribute ' . $username_attr, 'ldap', framework\Logging::LEVEL_FATAL); throw new \Exception(framework\Context::geti18n()->__('This user was found multiple times in the directory, please contact your administrator')); } /* * If groups are specified, perform group restriction tests */ if ($validgroups != '') { /* * We will repeat this for every group, but groups are supplied as a comma-separated list */ if (strstr($validgroups, ',')) { $groups = explode(',', $validgroups); } else { $groups = array(); $groups[] = $validgroups; } // Assumed we are initially banned $allowed = false; foreach ($groups as $group) { // No need to carry on looking if we have access if ($allowed == true) { continue; } /* * Find the group we are looking for, we search the entire directory as per users (See that stuff) * We want to find 1 group, if we don't get 1, silently ignore this group. */ $fields2 = array($groups_members_attr); $filter2 = '(&(objectClass=' . $this->escape($group_class) . ')(cn=' . $this->escape($group) . '))'; $results2 = ldap_search($connection, $base_dn, $filter2, $fields2); if (!$results2) { framework\Logging::log('failed to search for user after binding: ' . ldap_error($connection), 'ldap', framework\Logging::LEVEL_FATAL); throw new \Exception(framework\Context::geti18n()->__('Search failed ') . ldap_error($connection)); } $data2 = ldap_get_entries($connection, $results2); if ($data2['count'] != 1) { continue; } /* * Look through the group's member list. If we are found, grant access. */ foreach ($data2[0][strtolower($groups_members_attr)] as $member) { $member = preg_replace('/(?<=,) +(?=[a-zA-Z])/', '', $member); $user_dn = preg_replace('/(?<=,) +(?=[a-zA-Z])/', '', $data[0][strtolower($dn_attr)][0]); if (!is_numeric($member) && strtolower($member) == strtolower($user_dn)) { $allowed = true; } } } if ($allowed == false) { throw new \Exception(framework\Context::getI18n()->__('You are not a member of a group allowed to log in')); } } /* * Set user's properties. * Realname is obtained from directory, if not found we set it to the username * Email is obtained from directory, if not found we set it to blank */ if (!array_key_exists(strtolower($fullname_attr), $data[0])) { $realname = $username; } else { $realname = $data[0][strtolower($fullname_attr)][0]; } if (!array_key_exists(strtolower($buddyname_attr), $data[0])) { $buddyname = $username; } else { $buddyname = $data[0][strtolower($buddyname_attr)][0]; } if (!array_key_exists(strtolower($email_attr), $data[0])) { $email = ''; } else { $email = $data[0][strtolower($email_attr)][0]; } /* * If we are performing a non integrated authentication login, * now bind to the user and see if the credentials * are valid. We bind using the full DN of the user, so no need for DOMAIN\ stuff * on Windows, and more importantly it fixes other servers. * * If the bind fails (exception), we throw a nicer exception and don't continue. */ if ($mode == 1 && !$integrated_auth) { try { if (!is_array($data[0][strtolower($dn_attr)])) { $dn = $data[0][strtolower($dn_attr)]; } else { $dn = $data[0][strtolower($dn_attr)][0]; } $bind = $this->bind($connection, $this->escape($dn), $password); } catch (\Exception $e) { throw new \Exception(framework\Context::geti18n()->__('Your password was not accepted by the server')); } } elseif ($mode == 1) { if (!isset($_SERVER[$this->getSetting('integrated_auth_header')]) || $_SERVER[$this->getSetting('integrated_auth_header')] != $username) { throw new \Exception(framework\Context::geti18n()->__('HTTP authentication internal error.')); } } } catch (\Exception $e) { ldap_unbind($connection); throw $e; } try { /* * Get the user object. If the user exists, update the user's * data from the directory. */ $user = \thebuggenie\core\entities\User::getByUsername($username); if ($user instanceof \thebuggenie\core\entities\User) { $user->setBuddyname($buddyname); $user->setRealname($realname); $user->setPassword($user->getJoinedDate() . $username); // update password $user->setEmail($email); // update email address $user->save(); } else { /* * If not, and we are performing an initial login, create the user object * if we are validating a log in, kick the user out as the session is invalid. */ if ($mode == 1) { // create user $user = new \thebuggenie\core\entities\User(); $user->setUsername($username); $user->setRealname('temporary'); $user->setBuddyname($username); $user->setEmail('temporary'); $user->setEnabled(); $user->setActivated(); $user->setJoined(); $user->setPassword($user->getJoinedDate() . $username); $user->save(); } else { throw new \Exception('User does not exist in TBG'); } } } catch (\Exception $e) { ldap_unbind($connection); throw $e; } ldap_unbind($connection); /* * Set cookies and return user row for general operations. */ framework\Context::getResponse()->setCookie('tbg3_username', $username); framework\Context::getResponse()->setCookie('tbg3_password', \thebuggenie\core\entities\User::hashPassword($user->getJoinedDate() . $username, $user->getSalt())); return \thebuggenie\core\entities\tables\Users::getTable()->getByUsername($username); }
/** * Authenticates a request via application password. * The given token is created by requesting authentication via an API endpoint, * which also marks the password as "used" and thus usable here. * * @param string $token * @return boolean */ public function authenticateApplicationPassword($token) { $applicationPasswords = $this->getApplicationPasswords(); framework\Logging::log('Cycling application passwords for given user. Count: ' . count($applicationPasswords), 'auth', framework\Logging::LEVEL_INFO); // Create hash for comparison with db value $hashed_token = self::hashPassword($token, $this->getSalt()); foreach ($applicationPasswords as $password) { if ($password->getHashPassword() == $hashed_token) { framework\Logging::log('Token hash matches.', 'auth', framework\Logging::LEVEL_INFO); $password->useOnce(); $password->save(); return true; } } framework\Logging::log('No token hash matched.', 'auth', framework\Logging::LEVEL_INFO); return false; }
public function getUploadStatus($id) { Logging::log('sanitizing id'); // sanitize the ID value $id = preg_replace('/[^a-z0-9]/i', '', $id); if (mb_strlen($id) == 0) { Logging::log('oops, invalid id ' . $id); return; } // ensure the uploaded status data exists in the session if (!array_key_exists($id, $_SESSION['__upload_status'])) { Logging::log('upload with this id ' . $id . ' is not in progress yet'); $_SESSION['__upload_status'][$id] = array('id' => $id, 'finished' => false, 'percent' => 0, 'total' => 0, 'complete' => 0); } // retrieve the data from the session so it can be updated and returned $ret = $_SESSION['__upload_status'][$id]; // if we can't retrieve the status or the upload has finished just return if (!self::CanGetUploadStatus() || $ret['finished']) { Logging::log('upload either finished or we cant track it'); // $ret['finished'] = true; // $ret['percent'] = 100; // $ret['complete'] = 100; return $ret; } // retrieve the upload data from APC $status = apc_fetch('upload_' . $id); // false is returned if the data isn't found if ($status) { $ret['finished'] = (bool) $status['done']; $ret['total'] = $status['total']; $ret['complete'] = $status['current']; if (array_key_exists('file_id', $ret)) { $status['file_id'] = $ret['file_id']; } elseif (array_key_exists('error', $ret)) { $status['failed'] = true; $status['error'] = $ret['error']; } // calculate the completed percentage if ($ret['total'] > 0) { $ret['percent'] = $ret['complete'] / $ret['total'] * 100; } // write the changed data back to the session $_SESSION['__upload_status'][$id] = $ret; } return $ret; }
public static function loadSettings($uid = 0) { Logging::log("Loading settings"); if (self::$_settings === null || $uid > 0 && !array_key_exists($uid, self::$_loadedsettings)) { Logging::log('Loading settings'); if (self::$_settings === null) { self::$_settings = array(); } Logging::log('Settings not cached or install mode enabled. Retrieving from database'); if ($res = tables\Settings::getTable()->getSettingsForScope(Context::getScope()->getID(), $uid)) { $cc = 0; while ($row = $res->getNextRow()) { $cc++; self::$_settings[$row->get(tables\Settings::MODULE)][$row->get(tables\Settings::NAME)][$row->get(tables\Settings::UID)] = $row->get(tables\Settings::VALUE); } if ($cc == 0 && !Context::isInstallmode() && $uid == 0) { Logging::log('There were no settings stored in the database!', 'main', Logging::LEVEL_FATAL); throw new SettingsException('Could not retrieve settings from database (no settings stored)'); } } elseif (!Context::isInstallmode() && $uid == 0) { Logging::log('Settings could not be retrieved from the database!', 'main', Logging::LEVEL_FATAL); throw new SettingsException('Could not retrieve settings from database'); } self::$_loadedsettings[$uid] = true; self::$_timezone = new \DateTimeZone(self::getServerTimezoneIdentifier()); Logging::log('Retrieved'); } Logging::log("...done"); }
/** * Generate a url based on a route * * @param string $name The route key * @param array $params key=>value pairs of route parameters * @param boolean $relative Whether to generate an url relative to web root or an absolute * * @return string */ public function generate($name, $params = array(), $relative = true, $querydiv = '/', $divider = '/', $equals = '/') { if (mb_substr($name, 0, 1) == '@') { $name = mb_substr($name, 1); $details = explode('?', $name); $name = array_shift($details); if (count($details)) { $param_details = array_shift($details); $param_details = explode('&', $param_details); foreach ($param_details as $detail) { $param_detail = explode('=', $detail); if (count($param_detail) > 1) { $params[$param_detail[0]] = $param_detail[1]; } } } } if (!isset($this->routes[$name])) { Logging::log("The route '{$name}' does not exist", 'routing', Logging::LEVEL_FATAL); throw new \Exception("The route '{$name}' does not exist"); } list($url, , $names, $names_hash, $action, $module, , $options, , ) = $this->routes[$name]; $defaults = array('action' => $action, 'module' => $module); $params = self::arrayDeepMerge($defaults, $params); if (array_key_exists('csrf_enabled', $options) && $options['csrf_enabled']) { $params['csrf_token'] = Context::generateCSRFtoken(); } // all params must be given foreach ($names as $tmp) { if (!isset($params[$tmp]) && !isset($defaults[$tmp])) { throw new \Exception(sprintf('Route named "%s" have a mandatory "%s" parameter', $name, $tmp)); } } // in PHP 5.5, preg_replace with /e modifier is deprecated; preg_replace_callback is recommended $callback = function ($matches) use($params) { return array_key_exists($matches[1], $params) ? urlencode($params[$matches[1]]) : $matches[0]; }; $real_url = preg_replace_callback('/\\:([^\\/]+)/', $callback, $url); // we add all other params if * if (mb_strpos($real_url, '*')) { $tmp = array(); foreach ($params as $key => $value) { if (isset($names_hash[$key]) || isset($defaults[$key])) { continue; } if (is_array($value)) { foreach ($value as $k => $v) { if (is_array($v)) { foreach ($v as $vk => $vv) { if (is_array($vv)) { foreach ($vv as $vvk => $vvv) { $tmp[] = "{$key}[{$k}][{$vk}][{$vvk}]" . $equals . urlencode($vvv); } } else { $tmp[] = "{$key}[{$k}][{$vk}]" . $equals . urlencode($vv); } } } else { $tmp[] = "{$key}[{$k}]" . $equals . urlencode($v); } } } else { $tmp[] = urlencode($key) . $equals . urlencode($value); } } $tmp = implode($divider, $tmp); if (mb_strlen($tmp) > 0) { $tmp = $querydiv . $tmp; } $real_url = preg_replace('/\\/\\*(\\/|$)/', "{$tmp}\$1", $real_url); } // strip off last divider character if (mb_strlen($real_url) > 1) { $real_url = rtrim($real_url, $divider); } if (!$relative) { return Context::getURLhost() . Context::getStrippedWebroot() . $real_url; } return Context::getStrippedWebroot() . $real_url; }
public function runUpload(framework\Request $request) { $apc_exists = framework\Request::CanGetUploadStatus(); if ($apc_exists && !$request['APC_UPLOAD_PROGRESS']) { $request->setParameter('APC_UPLOAD_PROGRESS', $request['upload_id']); } $this->getResponse()->setDecoration(\thebuggenie\core\framework\Response::DECORATE_NONE); $canupload = false; if ($request['mode'] == 'issue') { $issue = entities\Issue::getB2DBTable()->selectById($request['issue_id']); $canupload = (bool) ($issue instanceof entities\Issue && $issue->hasAccess() && $issue->canAttachFiles()); } elseif ($request['mode'] == 'article') { $article = \thebuggenie\modules\publish\entities\Article::getByID($request['article_id']); $canupload = (bool) ($article instanceof \thebuggenie\modules\publish\entities\Article && $article->canEdit()); } else { $event = \thebuggenie\core\framework\Event::createNew('core', 'upload', $request['mode']); $event->triggerUntilProcessed(); $canupload = $event->isProcessed() ? (bool) $event->getReturnValue() : true; } if ($canupload) { try { $file = framework\Context::getRequest()->handleUpload('uploader_file'); if ($file instanceof entities\File) { switch ($request['mode']) { case 'issue': if (!$issue instanceof entities\Issue) { break; } $issue->attachFile($file, $request->getRawParameter('comment'), $request['uploader_file_description']); $issue->save(); break; case 'article': if (!$article instanceof \thebuggenie\modules\publish\entities\Article) { break; } $article->attachFile($file); break; } if ($apc_exists) { return $this->renderText('ok'); } } $this->error = framework\Context::getI18n()->__('An unhandled error occured with the upload'); } catch (\Exception $e) { $this->getResponse()->setHttpStatus(400); $this->error = $e->getMessage(); } } else { $this->error = framework\Context::getI18n()->__('You are not allowed to attach files here'); } if (!$apc_exists) { switch ($request['mode']) { case 'issue': if (!$issue instanceof entities\Issue) { break; } $this->forward(framework\Context::getRouting()->generate('viewissue', array('project_key' => $issue->getProject()->getKey(), 'issue_no' => $issue->getFormattedIssueNo()))); break; case 'article': if (!$article instanceof \thebuggenie\modules\publish\entities\Article) { break; } $this->forward(framework\Context::getRouting()->generate('publish_article_attachments', array('article_id' => $article->getID()))); break; } } framework\Logging::log('marking upload ' . $request['APC_UPLOAD_PROGRESS'] . ' as completed with error ' . $this->error); $request->markUploadAsFinishedWithError($request['APC_UPLOAD_PROGRESS'], $this->error); return $this->renderText($request['APC_UPLOAD_PROGRESS'] . ': ' . $this->error); }
public function log($message, $level = 1) { framework\Logging::log($message, $this->getName(), $level); }
/** * Authenticate an application using a one-time application password. * Creates a token to be used for subsequent requests. * * @param framework\Request $request */ public function runAuthenticate(framework\Request $request) { framework\Logging::log('Authenticating new application password.', 'api', framework\Logging::LEVEL_INFO); $username = trim($request['username']); $password = trim($request['password']); if ($username) { $user = tables\Users::getTable()->getByUsername($username); if ($password && $user instanceof entities\User) { // Generate token from the application password $token = entities\ApplicationPassword::createToken($password); // Crypt, for comparison with db value $hashed_token = entities\User::hashPassword($token, $user->getSalt()); foreach ($user->getApplicationPasswords() as $app_password) { // Only return the token for new application passwords! if (!$app_password->isUsed()) { if ($app_password->getHashPassword() == $hashed_token) { $app_password->useOnce(); $app_password->save(); return $this->renderJSON(array('token' => $token, 'name' => $app_password->getName(), 'created_at' => $app_password->getCreatedAt())); } } } } framework\Logging::log('No password matched.', 'api', framework\Logging::LEVEL_INFO); } $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('error' => 'Incorrect username or application password')); }
/** * Import all valid users * * @param \thebuggenie\core\framework\Request $request */ public function runImportUsers(framework\Request $request) { $validgroups = framework\Context::getModule('auth_ldap')->getSetting('groups'); $base_dn = framework\Context::getModule('auth_ldap')->getSetting('b_dn'); $dn_attr = framework\Context::getModule('auth_ldap')->getSetting('dn_attr'); $username_attr = framework\Context::getModule('auth_ldap')->getSetting('u_attr'); $fullname_attr = framework\Context::getModule('auth_ldap')->getSetting('f_attr'); $buddyname_attr = framework\Context::getModule('auth_ldap')->getSetting('b_attr'); $email_attr = framework\Context::getModule('auth_ldap')->getSetting('e_attr'); $groups_members_attr = framework\Context::getModule('auth_ldap')->getSetting('g_attr'); $user_class = framework\Context::getModule('auth_ldap')->getSetting('u_type'); $group_class = framework\Context::getModule('auth_ldap')->getSetting('g_type'); $users = array(); $importcount = 0; $updatecount = 0; try { /* * Connect and bind to the control user */ $connection = framework\Context::getModule('auth_ldap')->connect(); framework\Context::getModule('auth_ldap')->bind($connection, framework\Context::getModule('auth_ldap')->getSetting('control_user'), framework\Context::getModule('auth_ldap')->getSetting('control_pass')); /* * Get a list of all users of a certain objectClass */ $fields = array($fullname_attr, $buddyname_attr, $username_attr, $email_attr, 'cn', $dn_attr); $filter = '(objectClass=' . framework\Context::getModule('auth_ldap')->escape($user_class) . ')'; $results = ldap_search($connection, $base_dn, $filter, $fields); if (!$results) { framework\Logging::log('failed to search for users: ' . ldap_error($connection), 'ldap', framework\Logging::LEVEL_FATAL); throw new \Exception(framework\Context::geti18n()->__('Search failed: ') . ldap_error($connection)); } $data = ldap_get_entries($connection, $results); /* * For every user that exists, process it. */ for ($i = 0; $i != $data['count']; $i++) { $user_dn = $data[$i][strtolower($dn_attr)][0]; /* * If groups are specified, perform group restriction tests */ if ($validgroups != '') { /* * We will repeat this for every group, but groups are supplied as a comma-separated list */ if (strstr($validgroups, ',')) { $groups = explode(',', $validgroups); } else { $groups = array(); $groups[] = $validgroups; } // Assumed we are initially banned $allowed = false; foreach ($groups as $group) { // No need to carry on looking if we have access if ($allowed == true) { continue; } /* * Find the group we are looking for, we search the entire directory * We want to find 1 group, if we don't get 1, silently ignore this group. */ $fields2 = array($groups_members_attr); $filter2 = '(&(cn=' . framework\Context::getModule('auth_ldap')->escape($group) . ')(objectClass=' . framework\Context::getModule('auth_ldap')->escape($group_class) . '))'; $results2 = ldap_search($connection, $base_dn, $filter2, $fields2); if (!$results2) { framework\Logging::log('failed to search for user: '******'ldap', framework\Logging::LEVEL_FATAL); throw new \Exception(framework\Context::geti18n()->__('Search failed: ') . ldap_error($connection)); } $data2 = ldap_get_entries($connection, $results2); if ($data2['count'] != 1) { continue; } /* * Look through the group's member list. If we are found, grant access. */ foreach ($data2[0][strtolower($groups_members_attr)] as $member) { $member = preg_replace('/(?<=,) +(?=[a-zA-Z])/', '', $member); $user_dn = preg_replace('/(?<=,) +(?=[a-zA-Z])/', '', $user_dn); if (!is_numeric($member) && strtolower($member) == strtolower($user_dn)) { $allowed = true; } } } if ($allowed == false) { continue; } } $users[$i] = array(); /* * Set user's properties. * Realname is obtained from directory, if not found we set it to the username * Email is obtained from directory, if not found we set it to blank */ if (!array_key_exists(strtolower($fullname_attr), $data[$i])) { $users[$i]['realname'] = $data[$i]['cn'][0]; } else { $users[$i]['realname'] = $data[$i][strtolower($fullname_attr)][0]; } if (!array_key_exists(strtolower($buddyname_attr), $data[$i])) { $users[$i]['buddyname'] = $data[$i]['cn'][0]; } else { $users[$i]['buddyname'] = $data[$i][strtolower($buddyname_attr)][0]; } if (!array_key_exists(strtolower($email_attr), $data[$i])) { $users[$i]['email'] = ''; } else { $users[$i]['email'] = $data[$i][strtolower($email_attr)][0]; } $users[$i]['username'] = $data[$i][strtolower($username_attr)][0]; } } catch (\Exception $e) { framework\Context::setMessage('module_error', framework\Context::getI18n()->__('Import failed')); framework\Context::setMessage('module_error_details', $e->getMessage()); $this->forward(framework\Context::getRouting()->generate('configure_module', array('config_module' => 'auth_ldap'))); } /* * For every user that was found, either create a new user object, or update * the existing one. This will update the created and updated counts as appropriate. */ foreach ($users as $ldapuser) { $username = $ldapuser['username']; $email = $ldapuser['email']; $realname = $ldapuser['realname']; $buddyname = $ldapuser['buddyname']; try { $user = \thebuggenie\core\entities\User::getByUsername($username); if ($user instanceof \thebuggenie\core\entities\User) { $user->setRealname($realname); $user->setEmail($email); // update email address $user->save(); $updatecount++; } else { // create user $user = new \thebuggenie\core\entities\User(); $user->setUsername($username); $user->setRealname($realname); $user->setBuddyname($buddyname); $user->setEmail($email); $user->setEnabled(); $user->setActivated(); $user->setPassword($user->getJoinedDate() . $username); $user->setJoined(); $user->save(); $importcount++; } } catch (\Exception $e) { ldap_unbind($connection); framework\Context::setMessage('module_error', framework\Context::getI18n()->__('Import failed')); framework\Context::setMessage('module_error_details', $e->getMessage()); $this->forward(framework\Context::getRouting()->generate('configure_module', array('config_module' => 'auth_ldap'))); } } ldap_unbind($connection); framework\Context::setMessage('module_message', framework\Context::getI18n()->__('Import successful! %imp users imported, %upd users updated from LDAP', array('%imp' => $importcount, '%upd' => $updatecount))); $this->forward(framework\Context::getRouting()->generate('configure_module', array('config_module' => 'auth_ldap'))); }
public function __($text, $replacements = array(), $html_decode = false) { if (isset($this->_strings[$text])) { $retstring = $this->_strings[$text]; } else { $retstring = $this->__e($text); if (Context::isDebugMode()) { Logging::log('The text "' . $text . '" does not exist in list of translated strings.', 'i18n'); $this->_missing_strings[$text] = true; } } if (!empty($replacements)) { $retstring = str_replace(array_keys($replacements), array_values($replacements), $retstring); } if ($html_decode) { $retstring = html_entity_decode($retstring); } return $retstring; }
/** * Whether or not the current user can access the issue * * @return boolean */ public function hasAccess($target_user = null) { \thebuggenie\core\framework\Logging::log('checking access to issue ' . $this->getFormattedIssueNo()); $i_id = $this->getID(); $user = $target_user === null ? framework\Context::getUser() : $target_user; if (!$user->isGuest() && $user->isAuthenticated()) { $specific_access = $user->hasPermission("canviewissue", $i_id, 'core'); if ($specific_access !== null) { \thebuggenie\core\framework\Logging::log('done checking, returning specific access ' . ($specific_access ? 'allowed' : 'denied')); return $specific_access; } if ($this->getPostedByID() == $user->getID()) { \thebuggenie\core\framework\Logging::log('done checking, allowed since this user posted it'); return true; } if ($this->getOwner() instanceof \thebuggenie\core\entities\User && $this->getOwner()->getID() == $user->getID()) { \thebuggenie\core\framework\Logging::log('done checking, allowed since this user owns it'); return true; } if ($this->getAssignee() instanceof \thebuggenie\core\entities\User && $this->getAssignee()->getID() == $user->getID()) { \thebuggenie\core\framework\Logging::log('done checking, allowed since this user is assigned to it'); return true; } if ($user->hasPermission('canseegroupissues', 0, 'core') && $this->getPostedBy() instanceof \thebuggenie\core\entities\User && $this->getPostedBy()->getGroupID() == $user->getGroupID()) { \thebuggenie\core\framework\Logging::log('done checking, allowed since this user is in same group as user that posted it'); return true; } if ($user->hasPermission('canseeallissues', 0, 'core') === false) { \thebuggenie\core\framework\Logging::log('done checking, not allowed to access issues not posted by themselves'); return false; } } if ($this->getCategory() instanceof \thebuggenie\core\entities\Category) { if (!$this->getCategory()->hasAccess()) { \thebuggenie\core\framework\Logging::log('done checking, not allowed to access issues in this category'); return false; } } if ($this->getProject()->hasAccess()) { \thebuggenie\core\framework\Logging::log('done checking, can access project'); return true; } \thebuggenie\core\framework\Logging::log('done checking, denied'); return false; }
protected static function generateDebugInfo() { $tbg_summary = array(); $load_time = self::getLoadtime(); if (\b2db\Core::isInitialized()) { $tbg_summary['db']['queries'] = \b2db\Core::getSQLHits(); $tbg_summary['db']['timing'] = \b2db\Core::getSQLTiming(); $tbg_summary['db']['objectpopulation'] = \b2db\Core::getObjectPopulationHits(); $tbg_summary['db']['objecttiming'] = \b2db\Core::getObjectPopulationTiming(); $tbg_summary['db']['objectcount'] = \b2db\Core::getObjectPopulationCount(); } $tbg_summary['load_time'] = $load_time >= 1 ? round($load_time, 2) . 's' : round($load_time * 1000, 1) . 'ms'; $tbg_summary['scope'] = array(); $scope = self::getScope(); $tbg_summary['scope']['id'] = $scope instanceof Scope ? $scope->getID() : 'unknown'; $tbg_summary['scope']['hostnames'] = $scope instanceof Scope && \b2db\Core::isConnected() ? implode(', ', $scope->getHostnames()) : 'unknown'; $tbg_summary['settings'] = Settings::getAll(); $tbg_summary['memory'] = memory_get_usage(); $tbg_summary['partials'] = self::getVisitedPartials(); $tbg_summary['log'] = Logging::getEntries(); $tbg_summary['routing'] = array('name' => self::getRouting()->getCurrentRouteName(), 'module' => self::getRouting()->getCurrentRouteModule(), 'action' => self::getRouting()->getCurrentRouteAction()); if (isset($_SESSION)) { if (!array_key_exists('___DEBUGINFO___', $_SESSION)) { $_SESSION['___DEBUGINFO___'] = array(); } $_SESSION['___DEBUGINFO___'][self::$debug_id] = $tbg_summary; while (count($_SESSION['___DEBUGINFO___']) > 25) { array_shift($_SESSION['___DEBUGINFO___']); } } }
/** * Configure a module * * @param framework\Request $request The request object */ public function runConfigureModule(framework\Request $request) { $this->forward403unless($this->access_level == framework\Settings::ACCESS_FULL); try { $module = framework\Context::getModule($request['config_module']); if (!$module->isEnabled()) { throw new \Exception('disabled'); } elseif (!$module->hasConfigSettings()) { throw new \Exception('module not configurable'); } else { if ($request->isPost() && $this->access_level == framework\Settings::ACCESS_FULL) { try { $module->postConfigSettings($request); if (!framework\Context::hasMessage('module_message')) { framework\Context::setMessage('module_message', framework\Context::getI18n()->__('Settings saved successfully')); } } catch (\Exception $e) { framework\Context::setMessage('module_error', $e->getMessage()); } $this->forward(framework\Context::getRouting()->generate('configure_module', array('config_module' => $request['config_module']))); } $this->module = $module; } } catch (\Exception $e) { framework\Logging::log('Trying to configure module ' . $request['config_module'] . " which isn't configurable", 'main', framework\Logging::LEVEL_FATAL); framework\Context::setMessage('module_error', framework\Context::getI18n()->__('The module "%module_name" is not configurable', array('%module_name' => $request['config_module']))); $this->forward(framework\Context::getRouting()->generate('configure_modules')); } $this->module_message = framework\Context::getMessageAndClear('module_message'); $this->module_error = framework\Context::getMessageAndClear('module_error'); $this->module_error_details = framework\Context::getMessageAndClear('module_error_details'); }
echo link_tag(make_url('about'), 'The Bug Genie') . ' ' . \thebuggenie\core\framework\Settings::getVersion(); ?> <?php if ($tbg_user->canAccessConfigurationPage()) { ?> | <b><?php echo link_tag(make_url('configure'), __('Configure %thebuggenie_name', array('%thebuggenie_name' => \thebuggenie\core\framework\Settings::getSiteHeaderName()))); ?> </b> <?php } ?> | <a href="http://www.thebuggenie.com/support">Support</a> | <a href="http://www.thebuggenie.com/feedback">Feedback</a> <?php if (\thebuggenie\core\framework\Context::isDebugMode() && \thebuggenie\core\framework\Logging::isEnabled()) { ?> <script> function tbg_debug_show_menu_tab(tab, clicked) { $('debug-bar').childElements().each(function (unclicked) { unclicked.removeClassName('selected'); }); clicked.addClassName('selected'); $('debug-frames-container').childElements().each(function (container) { (container.id == tab) ? container.addClassName('selected') : container.removeClassName('selected'); }); } </script> <div id="tbg___DEBUGINFO___" style="position: fixed; bottom: 0; left: 0; z-index: 100; display: none; width: 100%;"> </div> <?php
public function componentTeamdropdown() { framework\Logging::log('team dropdown component'); $this->rnd_no = rand(); try { $this->team = isset($this->team) ? $this->team : null; if (!$this->team instanceof entities\Team) { framework\Logging::log('loading team object in dropdown'); $this->team = entities\Team::getB2DBTable()->selectById($this->team); framework\Logging::log('done (loading team object in dropdown)'); } } catch (\Exception $e) { } framework\Logging::log('done (team dropdown component)'); }
/** * Populates openid accounts array when needed */ protected function _populateOpenIDAccounts() { if ($this->_openid_accounts === null) { framework\Logging::log('Populating openid accounts'); $this->_openid_accounts = tables\OpenIdAccounts::getTable()->getIdentitiesForUserID($this->getID()); framework\Logging::log('...done (Populating user clients)'); } }
<?php if (is_array($tbg_summary)) { ?> <style type="text/css"> /* logging colors for categories */ <?php foreach (array("main", "B2DB", "core", "routing", "i18n", "cache", "search", "publish") as $category) { ?> .cat-<?php echo $category; ?> .badge.catname { background-color:#<?php echo \thebuggenie\core\framework\Logging::getCategoryColor($category); ?> ; color: #FFF; } <?php } ?> .catname { text-shadow: none; text-transform: uppercase; } h1 .log-selectors { float: right; font-size: 0.7em; } h1 .log-selectors .badge { opacity: 0.2; cursor: pointer; } h1 .log-selectors .badge.selected { opacity: 1; } #log_timing ul, #log_ajax ul, #log_messages ul, #debug_routes ul, #log_sql ol { list-style: none; padding: 0; margin: 0; } #log_timing ul li, #log_ajax ul li, #log_messages ul li { font-size: 1.1em; list-style: none; padding: 2px; margin: 2px 0; clear: both; display: block; } #log_timing ul li:hover, #log_ajax ul li:hover, #log_messages ul li:hover, #debug_routes ul li:hover { background-color: rgba(230, 230, 230, 0.1); } #debug_routes ul li.selected { background-color: rgba(160, 230, 160, 0.2); } #debug_routes ul li.selected:hover { background-color: rgba(160, 230, 160, 0.4); }
?> <?php \thebuggenie\core\framework\Logging::log('done (rendering header)'); ?> <?php } ?> <div id="content_container"> <?php \thebuggenie\core\framework\Logging::log('Rendering content'); ?> <?php echo $content; ?> <?php \thebuggenie\core\framework\Logging::log('done (rendering content)'); ?> </div> <?php \thebuggenie\core\framework\Event::createNew('core', 'layout.php::footer-begins')->trigger(); ?> <?php require THEBUGGENIE_CORE_PATH . 'templates/footer.inc.php'; ?> <?php \thebuggenie\core\framework\Event::createNew('core', 'layout.php::footer-ends')->trigger(); ?> </div> <?php require THEBUGGENIE_CORE_PATH . 'templates/backdrops.inc.php'; ?>
</span></span> <?php } ?> </div> </h1> <ul id="log_entries"> <?php foreach ($log as $entry) { ?> <li class="cat-<?php echo $entry['category']; ?> "> <span class="badge loglevel"><?php echo mb_strtoupper(\thebuggenie\core\framework\Logging::getLevelName($entry['level'])); ?> </span> <span class="badge catname"><?php echo $entry['category']; ?> </span> <span class="badge timing"><?php echo $entry['time']; ?> </span> <span class="logmessage"><?php echo $entry['message']; ?> </span> </li>
/** * Runs the action for the fourth step of the installation * where it loads fixtures and saves settings for url * * @param framework\Request $request The request object * * @return null */ public function runInstallStep4(framework\Request $request) { try { framework\Logging::log('Initializing language support'); framework\Context::reinitializeI18n('en_US'); framework\Logging::log('Loading fixtures for default scope'); $scope = new \thebuggenie\core\entities\Scope(); $scope->addHostname('*'); $scope->setName('The default scope'); $scope->setEnabled(true); framework\Context::setScope($scope); $scope->save(); framework\Settings::saveSetting('language', 'en_US', 'core', 1); \thebuggenie\core\entities\Module::installModule('publish'); \thebuggenie\core\entities\Module::installModule('agile'); \thebuggenie\core\entities\Module::installModule('mailing'); \thebuggenie\core\entities\Module::installModule('vcs_integration'); $this->htaccess_error = false; $this->htaccess_ok = (bool) $request['apache_autosetup']; if ($request['apache_autosetup']) { if (!is_writable(THEBUGGENIE_PATH . THEBUGGENIE_PUBLIC_FOLDER_NAME . '/') || file_exists(THEBUGGENIE_PATH . THEBUGGENIE_PUBLIC_FOLDER_NAME . '/.htaccess') && !is_writable(THEBUGGENIE_PATH . THEBUGGENIE_PUBLIC_FOLDER_NAME . '/.htaccess')) { $this->htaccess_error = 'Permission denied when trying to save the [main folder]/' . THEBUGGENIE_PUBLIC_FOLDER_NAME . '/.htaccess'; } else { $content = str_replace('###PUT URL SUBDIRECTORY HERE###', $request['url_subdir'], file_get_contents(THEBUGGENIE_CORE_PATH . '/templates/htaccess.template')); file_put_contents(THEBUGGENIE_PATH . THEBUGGENIE_PUBLIC_FOLDER_NAME . '/.htaccess', $content); if (file_get_contents(THEBUGGENIE_PATH . THEBUGGENIE_PUBLIC_FOLDER_NAME . '/.htaccess') != $content) { $this->htaccess_error = true; } } if (!is_writable(THEBUGGENIE_PATH . THEBUGGENIE_PUBLIC_FOLDER_NAME . '/') || file_exists(THEBUGGENIE_PATH . THEBUGGENIE_PUBLIC_FOLDER_NAME . '/.user.ini') && !is_writable(THEBUGGENIE_PATH . THEBUGGENIE_PUBLIC_FOLDER_NAME . '/.user.ini')) { $this->htaccess_error = 'Permission denied when trying to save the [main folder]/' . THEBUGGENIE_PUBLIC_FOLDER_NAME . '/.user.ini'; } else { $content = file_get_contents(THEBUGGENIE_CORE_PATH . '/templates/user.ini.template'); file_put_contents(THEBUGGENIE_PATH . THEBUGGENIE_PUBLIC_FOLDER_NAME . '/.user.ini', $content); if (file_get_contents(THEBUGGENIE_PATH . THEBUGGENIE_PUBLIC_FOLDER_NAME . '/.user.ini') != $content) { $this->htaccess_error = true; } } } } catch (\Exception $e) { $this->error = $e->getMessage(); throw $e; } }
</ul> <?php } ?> <?php if (class_exists('\\thebuggenie\\core\\framework\\Context') && class_exists("\thebuggenie\\core\framework\\Logging") && \thebuggenie\core\framework\Context::isDebugMode() && (!isset($exception) || !$exception instanceof \thebuggenie\core\framework\exceptions\ComposerException)) { ?> <h3>Log messages:</h3> <?php foreach (\thebuggenie\core\framework\Logging::getEntries() as $entry) { ?> <?php $color = \thebuggenie\core\framework\Logging::getCategoryColor($entry['category']); ?> <?php $lname = \thebuggenie\core\framework\Logging::getLevelName($entry['level']); ?> <div class="log_<?php echo $entry['category']; ?> "><strong><?php echo $lname; ?> </strong> <strong style="color: #<?php echo $color; ?> ">[<?php echo $entry['category']; ?> ]</strong> <span style="color: #555; font-size: 10px; font-style: italic;"><?php echo $entry['time'];