Exemplo n.º 1
0
 function saveWorkerPeekAction()
 {
     $translate = DevblocksPlatform::getTranslationService();
     $active_worker = CerberusApplication::getActiveWorker();
     if (!$active_worker || !$active_worker->is_superuser || DEMO_MODE) {
         return;
     }
     @($id = DevblocksPlatform::importGPC($_POST['id'], 'integer'));
     @($view_id = DevblocksPlatform::importGPC($_POST['view_id'], 'string'));
     @($first_name = DevblocksPlatform::importGPC($_POST['first_name'], 'string'));
     @($last_name = DevblocksPlatform::importGPC($_POST['last_name'], 'string'));
     @($title = DevblocksPlatform::importGPC($_POST['title'], 'string'));
     @($email = DevblocksPlatform::importGPC($_POST['email'], 'string'));
     @($password = DevblocksPlatform::importGPC($_POST['password'], 'string'));
     @($is_superuser = DevblocksPlatform::importGPC($_POST['is_superuser'], 'integer', 0));
     @($disabled = DevblocksPlatform::importGPC($_POST['is_disabled'], 'integer', 0));
     @($group_ids = DevblocksPlatform::importGPC($_POST['group_ids'], 'array'));
     @($group_roles = DevblocksPlatform::importGPC($_POST['group_roles'], 'array'));
     @($delete = DevblocksPlatform::importGPC($_POST['do_delete'], 'integer', 0));
     // [TODO] The superuser set bit here needs to be protected by ACL
     if (empty($first_name)) {
         $first_name = "Anonymous";
     }
     if (!empty($id) && !empty($delete)) {
         // Can't delete or disable self
         if ($active_worker->id != $id) {
             DAO_Worker::deleteAgent($id);
         }
     } else {
         if (empty($id) && null == DAO_Worker::lookupAgentEmail($email)) {
             $workers = DAO_Worker::getAll();
             $license = CerberusLicense::getInstance();
             if (!empty($license) && !empty($license['serial']) || count($workers) < 3) {
                 // Creating new worker.  If password is empty, email it to them
                 if (empty($password)) {
                     $settings = DevblocksPlatform::getPluginSettingsService();
                     $replyFrom = $settings->get('cerberusweb.core', CerberusSettings::DEFAULT_REPLY_FROM);
                     $replyPersonal = $settings->get('cerberusweb.core', CerberusSettings::DEFAULT_REPLY_PERSONAL, '');
                     $url = DevblocksPlatform::getUrlService();
                     $password = CerberusApplication::generatePassword(8);
                     try {
                         $mail_service = DevblocksPlatform::getMailService();
                         $mailer = $mail_service->getMailer(CerberusMail::getMailerDefaults());
                         $mail = $mail_service->createMessage();
                         $mail->setTo(array($email => $first_name . ' ' . $last_name));
                         $mail->setFrom(array($replyFrom => $replyPersonal));
                         $mail->setSubject('Your new helpdesk login information!');
                         $mail->generateId();
                         $headers = $mail->getHeaders();
                         $headers->addTextHeader('X-Mailer', 'Cerberus Helpdesk (Build ' . APP_BUILD . ')');
                         $body = sprintf("Your new helpdesk login information is below:\r\n" . "\r\n" . "URL: %s\r\n" . "Login: %s\r\n" . "Password: %s\r\n" . "\r\n" . "You should change your password from Preferences after logging in for the first time.\r\n" . "\r\n", $url->write('', true), $email, $password);
                         $mail->setBody($body);
                         if (!$mailer->send($mail)) {
                             throw new Exception('Password notification email failed to send.');
                         }
                     } catch (Exception $e) {
                         // [TODO] need to report to the admin when the password email doesn't send.  The try->catch
                         // will keep it from killing php, but the password will be empty and the user will never get an email.
                     }
                 }
                 $id = DAO_Worker::create($email, $password, '', '', '');
             }
         }
         // end create worker
         // Update
         $fields = array(DAO_Worker::FIRST_NAME => $first_name, DAO_Worker::LAST_NAME => $last_name, DAO_Worker::TITLE => $title, DAO_Worker::EMAIL => $email, DAO_Worker::IS_SUPERUSER => $is_superuser, DAO_Worker::IS_DISABLED => $disabled);
         // if we're resetting the password
         if (!empty($password)) {
             $fields[DAO_Worker::PASSWORD] = md5($password);
         }
         // Update worker
         DAO_Worker::updateAgent($id, $fields);
         // Update group memberships
         if (is_array($group_ids) && is_array($group_roles)) {
             foreach ($group_ids as $idx => $group_id) {
                 if (empty($group_roles[$idx])) {
                     DAO_Group::unsetTeamMember($group_id, $id);
                 } else {
                     DAO_Group::setTeamMember($group_id, $id, 2 == $group_roles[$idx]);
                 }
             }
         }
         // Add the worker e-mail to the addresses table
         if (!empty($email)) {
             DAO_Address::lookupAddress($email, true);
         }
         // Addresses
         if (null == DAO_AddressToWorker::getByAddress($email)) {
             DAO_AddressToWorker::assign($email, $id);
             DAO_AddressToWorker::update($email, array(DAO_AddressToWorker::IS_CONFIRMED => 1));
         }
         // Custom field saves
         @($field_ids = DevblocksPlatform::importGPC($_POST['field_ids'], 'array', array()));
         DAO_CustomFieldValue::handleFormPost(ChCustomFieldSource_Worker::ID, $id, $field_ids);
     }
     if (!empty($view_id)) {
         $view = C4_AbstractViewLoader::getView($view_id);
         $view->render();
     }
     //DevblocksPlatform::setHttpResponse(new DevblocksHttpResponse(array('config','workers')));
 }
Exemplo n.º 2
0
 public function writeResponse(DevblocksHttpResponse $response)
 {
     $umsession = UmPortalHelper::getSession();
     $stack = $response->path;
     $tpl = DevblocksPlatform::getTemplateService();
     $tpl_path = dirname(dirname(__FILE__)) . '/templates/';
     $tpl->assign('portal_code', UmPortalHelper::getCode());
     $page_title = DAO_CommunityToolProperty::get(UmPortalHelper::getCode(), self::PARAM_PAGE_TITLE, 'Support Center');
     $tpl->assign('page_title', $page_title);
     $login_handler = DAO_CommunityToolProperty::get(UmPortalHelper::getCode(), self::PARAM_LOGIN_HANDLER, '');
     $tpl->assign('login_handler', $login_handler);
     $login_extension = DevblocksPlatform::getExtension($login_handler, true);
     $tpl->assign('login_extension', $login_extension);
     @($visible_modules = unserialize(DAO_CommunityToolProperty::get(UmPortalHelper::getCode(), self::PARAM_VISIBLE_MODULES, '')));
     $tpl->assign('visible_modules', $visible_modules);
     @($active_user = $umsession->getProperty('sc_login', null));
     $tpl->assign('active_user', $active_user);
     // Usermeet Session
     if (null == ($fingerprint = UmPortalHelper::getFingerprint())) {
         die("A problem occurred.");
     }
     $tpl->assign('fingerprint', $fingerprint);
     $module_uri = array_shift($stack);
     switch ($module_uri) {
         case 'ajax':
             $controller = new UmScAjaxController(null);
             $controller->handleRequest(new DevblocksHttpRequest($stack));
             break;
         case 'rss':
             $controller = new UmScRssController(null);
             $controller->handleRequest(new DevblocksHttpRequest($stack));
             break;
         case 'captcha':
             @($color = DevblocksPlatform::parseCsvString(DevblocksPlatform::importGPC($_REQUEST['color'], 'string', '40,40,40')));
             @($bgcolor = DevblocksPlatform::parseCsvString(DevblocksPlatform::importGPC($_REQUEST['bgcolor'], 'string', '240,240,240')));
             // Sanitize colors
             // [TODO] Sanitize numeric range for elements 0-2
             if (3 != count($color)) {
                 $color = array(40, 40, 40);
             }
             if (3 != count($bgcolor)) {
                 $color = array(240, 240, 240);
             }
             header('Cache-control: max-age=0', true);
             // 1 wk // , must-revalidate
             header('Expires: ' . gmdate('D, d M Y H:i:s', time() - 604800) . ' GMT');
             // 1 wk
             header('Content-type: image/jpeg');
             // Get CAPTCHA secret passphrase
             $phrase = CerberusApplication::generatePassword(4);
             $umsession->setProperty(UmScApp::SESSION_CAPTCHA, $phrase);
             $im = @imagecreate(150, 70) or die("Cannot Initialize new GD image stream");
             $background_color = imagecolorallocate($im, $bgcolor[0], $bgcolor[1], $bgcolor[2]);
             $text_color = imagecolorallocate($im, $color[0], $color[1], $color[2]);
             $font = DEVBLOCKS_PATH . 'resources/font/ryanlerch_-_Tuffy_Bold(2).ttf';
             imagettftext($im, 24, mt_rand(0, 20), 5, 60 + 6, $text_color, $font, $phrase);
             imagejpeg($im, null, 85);
             imagedestroy($im);
             exit;
             break;
         case 'captcha.check':
             $entered = DevblocksPlatform::importGPC($_REQUEST['captcha'], 'string', '');
             $captcha = $umsession->getProperty(UmScApp::SESSION_CAPTCHA, '');
             if (!empty($entered) && !empty($captcha) && 0 == strcasecmp($entered, $captcha)) {
                 echo 'true';
                 exit;
             }
             echo 'false';
             exit;
             break;
         default:
             // Build the menu
             $modules = $this->_getModules();
             $menu_modules = array();
             if (is_array($modules)) {
                 foreach ($modules as $uri => $module) {
                     // Must be menu renderable
                     if (!empty($module->manifest->params['menu_title']) && !empty($uri)) {
                         $menu_modules[$uri] = $module;
                     }
                 }
             }
             $tpl->assign('menu', $menu_modules);
             // Modules
             if (isset($modules[$module_uri])) {
                 $controller = $modules[$module_uri];
             } else {
                 // First menu item
                 $controller = reset($menu_modules);
             }
             array_unshift($stack, $module_uri);
             $tpl->assign('module', $controller);
             $tpl->assign('module_response', new DevblocksHttpResponse($stack));
             $tpl->display('devblocks:usermeet.core:support_center/index.tpl:portal_' . UmPortalHelper::getCode());
             break;
     }
 }
Exemplo n.º 3
0
 private function _handleImportWorker($xml)
 {
     $settings = CerberusSettings::getInstance();
     $logger = DevblocksPlatform::getConsoleLog();
     $sFirstName = (string) $xml->first_name;
     $sLastName = (string) $xml->last_name;
     $sEmail = (string) $xml->email;
     $sPassword = (string) $xml->password;
     $isSuperuser = (int) $xml->is_superuser;
     // Dupe check worker email
     if (null != ($worker_id = DAO_Worker::lookupAgentEmail($sEmail))) {
         $logger->info('[Importer] Avoiding creating duplicate worker #' . $worker_id . ' (' . $sEmail . ')');
         return true;
     }
     $worker_id = DAO_Worker::create($sEmail, CerberusApplication::generatePassword(8), $sFirstName, $sLastName, '');
     DAO_Worker::updateAgent($worker_id, array(DAO_Worker::PASSWORD => $sPassword, DAO_Worker::IS_SUPERUSER => intval($isSuperuser)));
     // Address to Worker
     DAO_AddressToWorker::assign($sEmail, $worker_id);
     DAO_AddressToWorker::update($sEmail, array(DAO_AddressToWorker::IS_CONFIRMED => 1));
     $logger->info('[Importer] Imported worker #' . $worker_id . ' (' . $sEmail . ')');
     DAO_Worker::clearCache();
     return true;
 }
Exemplo n.º 4
0
 function doRegisterAction()
 {
     @($email = DevblocksPlatform::importGPC($_REQUEST['email'], 'string', ''));
     $tpl = DevblocksPlatform::getTemplateService();
     $settings = CerberusSettings::getInstance();
     $from = $settings->get(CerberusSettings::DEFAULT_REPLY_FROM, null);
     $from_personal = $settings->get(CerberusSettings::DEFAULT_REPLY_PERSONAL, "Support Dept.");
     $url = DevblocksPlatform::getUrlService();
     $mail_service = DevblocksPlatform::getMailService();
     $mailer = $mail_service->getMailer(CerberusMail::getMailerDefaults());
     $code = CerberusApplication::generatePassword(8);
     if (!empty($email) && null != ($addy = DAO_Address::lookupAddress($email, true))) {
         // Already registered?
         if ($addy->is_registered) {
             $tpl->assign('register_error', sprintf("'%s' is already registered.", $email));
             DevblocksPlatform::setHttpResponse(new DevblocksHttpResponse(array('portal', UmPortalHelper::getCode(), 'register')));
             return;
         }
         $fields = array(DAO_Address::IS_REGISTERED => 0, DAO_Address::PASS => $code);
         DAO_Address::update($addy->id, $fields);
     } else {
         $tpl->assign('register_error', sprintf("'%s' is an invalid e-mail address.", $email));
         DevblocksPlatform::setHttpResponse(new DevblocksHttpResponse(array('portal', UmPortalHelper::getCode(), 'register')));
         return;
     }
     $message = $mail_service->createMessage();
     $message->setTo($email);
     $message->setFrom(array($from => $from_personal));
     $message->setSubject("Confirming your support e-mail address");
     $message->setBody(sprintf("This is a message to confirm your recent registration request at:\r\n" . "%s\r\n" . "\r\n" . "Your confirmation code is: %s\r\n" . "\r\n" . "If you've closed the browser window, you can continue by visiting:\r\n" . "%s\r\n" . "\r\n" . "Thanks!\r\n" . "%s\r\n", $url->write('', true), $code, $url->write('c=register&a=confirm', true), $from_personal));
     $headers = $message->getHeaders();
     $headers->addTextHeader('X-Mailer', 'Cerberus Helpdesk (Build ' . APP_BUILD . ')');
     $result = $mailer->send($message);
     DevblocksPlatform::setHttpResponse(new DevblocksHttpResponse(array('portal', UmPortalHelper::getCode(), 'register', 'confirm')));
 }
Exemplo n.º 5
0
 function doRecoverStep1Action()
 {
     $translate = DevblocksPlatform::getTranslationService();
     @($email = DevblocksPlatform::importGPC($_REQUEST['email'], 'string'));
     $worker = DAO_Worker::lookupAgentEmail($email);
     if (empty($email) || empty($worker)) {
         return;
     }
     $_SESSION[self::KEY_FORGOT_EMAIL] = $email;
     try {
         $mail_service = DevblocksPlatform::getMailService();
         $mailer = $mail_service->getMailer(CerberusMail::getMailerDefaults());
         $mail = $mail_service->createMessage();
         $code = CerberusApplication::generatePassword(10);
         $_SESSION[self::KEY_FORGOT_SENTCODE] = $code;
         $settings = CerberusSettings::getInstance();
         $from = $settings->get(CerberusSettings::DEFAULT_REPLY_FROM);
         $personal = $settings->get(CerberusSettings::DEFAULT_REPLY_PERSONAL);
         // Headers
         $mail->setTo(array($email));
         $mail->setFrom(array($from => $personal));
         $mail->setSubject($translate->_('signin.forgot.mail.subject'));
         $mail->generateId();
         $headers = $mail->getHeaders();
         $headers->addTextHeader('X-Mailer', 'Cerberus Helpdesk (Build ' . APP_BUILD . ')');
         $mail->setBody(vsprintf($translate->_('signin.forgot.mail.body'), $code));
         if (!$mailer->send($mail)) {
             throw new Exception('Password Forgot confirmation email failed to send.');
         }
     } catch (Exception $e) {
         DevblocksPlatform::redirect(new DevblocksHttpResponse(array('login', 'forgot', 'step1', 'failed')));
     }
     DevblocksPlatform::redirect(new DevblocksHttpResponse(array('login', 'forgot', 'step2')));
 }
Exemplo n.º 6
0
 private function _sendConfirmation($email, $link)
 {
     $settings = CerberusSettings::getInstance();
     $from = $settings->get(CerberusSettings::DEFAULT_REPLY_FROM);
     $from_personal = $settings->get(CerberusSettings::DEFAULT_REPLY_PERSONAL);
     $url = DevblocksPlatform::getUrlService();
     try {
         $mail_service = DevblocksPlatform::getMailService();
         $mailer = $mail_service->getMailer(CerberusMail::getMailerDefaults());
         $code = CerberusApplication::generatePassword(8);
         if (!empty($email) && null != ($addy = DAO_Address::lookupAddress($email, false))) {
             $fields = array(DAO_AddressAuth::CONFIRM => $code);
             DAO_AddressAuth::update($addy->id, $fields);
         } else {
             return;
         }
         $message = $mail_service->createMessage();
         $message->setTo($email);
         $send_from = new Swift_Address($from, $from_personal);
         $message->setFrom($send_from);
         $message->setSubject("Account Confirmation Code");
         $message->setBody(sprintf("Below is your confirmation code.  Please copy and paste it into the confirmation form at:\r\n" . "%s\r\n" . "\r\n" . "Your confirmation code is: %s\r\n" . "\r\n" . "Thanks!\r\n", $link, $code));
         $message->headers->set('X-Mailer', 'Cerberus Helpdesk (Build ' . APP_BUILD . ')');
         $mailer->send($message, $email, $send_from);
     } catch (Exception $e) {
         return;
     }
 }
Exemplo n.º 7
0
 private function _sendConfirmationEmail($to, $worker)
 {
     $translate = DevblocksPlatform::getTranslationService();
     $settings = DevblocksPlatform::getPluginSettingsService();
     $url_writer = DevblocksPlatform::getUrlService();
     $tpl = DevblocksPlatform::getTemplateService();
     // Tentatively assign the e-mail address to this worker
     DAO_AddressToWorker::assign($to, $worker->id);
     // Create a confirmation code and save it
     $code = CerberusApplication::generatePassword(20);
     DAO_AddressToWorker::update($to, array(DAO_AddressToWorker::CODE => $code, DAO_AddressToWorker::CODE_EXPIRE => time() + 24 * 60 * 60));
     // Email the confirmation code to the address
     // [TODO] This function can return false, and we need to do something different if it does.
     CerberusMail::quickSend($to, vsprintf($translate->_('prefs.address.confirm.mail.subject'), $settings->get('cerberusweb.core', CerberusSettings::HELPDESK_TITLE)), vsprintf($translate->_('prefs.address.confirm.mail.body'), array($worker->getName(), $url_writer->write('c=preferences&a=confirm_email&code=' . $code, true))));
     $output = array(vsprintf($translate->_('prefs.address.confirm.mail.subject'), $to));
     $tpl->assign('pref_success', $output);
 }
Exemplo n.º 8
0
 public function writeResponse(DevblocksHttpResponse $response)
 {
     $tpl = DevblocksPlatform::getTemplateService();
     $tpl->cache_lifetime = "0";
     $tpl->assign('path', dirname(__FILE__) . '/templates/');
     $umsession = $this->getSession();
     $stack = $response->path;
     $logo_url = DAO_CommunityToolProperty::get($this->getPortal(), self::PARAM_LOGO_URL, '');
     $tpl->assign('logo_url', $logo_url);
     $page_title = DAO_CommunityToolProperty::get($this->getPortal(), self::PARAM_PAGE_TITLE, 'Contact Us');
     $tpl->assign('page_title', $page_title);
     $captcha_enabled = DAO_CommunityToolProperty::get($this->getPortal(), self::PARAM_CAPTCHA_ENABLED, 1);
     $tpl->assign('captcha_enabled', $captcha_enabled);
     // Usermeet Session
     if (null == ($fingerprint = parent::getFingerprint())) {
         die("A problem occurred.");
     }
     $tpl->assign('fingerprint', $fingerprint);
     switch (array_shift($stack)) {
         case 'captcha':
             header('Cache-control: max-age=0', true);
             // 1 wk // , must-revalidate
             header('Expires: ' . gmdate('D, d M Y H:i:s', time() - 604800) . ' GMT');
             // 1 wk
             header('Content-type: image/jpeg');
             //header('Content-length: '. count($jpg));
             //		        // Get CAPTCHA secret passphrase
             $phrase = CerberusApplication::generatePassword(4);
             $umsession->setProperty(self::SESSION_CAPTCHA, $phrase);
             $im = @imagecreate(150, 80) or die("Cannot Initialize new GD image stream");
             $background_color = imagecolorallocate($im, 0, 0, 0);
             $text_color = imagecolorallocate($im, 255, 255, 255);
             //233, 14, 91
             $font = DEVBLOCKS_PATH . 'resources/font/ryanlerch_-_Tuffy_Bold(2).ttf';
             imagettftext($im, 24, mt_rand(0, 20), 5, 60 + 6, $text_color, $font, $phrase);
             //				$im = imagerotate($im, mt_rand(-20,20), $background_color);
             imagejpeg($im, null, 85);
             imagedestroy($im);
             exit;
             break;
         default:
         case 'write':
             $response = array_shift($stack);
             switch ($response) {
                 case 'confirm':
                     $tpl->assign('last_opened', $umsession->getProperty('support.write.last_opened', ''));
                     $tpl->display('file:' . dirname(__FILE__) . '/templates/portal/contact/write/confirm.tpl');
                     break;
                 default:
                 case 'step1':
                 case 'step2':
                 case 'step3':
                     $sFrom = $umsession->getProperty('support.write.last_from', '');
                     $sNature = $umsession->getProperty('support.write.last_nature', '');
                     $sContent = $umsession->getProperty('support.write.last_content', '');
                     $sError = $umsession->getProperty('support.write.last_error', '');
                     $tpl->assign('last_from', $sFrom);
                     $tpl->assign('last_nature', $sNature);
                     $tpl->assign('last_content', $sContent);
                     $tpl->assign('last_error', $sError);
                     $sDispatch = DAO_CommunityToolProperty::get($this->getPortal(), self::PARAM_DISPATCH, '');
                     $dispatch = !empty($sDispatch) ? unserialize($sDispatch) : array();
                     $tpl->assign('dispatch', $dispatch);
                     switch ($response) {
                         default:
                             $tpl->display('file:' . dirname(__FILE__) . '/templates/portal/contact/write/step1.tpl');
                             break;
                         case 'step2':
                             // Cache along with answers?
                             if (is_array($dispatch)) {
                                 foreach ($dispatch as $k => $v) {
                                     if (md5($k) == $sNature) {
                                         $umsession->setProperty('support.write.last_nature_string', $k);
                                         $tpl->assign('situation', $k);
                                         $tpl->assign('situation_params', $v);
                                         break;
                                     }
                                 }
                             }
                             $tpl->display('file:' . dirname(__FILE__) . '/templates/portal/contact/write/step2.tpl');
                             break;
                         case 'step3':
                             $tpl->display('file:' . dirname(__FILE__) . '/templates/portal/contact/write/step3.tpl');
                             break;
                     }
                     break;
             }
             break;
     }
 }
Exemplo n.º 9
0
 public function writeResponse(DevblocksHttpResponse $response)
 {
     $umsession = UmPortalHelper::getSession();
     $stack = $response->path;
     $tpl = DevblocksPlatform::getTemplateService();
     $tpl->cache_lifetime = "0";
     $tpl_path = dirname(dirname(__FILE__)) . '/templates/';
     $tpl->assign('tpl_path', $tpl_path);
     $logo_url = DAO_CommunityToolProperty::get(UmPortalHelper::getCode(), self::PARAM_LOGO_URL, '');
     $tpl->assign('logo_url', $logo_url);
     $page_title = DAO_CommunityToolProperty::get(UmPortalHelper::getCode(), self::PARAM_PAGE_TITLE, 'Support Center');
     $tpl->assign('page_title', $page_title);
     $style_css = DAO_CommunityToolProperty::get(UmPortalHelper::getCode(), self::PARAM_STYLE_CSS, '');
     $tpl->assign('style_css', $style_css);
     $footer_html = DAO_CommunityToolProperty::get(UmPortalHelper::getCode(), self::PARAM_FOOTER_HTML, '');
     $tpl->assign('footer_html', $footer_html);
     $allow_logins = DAO_CommunityToolProperty::get(UmPortalHelper::getCode(), self::PARAM_ALLOW_LOGINS, 0);
     $tpl->assign('allow_logins', $allow_logins);
     $enabled_modules = DevblocksPlatform::parseCsvString(DAO_CommunityToolProperty::get(UmPortalHelper::getCode(), self::PARAM_ENABLED_MODULES, ''));
     $tpl->assign('enabled_modules', $enabled_modules);
     @($active_user = $umsession->getProperty('sc_login', null));
     $tpl->assign('active_user', $active_user);
     // Usermeet Session
     if (null == ($fingerprint = UmPortalHelper::getFingerprint())) {
         die("A problem occurred.");
     }
     $tpl->assign('fingerprint', $fingerprint);
     $module_uri = array_shift($stack);
     switch ($module_uri) {
         case 'ajax':
             $controller = new UmScAjaxController(null);
             $controller->handleRequest(new DevblocksHttpRequest($stack));
             break;
         case 'rss':
             $controller = new UmScRssController(null);
             $controller->handleRequest(new DevblocksHttpRequest($stack));
             break;
         case 'captcha':
             header('Cache-control: max-age=0', true);
             // 1 wk // , must-revalidate
             header('Expires: ' . gmdate('D, d M Y H:i:s', time() - 604800) . ' GMT');
             // 1 wk
             header('Content-type: image/jpeg');
             // Get CAPTCHA secret passphrase
             $phrase = CerberusApplication::generatePassword(4);
             $umsession->setProperty(UmScApp::SESSION_CAPTCHA, $phrase);
             $im = @imagecreate(150, 70) or die("Cannot Initialize new GD image stream");
             $background_color = imagecolorallocate($im, 240, 240, 240);
             $text_color = imagecolorallocate($im, 40, 40, 40);
             //233, 14, 91
             $font = DEVBLOCKS_PATH . 'resources/font/ryanlerch_-_Tuffy_Bold(2).ttf';
             imagettftext($im, 24, mt_rand(0, 20), 5, 60 + 6, $text_color, $font, $phrase);
             imagejpeg($im, null, 85);
             imagedestroy($im);
             exit;
             break;
         default:
             // Build the menu
             $modules = $this->_getModules();
             $menu_modules = array();
             if (is_array($modules)) {
                 foreach ($modules as $uri => $module) {
                     // Must be menu renderable
                     if (!empty($module->manifest->params['menu_title']) && !empty($uri)) {
                         $menu_modules[$uri] = $module;
                     }
                 }
             }
             $tpl->assign('menu', $menu_modules);
             if (isset($modules[$module_uri])) {
                 $controller = $modules[$module_uri];
             } else {
                 // First menu item
                 $controller = reset($menu_modules);
             }
             array_unshift($stack, $module_uri);
             $tpl->assign('module', $controller);
             $tpl->assign('module_response', new DevblocksHttpResponse($stack));
             $tpl->display('file:' . $tpl_path . 'portal/sc/module/index.tpl');
             break;
     }
 }