Beispiel #1
0
 /**
  * Set the module
  *
  * @param string $module The module to load.
  */
 public function setModule($module)
 {
     // is this module allowed?
     if (!BackendAuthentication::isAllowedModule($module)) {
         // set correct headers
         SpoonHTTP::setHeadersByCode(403);
         // throw exception
         throw new BackendException('Module not allowed.');
     }
     // set property
     $this->module = $module;
 }
Beispiel #2
0
 /**
  * Get the widgets
  *
  * @return	void
  */
 private function getWidgets()
 {
     // get all active modules
     $modules = BackendModel::getModules(true);
     // loop all modules
     foreach ($modules as $module) {
         // you have sufficient rights?
         if (BackendAuthentication::isAllowedModule($module)) {
             // build pathName
             $pathName = BACKEND_MODULES_PATH . '/' . $module;
             // check if the folder exists
             if (SpoonDirectory::exists($pathName . '/widgets')) {
                 // get widgets
                 $widgets = (array) SpoonFile::getList($pathName . '/widgets', '/(.*)\\.php/i');
                 // loop through widgets
                 foreach ($widgets as $widget) {
                     // require the classes
                     require_once $pathName . '/widgets/' . $widget;
                     // init var
                     $widgetName = str_replace('.php', '', $widget);
                     // build classname
                     $className = 'Backend' . SpoonFilter::toCamelCase($module) . 'Widget' . SpoonFilter::toCamelCase($widgetName);
                     // validate if the class exists
                     if (!class_exists($className)) {
                         // throw exception
                         throw new BackendException('The widgetfile is present, but the classname should be: ' . $className . '.');
                     } else {
                         // add to array
                         $this->widgetInstances[] = array('module' => $module, 'widget' => $widgetName, 'className' => $className);
                         // create reflection class
                         $reflection = new ReflectionClass('Backend' . SpoonFilter::toCamelCase($module) . 'Widget' . SpoonFilter::toCamelCase($widgetName));
                         // get the offset
                         $offset = strpos($reflection->getDocComment(), '*', 7);
                         // get the first sentence
                         $description = substr($reflection->getDocComment(), 0, $offset);
                         // replacements
                         $description = str_replace('*', '', $description);
                         $description = trim(str_replace('/', '', $description));
                     }
                     // check if model file exists
                     if (SpoonFile::exists($pathName . '/engine/model.php')) {
                         // require model
                         require_once $pathName . '/engine/model.php';
                     }
                     // add to array
                     $this->widgets[] = array('label' => SpoonFilter::toCamelCase($widgetName), 'value' => $widgetName, 'description' => $description);
                 }
             }
         }
     }
 }
Beispiel #3
0
 /**
  * Set module
  *
  * @param string $value The module to use.
  */
 private function setModule($value)
 {
     // set property
     $this->module = (string) $value;
     // core is a module that contains general stuff, so it has to be allowed
     if ($this->module !== 'core') {
         // is this module allowed?
         if (!BackendAuthentication::isAllowedModule($this->module)) {
             // set correct headers
             SpoonHTTP::setHeadersByCode(403);
             // stop script execution
             exit;
         }
     }
     // create URL instance, the templatemodifiers need this object
     $URL = new BackendURL();
     // set the module
     $URL->setModule($this->module);
 }
Beispiel #4
0
 /**
  * Validate the forms
  */
 private function validateForm()
 {
     if ($this->frm->isSubmitted()) {
         $txtEmail = $this->frm->getField('backend_email');
         $txtPassword = $this->frm->getField('backend_password');
         // required fields
         if (!$txtEmail->isFilled() || !$txtPassword->isFilled()) {
             // add error
             $this->frm->addError('fields required');
             // show error
             $this->tpl->assign('hasError', true);
         }
         // invalid form-token?
         if ($this->frm->getToken() != $this->frm->getField('form_token')->getValue()) {
             // set a correct header, so bots understand they can't mess with us.
             if (!headers_sent()) {
                 header('400 Bad Request', true, 400);
             }
         }
         // all fields are ok?
         if ($txtEmail->isFilled() && $txtPassword->isFilled() && $this->frm->getToken() == $this->frm->getField('form_token')->getValue()) {
             // try to login the user
             if (!BackendAuthentication::loginUser($txtEmail->getValue(), $txtPassword->getValue())) {
                 // add error
                 $this->frm->addError('invalid login');
                 // store attempt in session
                 $current = SpoonSession::exists('backend_login_attempts') ? (int) SpoonSession::get('backend_login_attempts') : 0;
                 // increment and store
                 SpoonSession::set('backend_login_attempts', ++$current);
                 // show error
                 $this->tpl->assign('hasError', true);
             }
         }
         // check sessions
         if (SpoonSession::exists('backend_login_attempts') && (int) SpoonSession::get('backend_login_attempts') >= 5) {
             // get previous attempt
             $previousAttempt = SpoonSession::exists('backend_last_attempt') ? SpoonSession::get('backend_last_attempt') : time();
             // calculate timeout
             $timeout = 5 * (SpoonSession::get('backend_login_attempts') - 4);
             // too soon!
             if (time() < $previousAttempt + $timeout) {
                 // sleep untill the user can login again
                 sleep($timeout);
                 // set a correct header, so bots understand they can't mess with us.
                 if (!headers_sent()) {
                     header('503 Service Unavailable', true, 503);
                 }
             } else {
                 // increment and store
                 SpoonSession::set('backend_last_attempt', time());
             }
             // too many attempts
             $this->frm->addEditor('too many attempts');
             // show error
             $this->tpl->assign('hasTooManyAttemps', true);
             $this->tpl->assign('hasError', false);
         }
         // no errors in the form?
         if ($this->frm->isCorrect()) {
             // cleanup sessions
             SpoonSession::delete('backend_login_attempts');
             SpoonSession::delete('backend_last_attempt');
             // create filter with modules which may not be displayed
             $filter = array('authentication', 'error', 'core');
             // get all modules
             $modules = array_diff(BackendModel::getModules(), $filter);
             // loop through modules and break on first allowed module
             foreach ($modules as $module) {
                 if (BackendAuthentication::isAllowedModule($module)) {
                     break;
                 }
             }
             // redirect to the correct URL (URL the user was looking for or fallback)
             $this->redirect($this->getParameter('querystring', 'string', BackendModel::createUrlForAction(null, $module)));
         }
     }
     // is the form submitted
     if ($this->frmForgotPassword->isSubmitted()) {
         // backend email
         $email = $this->frmForgotPassword->getField('backend_email_forgot')->getValue();
         // required fields
         if ($this->frmForgotPassword->getField('backend_email_forgot')->isEmail(BL::err('EmailIsInvalid'))) {
             // check if there is a user with the given emailaddress
             if (!BackendUsersModel::existsEmail($email)) {
                 $this->frmForgotPassword->getField('backend_email_forgot')->addError(BL::err('EmailIsUnknown'));
             }
         }
         // no errors in the form?
         if ($this->frmForgotPassword->isCorrect()) {
             // generate the key for the reset link and fetch the user ID for this email
             $key = BackendAuthentication::getEncryptedString($email, uniqid());
             // insert the key and the timestamp into the user settings
             $userId = BackendUsersModel::getIdByEmail($email);
             $user = new BackendUser($userId);
             $user->setSetting('reset_password_key', $key);
             $user->setSetting('reset_password_timestamp', time());
             // variables to parse in the e-mail
             $variables['resetLink'] = SITE_URL . BackendModel::createURLForAction('reset_password') . '&email=' . $email . '&key=' . $key;
             // send e-mail to user
             BackendMailer::addEmail(SpoonFilter::ucfirst(BL::msg('ResetYourPasswordMailSubject')), BACKEND_MODULE_PATH . '/layout/templates/mails/reset_password.tpl', $variables, $email);
             // clear post-values
             $_POST['backend_email_forgot'] = '';
             // show success message
             $this->tpl->assign('isForgotPasswordSuccess', true);
             // show form
             $this->tpl->assign('showForm', true);
         } else {
             $this->tpl->assign('showForm', true);
         }
     }
 }
Beispiel #5
0
 /**
  * Set module
  *
  * @return	void
  * @param	string $value	The module to use.
  */
 public function setModule($value)
 {
     // set property
     $this->module = (string) $value;
     // is this module allowed?
     if (!BackendAuthentication::isAllowedModule($this->module)) {
         // set correct headers
         SpoonHTTP::setHeadersByCode(403);
         // output
         $fakeAction = new BackendBaseAJAXAction('', '');
         $fakeAction->output(BackendBaseAJAXAction::FORBIDDEN, null, 'Module not allowed.');
     }
     // create URL instance, the templatemodifiers need this object
     $URL = new BackendURL();
     // set the module
     $URL->setModule($this->module);
 }
Beispiel #6
0
 /**
  * Clean the navigation
  *
  * @return	array
  * @param	array $navigation	The navigation array.
  */
 private function cleanup(array $navigation)
 {
     // loop elements
     foreach ($navigation as $key => $value) {
         // init var
         $allowedChildren = array();
         // error?
         $allowed = true;
         // get rid of invalid items
         if (!isset($value['url']) || !isset($value['label'])) {
             $allowed = false;
         }
         // split up chunks
         list($module, $action) = explode('/', $value['url']);
         // no rights for this module?
         if (!BackendAuthentication::isAllowedModule($module)) {
             $allowed = false;
         }
         // no rights for this action?
         if (!BackendAuthentication::isAllowedAction($action, $module)) {
             $allowed = false;
         }
         // has children
         if (isset($value['children']) && is_array($value['children']) && !empty($value['children'])) {
             // loop children
             foreach ($value['children'] as $keyB => $valueB) {
                 // error?
                 $allowed = true;
                 // init var
                 $allowedChildrenB = array();
                 // get rid of invalid items
                 if (!isset($valueB['url']) || !isset($valueB['label'])) {
                     $allowed = false;
                 }
                 // split up chunks
                 list($module, $action) = explode('/', $valueB['url']);
                 // no rights for this module?
                 if (!BackendAuthentication::isAllowedModule($module)) {
                     $allowed = false;
                 }
                 // no rights for this action?
                 if (!BackendAuthentication::isAllowedAction($action, $module)) {
                     $allowed = false;
                 }
                 // has children
                 if (isset($valueB['children']) && is_array($valueB['children']) && !empty($valueB['children'])) {
                     // loop children
                     foreach ($valueB['children'] as $keyC => $valueC) {
                         // error?
                         $allowed = true;
                         // get rid of invalid items
                         if (!isset($valueC['url']) || !isset($valueC['label'])) {
                             $allowed = false;
                         }
                         // split up chunks
                         list($module, $action) = explode('/', $valueC['url']);
                         // no rights for this module?
                         if (!BackendAuthentication::isAllowedModule($module)) {
                             $allowed = false;
                         }
                         // no rights for this action?
                         if (!BackendAuthentication::isAllowedAction($action, $module)) {
                             $allowed = false;
                         }
                         // error occured
                         if (!$allowed) {
                             unset($navigation[$key]['children'][$keyB]['children'][$keyC]);
                             continue;
                         } elseif (!in_array($navigation[$key]['children'][$keyB]['children'][$keyC], $allowedChildrenB)) {
                             $allowedChildrenB[] = $navigation[$key]['children'][$keyB]['children'][$keyC];
                         }
                     }
                 }
                 // error occured and no allowed children on level B
                 if (!$allowed && empty($allowedChildrenB)) {
                     unset($navigation[$key]['children'][$keyB]);
                     continue;
                 } elseif (!in_array($navigation[$key]['children'][$keyB], $allowedChildren)) {
                     $allowedChildren[] = $navigation[$key]['children'][$keyB];
                 }
                 // assign new base url for level B
                 if (!empty($allowedChildrenB)) {
                     $navigation[$key]['children'][$keyB]['url'] = $allowedChildrenB[0]['url'];
                 }
             }
         }
         // error occured and no allowed children
         if (!$allowed && empty($allowedChildren)) {
             unset($navigation[$key]);
             continue;
         } elseif (!empty($allowedChildren)) {
             // init var
             $allowed = true;
             // split up chunks
             list($module, $action) = explode('/', $allowedChildren[0]['url']);
             // no rights for this module?
             if (!BackendAuthentication::isAllowedModule($module)) {
                 $allowed = false;
             }
             // no rights for this action?
             if (!BackendAuthentication::isAllowedAction($action, $module)) {
                 $allowed = false;
             }
             // allowed? assign base URL
             if ($allowed) {
                 $navigation[$key]['url'] = $allowedChildren[0]['url'];
             } else {
                 // get first child
                 $child = reset($navigation[$key]['children']);
                 // assign base URL
                 $navigation[$key]['url'] = $child['url'];
             }
         }
     }
     return $navigation;
 }
Beispiel #7
0
 /**
  * Process the querystring
  *
  * @return	void
  */
 private function processQueryString()
 {
     // store the querystring local, so we don't alter it.
     $queryString = $this->getQueryString();
     // find the position of ? (which seperates real URL and GET-parameters)
     $positionQuestionMark = strpos($queryString, '?');
     // remove the GET-chunk from the parameters
     $processedQueryString = $positionQuestionMark === false ? $queryString : substr($queryString, 0, $positionQuestionMark);
     // split into chunks, a Backend URL will always look like /<lang>/<module>/<action>(?GET)
     $chunks = (array) explode('/', trim($processedQueryString, '/'));
     // check if this is a request for a JS-file
     $isJS = isset($chunks[1]) && $chunks[1] == 'js.php';
     // check if this is a request for a AJAX-file
     $isAJAX = isset($chunks[1]) && $chunks[1] == 'ajax.php';
     // get the language, this will always be in front
     $language = isset($chunks[1]) && $chunks[1] != '' ? SpoonFilter::getValue($chunks[1], array_keys(BackendLanguage::getWorkingLanguages()), '') : '';
     // no language provided?
     if ($language == '' && !$isJS && !$isAJAX) {
         // remove first element
         array_shift($chunks);
         // redirect to login
         SpoonHTTP::redirect('/' . NAMED_APPLICATION . '/' . SITE_DEFAULT_LANGUAGE . '/' . implode('/', $chunks));
     }
     // get the module, null will be the default
     $module = isset($chunks[2]) && $chunks[2] != '' ? $chunks[2] : 'dashboard';
     // get the requested action, if it is passed
     if (isset($chunks[3]) && $chunks[3] != '') {
         $action = $chunks[3];
     } elseif (!$isJS && !$isAJAX) {
         // build path to the module and define it. This is a constant because we can use this in templates.
         if (!defined('BACKEND_MODULE_PATH')) {
             define('BACKEND_MODULE_PATH', BACKEND_MODULES_PATH . '/' . $module);
         }
         // check if the config is present? If it isn't present there is a huge problem, so we will stop our code by throwing an error
         if (!SpoonFile::exists(BACKEND_MODULE_PATH . '/config.php')) {
             throw new BackendException('The configfile for the module (' . $module . ') can\'t be found.');
         }
         // build config-object-name
         $configClassName = 'Backend' . SpoonFilter::toCamelCase($module . '_config');
         // require the config file, we validated before for existence.
         require_once BACKEND_MODULE_PATH . '/config.php';
         // validate if class exists (aka has correct name)
         if (!class_exists($configClassName)) {
             throw new BackendException('The config file is present, but the classname should be: ' . $configClassName . '.');
         }
         // create config-object, the constructor will do some magic
         $config = new $configClassName($module);
         // set action
         $action = $config->getDefaultAction() !== null ? $config->getDefaultAction() : 'index';
     }
     // if it is an request for a JS-file or an AJAX-file we only need the module
     if ($isJS || $isAJAX) {
         // set the working language, this is not the interface language
         BackendLanguage::setWorkingLanguage(SpoonFilter::getGetValue('language', null, SITE_DEFAULT_LANGUAGE));
         // set current module
         $this->setModule(SpoonFilter::getGetValue('module', null, null));
         // set action
         $this->setAction('index');
     } else {
         // the person isn't logged in? or the module doesn't require authentication
         if (!BackendAuthentication::isLoggedIn() && !BackendAuthentication::isAllowedModule($module)) {
             // redirect to login
             SpoonHTTP::redirect('/' . NAMED_APPLICATION . '/' . $language . '/authentication/?querystring=' . urlencode('/' . $this->getQueryString()));
         } else {
             // does our user has access to this module?
             if (!BackendAuthentication::isAllowedModule($module)) {
                 // the user doesn't have access, redirect to error page
                 SpoonHTTP::redirect('/' . NAMED_APPLICATION . '/' . $language . '/error?type=module-not-allowed&querystring=' . urlencode('/' . $this->getQueryString()));
             } else {
                 // can our user execute the requested action?
                 if (!BackendAuthentication::isAllowedAction($action, $module)) {
                     // the user hasn't access, redirect to error page
                     SpoonHTTP::redirect('/' . NAMED_APPLICATION . '/' . $language . '/error?type=action-not-allowed&querystring=' . urlencode('/' . $this->getQueryString()));
                 } else {
                     // set the working language, this is not the interface language
                     BackendLanguage::setWorkingLanguage($language);
                     // is the user authenticated
                     if (BackendAuthentication::getUser()->isAuthenticated()) {
                         // set interface language based on the user preferences
                         BackendLanguage::setLocale(BackendAuthentication::getUser()->getSetting('interface_language', 'nl'));
                     } else {
                         // init var
                         $interfaceLanguage = BackendModel::getModuleSetting('core', 'default_interface_language');
                         // override with cookie value if that exists
                         if (SpoonCookie::exists('interface_language') && in_array(SpoonCookie::get('interface_language'), array_keys(BackendLanguage::getInterfaceLanguages()))) {
                             // set interface language based on the perons' cookies
                             $interfaceLanguage = SpoonCookie::get('interface_language');
                         }
                         // set interface language
                         BackendLanguage::setLocale($interfaceLanguage);
                     }
                     // set current module
                     $this->setModule($module);
                     $this->setAction($action);
                 }
             }
         }
     }
 }
Beispiel #8
0
 /**
  * Process a regular request
  *
  * @param string $module The requested module.
  * @param string $action The requested action.
  * @param strring $language The requested language.
  */
 private function processRegularRequest($module, $action, $language)
 {
     // the person isn't logged in? or the module doesn't require authentication
     if (!BackendAuthentication::isLoggedIn() && !BackendAuthentication::isAllowedModule($module)) {
         // redirect to login
         SpoonHTTP::redirect('/' . NAMED_APPLICATION . '/' . $language . '/authentication/?querystring=' . urlencode('/' . $this->getQueryString()));
     } else {
         // does our user has access to this module?
         if (!BackendAuthentication::isAllowedModule($module)) {
             // if the module is the dashboard redirect to the first allowed module
             if ($module == 'dashboard') {
                 // require navigation-file
                 require_once BACKEND_CACHE_PATH . '/navigation/navigation.php';
                 // loop the navigation to find the first allowed module
                 foreach ($navigation as $key => $value) {
                     // split up chunks
                     list($module, $action) = explode('/', $value['url']);
                     // user allowed?
                     if (BackendAuthentication::isAllowedModule($module)) {
                         // redirect to the page
                         SpoonHTTP::redirect('/' . NAMED_APPLICATION . '/' . $language . '/' . $value['url']);
                     }
                 }
             }
             // the user doesn't have access, redirect to error page
             SpoonHTTP::redirect('/' . NAMED_APPLICATION . '/' . $language . '/error?type=module-not-allowed&querystring=' . urlencode('/' . $this->getQueryString()));
         } else {
             // can our user execute the requested action?
             if (!BackendAuthentication::isAllowedAction($action, $module)) {
                 // the user hasn't access, redirect to error page
                 SpoonHTTP::redirect('/' . NAMED_APPLICATION . '/' . $language . '/error?type=action-not-allowed&querystring=' . urlencode('/' . $this->getQueryString()));
             } else {
                 // set the working language, this is not the interface language
                 BackendLanguage::setWorkingLanguage($language);
                 $this->setLocale();
                 $this->setModule($module);
                 $this->setAction($action);
             }
         }
     }
 }
Beispiel #9
0
 /**
  * Load the data
  */
 private function loadData()
 {
     // get all modules
     $modules = BackendModel::getModules();
     // get user sequence
     $userSequence = BackendAuthentication::getUser()->getSetting('dashboard_sequence');
     // user sequence does not exist?
     if (!isset($userSequence)) {
         // get group ID of user
         $groupId = BackendAuthentication::getUser()->getGroupId();
         // get group preset
         $userSequence = BackendGroupsModel::getSetting($groupId, 'dashboard_sequence');
     }
     // loop all modules
     foreach ($modules as $module) {
         // you have sufficient rights?
         if (BackendAuthentication::isAllowedModule($module)) {
             // build pathName
             $pathName = BACKEND_MODULES_PATH . '/' . $module;
             // check if the folder exists
             if (SpoonDirectory::exists($pathName . '/widgets')) {
                 // get widgets
                 $widgets = (array) SpoonFile::getList($pathName . '/widgets', '/(.*)\\.php/i');
                 // loop widgets
                 foreach ($widgets as $widget) {
                     // require the class
                     require_once $pathName . '/widgets/' . $widget;
                     // init var
                     $widgetName = str_replace('.php', '', $widget);
                     // build classname
                     $className = 'Backend' . SpoonFilter::toCamelCase($module) . 'Widget' . SpoonFilter::toCamelCase($widgetName);
                     // validate if the class exists
                     if (!class_exists($className)) {
                         throw new BackendException('The widgetfile is present, but the classname should be: ' . $className . '.');
                     }
                     // check if model file exists
                     if (SpoonFile::exists($pathName . '/engine/model.php')) {
                         // require model
                         require_once $pathName . '/engine/model.php';
                     }
                     // present?
                     $present = isset($userSequence[$module][$widgetName]['present']) ? $userSequence[$module][$widgetName]['present'] : false;
                     // if not present, continue
                     if (!$present) {
                         continue;
                     }
                     // create instance
                     $instance = new $className();
                     // has rights
                     if (!$instance->isAllowed()) {
                         continue;
                     }
                     // hidden?
                     $hidden = isset($userSequence[$module][$widgetName]['hidden']) ? $userSequence[$module][$widgetName]['hidden'] : false;
                     // execute instance if it is not hidden
                     if (!$hidden) {
                         $instance->execute();
                     }
                     // user sequence provided?
                     $column = isset($userSequence[$module][$widgetName]['column']) ? $userSequence[$module][$widgetName]['column'] : $instance->getColumn();
                     $position = isset($userSequence[$module][$widgetName]['position']) ? $userSequence[$module][$widgetName]['position'] : $instance->getPosition();
                     $title = SpoonFilter::ucfirst(BL::lbl(SpoonFilter::toCamelCase($module))) . ': ' . BL::lbl(SpoonFilter::toCamelCase($widgetName));
                     $templatePath = $instance->getTemplatePath();
                     // reset template path
                     if ($templatePath == null) {
                         $templatePath = BACKEND_PATH . '/modules/' . $module . '/layout/widgets/' . $widgetName . '.tpl';
                     }
                     // build item
                     $item = array('template' => $templatePath, 'module' => $module, 'widget' => $widgetName, 'title' => $title, 'hidden' => $hidden);
                     // add on new position if no position is set or if the position is already used
                     if ($position === null || isset($this->widgets[$column][$position])) {
                         $this->widgets[$column][] = $item;
                     } else {
                         $this->widgets[$column][$position] = $item;
                     }
                 }
             }
         }
     }
     // sort the widgets
     foreach ($this->widgets as &$column) {
         ksort($column);
     }
 }