Ejemplo n.º 1
0
 /**
  * Execute the action
  */
 public function execute()
 {
     // get parameters
     $this->id = $this->getParameter('id', 'int');
     // does the user exist
     if ($this->id !== null && BackendUsersModel::exists($this->id) && BackendAuthentication::getUser()->getUserId() != $this->id) {
         parent::execute();
         // get data
         $user = new BackendUser($this->id);
         // God-users can't be deleted
         if ($user->isGod()) {
             $this->redirect(BackendModel::createURLForAction('Index') . '&error=cant-delete-god');
         }
         // delete item
         BackendUsersModel::delete($this->id);
         // trigger event
         BackendModel::triggerEvent($this->getModule(), 'after_delete', array('id' => $this->id));
         // item was deleted, so redirect
         $this->redirect(BackendModel::createURLForAction('Index') . '&report=deleted&var=' . $user->getSetting('nickname'));
     } else {
         $this->redirect(BackendModel::createURLForAction('Index') . '&error=non-existing');
     }
 }
Ejemplo n.º 2
0
 /**
  * Execute the action
  */
 public function execute()
 {
     $email = $this->getParameter('email', 'string');
     // does the user exist
     if ($email !== null) {
         parent::execute();
         // delete item
         if (BackendUsersModel::undoDelete($email)) {
             // get user
             $user = new BackendUser(null, $email);
             // trigger event
             $item = array('id' => $user->getUserId(), 'email' => $email);
             BackendModel::triggerEvent($this->getModule(), 'after_undelete', array('item' => $item));
             // item was deleted, so redirect
             $this->redirect(BackendModel::createURLForAction('edit') . '&id=' . $user->getUserId() . '&report=restored&var=' . $user->getSetting('nickname') . '&highlight=row-' . $user->getUserId());
         } else {
             // invalid user
             $this->redirect(BackendModel::createURLForAction('index') . '&error=non-existing');
         }
     } else {
         $this->redirect(BackendModel::createURLForAction('index') . '&error=non-existing');
     }
 }
Ejemplo n.º 3
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);
         }
         $this->getContainer()->get('logger')->info("Trying to authenticate user '{$txtEmail->getValue()}'.");
         // 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);
             }
         }
         // get the user's id
         $userId = BackendUsersModel::getIdByEmail($txtEmail->getValue());
         // 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())) {
                 $this->getContainer()->get('logger')->info("Failed authenticating user '{$txtEmail->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);
                 // save the failed login attempt in the user's settings
                 if ($userId !== false) {
                     BackendUsersModel::setSetting($userId, 'last_failed_login_attempt', time());
                 }
                 // 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 until 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');
             $this->getContainer()->get('logger')->info("Too many login attempts for user '{$txtEmail->getValue()}'.");
             // 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');
             // save the login timestamp in the user's settings
             $lastLogin = BackendUsersModel::getSetting($userId, 'current_login');
             BackendUsersModel::setSetting($userId, 'current_login', time());
             if ($lastLogin) {
                 BackendUsersModel::setSetting($userId, 'last_login', $lastLogin);
             }
             $this->getContainer()->get('logger')->info("Successfully authenticated user '{$txtEmail->getValue()}'.");
             // redirect to the correct URL (URL the user was looking for or fallback)
             $this->redirectToAllowedModuleAndAction();
         }
     }
     // 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 User($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('ResetPassword') . '&email=' . $email . '&key=' . $key;
             // send e-mail to user
             $from = $this->get('fork.settings')->get('Core', 'mailer_from');
             $replyTo = $this->get('fork.settings')->get('Core', 'mailer_reply_to');
             $message = \Common\Mailer\Message::newInstance(\SpoonFilter::ucfirst(BL::msg('ResetYourPasswordMailSubject')))->setFrom(array($from['email'] => $from['name']))->setTo(array($email))->setReplyTo(array($replyTo['email'] => $replyTo['name']))->parseHtml(BACKEND_MODULES_PATH . '/Authentication/Layout/Templates/Mails/ResetPassword.tpl', $variables);
             $this->get('mailer')->send($message);
             // clear post-values
             $_POST['backend_email_forgot'] = '';
             // show success message
             $this->tpl->assign('isForgotPasswordSuccess', true);
             // show form
             $this->tpl->assign('showForm', true);
         } else {
             // errors?
             $this->tpl->assign('showForm', true);
         }
     }
 }
Ejemplo n.º 4
0
 /**
  * Remove a device from a user.
  *
  * @param string $uri   The uri of the channel opened for the device.
  * @param string $email The emailaddress for the user to link the device to.
  */
 public static function microsoftRemoveDevice($uri, $email)
 {
     if (BaseAPI::isAuthorized()) {
         // redefine
         $uri = (string) $uri;
         // validate
         if ($uri == '') {
             BaseAPI::output(BaseAPI::BAD_REQUEST, array('message' => 'No uri-parameter provided.'));
         }
         if ($email == '') {
             BaseAPI::output(BaseAPI::BAD_REQUEST, array('message' => 'No email-parameter provided.'));
         }
         try {
             // load user
             $user = new User(null, $email);
             // get current uris
             $uris = (array) $user->getSetting('microsoft_channel_uri');
             // not already in array?
             $index = array_search($uri, $uris);
             if ($index !== false) {
                 // remove from array
                 unset($uris[$index]);
                 // save it
                 $user->setSetting('microsoft_channel_uri', $uris);
             }
         } catch (Exception $e) {
             BaseAPI::output(BaseAPI::FORBIDDEN, array('message' => 'Can\'t authenticate you.'));
         }
     }
 }
Ejemplo n.º 5
0
 /**
  * Returns the encrypted password for a user by giving a email/password
  * Returns false if no user was found for this user/pass combination
  *
  * @param string $email    The email.
  * @param string $password The password.
  *
  * @return string
  */
 public static function getEncryptedPassword($email, $password)
 {
     $email = (string) $email;
     $password = (string) $password;
     // fetch user ID by email
     $userId = BackendUsersModel::getIdByEmail($email);
     // check if a user ID was found, return false if no user exists
     if ($userId === false) {
         return false;
     }
     // fetch user record
     $user = new User($userId);
     $key = $user->getSetting('password_key');
     // return the encrypted string
     return (string) self::getEncryptedString($password, $key);
 }
Ejemplo n.º 6
0
 /**
  * Default authentication
  *
  * @return bool
  */
 public static function isAuthorized()
 {
     // grab data
     $email = \SpoonFilter::getGetValue('email', null, '');
     $nonce = \SpoonFilter::getGetValue('nonce', null, '');
     $secret = \SpoonFilter::getGetValue('secret', null, '');
     // data can be available in the POST, so check it
     if ($email == '') {
         $email = \SpoonFilter::getPostValue('email', null, '');
     }
     if ($nonce == '') {
         $nonce = \SpoonFilter::getPostValue('nonce', null, '');
     }
     if ($secret == '') {
         $secret = \SpoonFilter::getPostValue('secret', null, '');
     }
     // check if needed elements are available
     if ($email === '' || $nonce === '' || $secret === '') {
         return self::output(self::NOT_AUTHORIZED, array('message' => 'Not authorized.'));
     }
     // get the user
     try {
         $user = new BackendUser(null, $email);
     } catch (\Exception $e) {
         return self::output(self::FORBIDDEN, array('message' => 'This account does not exist.'));
     }
     // get settings
     $apiAccess = $user->getSetting('api_access', false);
     $apiKey = $user->getSetting('api_key');
     // no API-access
     if (!$apiAccess) {
         return self::output(self::FORBIDDEN, array('message' => 'Your account isn\'t allowed to use the API. Contact an administrator.'));
     }
     // create hash
     $hash = BackendAuthentication::getEncryptedString($email . $apiKey, $nonce);
     // output
     if ($secret != $hash) {
         return self::output(self::FORBIDDEN, array('message' => 'Invalid secret.'));
     }
     // return
     return true;
 }
Ejemplo n.º 7
0
 /**
  * Get the HTML for a user to use in a datagrid
  *
  * @param int $id The Id of the user.
  * @return string
  */
 public static function getUser($id)
 {
     $id = (int) $id;
     // nothing in cache
     if (!isset(self::$dataGridUsers[$id])) {
         // create user instance
         $user = new User($id);
         // get settings
         $avatar = $user->getSetting('avatar', 'no-avatar.gif');
         $nickname = $user->getSetting('nickname');
         $allowed = Authentication::isAllowedAction('Edit', 'Users');
         // build html
         $html = '<div class="dataGridAvatar">' . "\n";
         $html .= '  <div class="avatar av24">' . "\n";
         if ($allowed) {
             $html .= '     <a href="' . BackendModel::createURLForAction('Edit', 'Users') . '&amp;id=' . $id . '">' . "\n";
         }
         $html .= '          <img src="' . FRONTEND_FILES_URL . '/backend_users/avatars/32x32/' . $avatar . '" width="24" height="24" alt="' . $nickname . '" />' . "\n";
         if ($allowed) {
             $html .= '     </a>' . "\n";
         }
         $html .= '  </div>';
         $html .= '  <p><a href="' . BackendModel::createURLForAction('edit', 'users') . '&amp;id=' . $id . '">' . $nickname . '</a></p>' . "\n";
         $html .= '</div>';
         self::$dataGridUsers[$id] = $html;
     }
     return self::$dataGridUsers[$id];
 }
Ejemplo n.º 8
0
 /**
  * Validate the form
  */
 private function validateForm()
 {
     // is the form submitted?
     if ($this->frm->isSubmitted()) {
         // cleanup the submitted fields, ignore fields that were added by hackers
         $this->frm->cleanupFields();
         $fields = $this->frm->getFields();
         // email is present
         if (!$this->user->isGod()) {
             if ($fields['email']->isFilled(BL::err('EmailIsRequired'))) {
                 // is this an email-address
                 if ($fields['email']->isEmail(BL::err('EmailIsInvalid'))) {
                     // was this emailaddress deleted before
                     if (BackendUsersModel::emailDeletedBefore($fields['email']->getValue())) {
                         $fields['email']->addError(sprintf(BL::err('EmailWasDeletedBefore'), BackendModel::createURLForAction('UndoDelete', null, null, array('email' => $fields['email']->getValue()))));
                     } elseif (BackendUsersModel::existsEmail($fields['email']->getValue(), $this->id)) {
                         // email already exists
                         $fields['email']->addError(BL::err('EmailAlreadyExists'));
                     }
                 }
             }
         }
         // required fields
         if ($this->user->isGod() && $fields['email']->getValue() != '' && $this->user->getEmail() != $fields['email']->getValue()) {
             $fields['email']->addError(BL::err('CantChangeGodsEmail'));
         }
         if (!$this->user->isGod()) {
             $fields['email']->isEmail(BL::err('EmailIsInvalid'));
         }
         $fields['nickname']->isFilled(BL::err('NicknameIsRequired'));
         $fields['name']->isFilled(BL::err('NameIsRequired'));
         $fields['surname']->isFilled(BL::err('SurnameIsRequired'));
         $fields['interface_language']->isFilled(BL::err('FieldIsRequired'));
         $fields['date_format']->isFilled(BL::err('FieldIsRequired'));
         $fields['time_format']->isFilled(BL::err('FieldIsRequired'));
         $fields['number_format']->isFilled(BL::err('FieldIsRequired'));
         if ($this->allowUserRights) {
             $fields['groups']->isFilled(BL::err('FieldIsRequired'));
         }
         if (isset($fields['new_password']) && $fields['new_password']->isFilled()) {
             if ($fields['new_password']->getValue() !== $fields['confirm_password']->getValue()) {
                 $fields['confirm_password']->addError(BL::err('ValuesDontMatch'));
             }
         }
         // validate avatar
         if ($fields['avatar']->isFilled()) {
             // correct extension
             if ($fields['avatar']->isAllowedExtension(array('jpg', 'jpeg', 'gif', 'png'), BL::err('JPGGIFAndPNGOnly'))) {
                 // correct mimetype?
                 $fields['avatar']->isAllowedMimeType(array('image/gif', 'image/jpg', 'image/jpeg', 'image/png'), BL::err('JPGGIFAndPNGOnly'));
             }
         }
         // no errors?
         if ($this->frm->isCorrect()) {
             // build user-array
             $user['id'] = $this->id;
             if (!$this->user->isGod()) {
                 $user['email'] = $fields['email']->getValue(true);
             }
             if ($this->authenticatedUser->getUserId() != $this->record['id']) {
                 $user['active'] = $fields['active']->isChecked() ? 'Y' : 'N';
             }
             // user is now de-activated, we now remove all sessions for this user so he is logged out immediately
             if (isset($user['active']) && $user['active'] === 'N' && $this->record['active'] !== $user['active']) {
                 // delete all sessions for user
                 BackendModel::get('database')->delete('users_sessions', 'user_id = ?', array($this->user->getUserId()));
             }
             // build settings-array
             $settings['nickname'] = $fields['nickname']->getValue();
             $settings['name'] = $fields['name']->getValue();
             $settings['surname'] = $fields['surname']->getValue();
             $settings['interface_language'] = $fields['interface_language']->getValue();
             $settings['date_format'] = $fields['date_format']->getValue();
             $settings['time_format'] = $fields['time_format']->getValue();
             $settings['datetime_format'] = $settings['date_format'] . ' ' . $settings['time_format'];
             $settings['number_format'] = $fields['number_format']->getValue();
             $settings['csv_split_character'] = $fields['csv_split_character']->getValue();
             $settings['csv_line_ending'] = $fields['csv_line_ending']->getValue();
             $settings['api_access'] = $this->allowUserRights ? (bool) $fields['api_access']->getChecked() : $this->record['settings']['api_access'];
             // update password (only if filled in)
             if (isset($fields['new_password']) && $fields['new_password']->isFilled()) {
                 $user['password'] = BackendAuthentication::getEncryptedString($fields['new_password']->getValue(), $this->record['settings']['password_key']);
                 // the password has changed
                 if ($this->record['password'] != $user['password']) {
                     // save the login timestamp in the user's settings
                     $lastPasswordChange = BackendUsersModel::getSetting($user['id'], 'current_password_change');
                     $settings['current_password_change'] = time();
                     if ($lastPasswordChange) {
                         $settings['last_password_change'] = $lastPasswordChange;
                     }
                     // save the password strength
                     $passwordStrength = BackendAuthentication::checkPassword($fields['new_password']->getValue());
                     $settings['password_strength'] = $passwordStrength;
                 }
             }
             // get user groups when allowed to edit
             if ($this->allowUserRights) {
                 // get selected groups
                 $groups = $fields['groups']->getChecked();
                 // init var
                 $newSequence = BackendGroupsModel::getSetting($groups[0], 'dashboard_sequence');
                 // loop through groups and collect all dashboard widget sequences
                 foreach ($groups as $group) {
                     $sequences[] = BackendGroupsModel::getSetting($group, 'dashboard_sequence');
                 }
                 // loop through sequences
                 foreach ($sequences as $sequence) {
                     // loop through modules inside a sequence
                     foreach ($sequence as $moduleKey => $module) {
                         // loop through widgets inside a module
                         foreach ($module as $widgetKey => $widget) {
                             // if widget present set true
                             if ($widget['present']) {
                                 $newSequence[$moduleKey][$widgetKey]['present'] = true;
                             }
                         }
                     }
                 }
                 // add new sequence to settings
                 $settings['dashboard_sequence'] = $newSequence;
             }
             // has the user submitted an avatar?
             if ($fields['avatar']->isFilled()) {
                 // init vars
                 $avatarsPath = FRONTEND_FILES_PATH . '/backend_users/avatars';
                 // delete old avatar if it isn't the default-image
                 if ($this->record['settings']['avatar'] != 'no-avatar.jpg' && $this->record['settings']['avatar'] != '') {
                     $fs = new Filesystem();
                     $fs->remove($avatarsPath . '/source/' . $this->record['settings']['avatar']);
                     $fs->remove($avatarsPath . '/128x128/' . $this->record['settings']['avatar']);
                     $fs->remove($avatarsPath . '/64x64/' . $this->record['settings']['avatar']);
                     $fs->remove($avatarsPath . '/32x32/' . $this->record['settings']['avatar']);
                 }
                 // create new filename
                 $filename = rand(0, 3) . '_' . $user['id'] . '.' . $fields['avatar']->getExtension();
                 // add into settings to update
                 $settings['avatar'] = $filename;
                 // resize (128x128)
                 $fields['avatar']->createThumbnail($avatarsPath . '/128x128/' . $filename, 128, 128, true, false, 100);
                 // resize (64x64)
                 $fields['avatar']->createThumbnail($avatarsPath . '/64x64/' . $filename, 64, 64, true, false, 100);
                 // resize (32x32)
                 $fields['avatar']->createThumbnail($avatarsPath . '/32x32/' . $filename, 32, 32, true, false, 100);
             }
             // save changes
             BackendUsersModel::update($user, $settings);
             // save groups
             if ($this->allowUserRights) {
                 BackendGroupsModel::insertMultipleGroups($this->id, $groups);
             }
             // trigger event
             BackendModel::triggerEvent($this->getModule(), 'after_edit', array('item' => $user));
             // can only edit own profile
             if (!BackendAuthentication::isAllowedAction('Index')) {
                 // everything is saved, so redirect to the edit page
                 $this->redirect(BackendModel::createURLForAction('Edit') . '&id=' . $this->id . '&report=edited&var=' . $settings['nickname']);
             } else {
                 // everything is saved, so redirect to the overview
                 $this->redirect(BackendModel::createURLForAction('Index') . '&report=edited&var=' . $settings['nickname'] . '&highlight=row-' . $user['id']);
             }
         }
     }
 }
Ejemplo n.º 9
0
 /**
  * Update the user password
  *
  * @param BackendUser $user     An instance of BackendUser.
  * @param string      $password The new password for the user.
  */
 public static function updatePassword(BackendUser $user, $password)
 {
     // fetch user info
     $userId = $user->getUserId();
     $key = $user->getSetting('password_key');
     // update user
     BackendModel::getContainer()->get('database')->update('users', array('password' => BackendAuthentication::getEncryptedString((string) $password, $key)), 'id = ?', $userId);
     // remove the user settings linked to the resetting of passwords
     self::deleteResetPasswordSettings($userId);
 }