/** * Creates a person object for testing. * * @return Alpha\Model\Person * * @since 2.0 */ private function createPersonObject($name) { $person = new Person(); $person->setDisplayname($name); $person->set('email', $name . '@test.com'); $person->set('password', 'passwordTest'); $person->set('URL', 'http://unitTestUser/'); return $person; }
/** * Login the user and re-direct to the defined destination. * * @param string $password The password supplied by the user logging in * * @throws Alpha\Exception\ValidationException * * @return Alpha\Util\Http\Response * * @since 1.0 */ protected function doLoginAndRedirect($password) { self::$logger->debug('>>doLoginAndRedirect(password=[' . $password . '])'); $config = ConfigProvider::getInstance(); if (!$this->personObject->isTransient() && $this->personObject->get('state') == 'Active') { if (password_verify($password, $this->personObject->get('password'))) { $sessionProvider = $config->get('session.provider.name'); $session = SessionProviderFactory::getInstance($sessionProvider); $session->set('currentUser', $this->personObject); self::$logger->debug('Logging in [' . $this->personObject->get('email') . '] at [' . date('Y-m-d H:i:s') . ']'); self::$logger->action('Login'); $response = new Response(301); if ($this->getNextJob() != '') { $response->redirect(FrontController::generateSecureURL('act=' . $this->getNextJob())); $this->clearUnitOfWorkAttributes(); } else { $response->redirect($config->get('app.url')); } return $response; } else { throw new ValidationException('Failed to login user ' . $this->personObject->get('email') . ', the password is incorrect!'); self::$logger->debug('<<doLoginAndRedirect'); } } }
/** * Testing the getRelatedObject method. * * @since 1.2.1 */ public function testGetRelatedObject() { $oneToOneRel = new Relation(); $oneToOneRel->setRelatedClass('Alpha\\Model\\Person'); $oneToOneRel->setRelatedClassField('OID'); $oneToOneRel->setRelatedClassDisplayField('displayName'); $oneToOneRel->setRelationType('ONE-TO-ONE'); $oneToOneRel->setValue($this->person->getOID()); $this->assertEquals($this->person->getDisplayName(), $oneToOneRel->getRelatedObject()->get('displayName'), 'testing the getRelatedObject method'); }
/** * Set up tests. * * @since 2.0 */ protected function setUp() { $config = ConfigProvider::getInstance(); $config->set('session.provider.name', 'Alpha\\Util\\Http\\Session\\SessionProviderArray'); $standardGroup = new Rights(); $standardGroup->rebuildTable(); $standardGroup->set('name', 'Standard'); $standardGroup->save(); $person = new Person(); $person->set('displayName', 'unittestuser'); $person->set('email', '*****@*****.**'); $person->set('password', 'password'); $person->rebuildTable(); $person->save(); $article = new Article(); $article->set('title', 'unit test'); $article->set('description', 'unit test'); $article->set('content', 'unit test'); $article->set('author', 'unit test'); $article->rebuildTable(); $article->save(); $comment = new ArticleComment(); $comment->set('content', 'unit test'); $comment->getPropObject('articleOID')->setValue($article->getOID()); $comment->rebuildTable(); $comment->save(); }
/** * Testing the removeFromCache method. * * @since 1.2.1 * @dataProvider getActiveRecordProviders */ public function testRemoveFromCache($provider) { $config = ConfigProvider::getInstance(); $config->set('db.provider.name', $provider); $config = ConfigProvider::getInstance(); $oldSetting = $config->get('cache.provider.name'); $config->set('cache.provider.name', 'Alpha\\Util\\Cache\\CacheProviderArray'); $this->person->save(); $fromCache = new Person(); $fromCache->setOID($this->person->getOID()); $this->assertTrue($fromCache->loadFromCache(), 'testing that the item loads from the cache'); $fromCache->removeFromCache(); $this->assertFalse($fromCache->loadFromCache(), 'testing that the item is gone from the cache'); $config->set('cache.provider.name', $oldSetting); }
/** * Method to generate the markdown HTML render of the ArticleComment content. * * @param array $fields hash array of HTML fields to pass to the template * * @since 1.0 * * @return string */ public function markdownView($fields = array()) { $config = ConfigProvider::getInstance(); $sessionProvider = $config->get('session.provider.name'); $session = SessionProviderFactory::getInstance($sessionProvider); $markdown = new MarkdownFacade($this->BO); $author = new Person(); $id = $this->BO->getCreatorID(); $author->load($id->getValue()); $html = '<blockquote class="usercomment">'; $createTS = $this->BO->getCreateTS(); $updateTS = $this->BO->getUpdateTS(); $html .= '<p>Posted by ' . ($author->get('URL') == '' ? $author->get('displayname') : '<a href="' . $author->get('URL') . '" target="new window">' . $author->get('displayname') . '</a>') . ' at ' . $createTS->getValue() . '.'; $html .= ' ' . $author->get('displayname') . ' has posted [' . $author->getCommentCount() . '] comments on articles since joining.'; $html .= '</p>'; if ($config->get('cms.comments.allowed') && $session->get('currentUser') != null && $session->get('currentUser')->getID() == $author->getID()) { $html .= $this->editView($fields); } else { $html .= $markdown->getContent(); } if ($createTS->getValue() != $updateTS->getValue()) { $updator = new Person(); $id = $this->BO->getCreatorID(); $updator->load($id->getValue()); $html .= '<p>Updated by ' . ($updator->get('URL') == '' ? $updator->get('displayname') : '<a href="' . $updator->get('URL') . '" target="new window">' . $updator->get('displayname') . '</a>') . ' at ' . $updateTS->getValue() . '.</p>'; } $html .= '</blockquote>'; return $html; }
/** * Testing the getRelatedObjects method with a ONE-TO-MANY and MANY-TO-MANY relation. * * @since 1.2.1 */ public function testGetRelatedObjects() { $group = new Rights(); $group->set('name', 'unittestgroup'); $group->save(); $person1 = new Person(); $person1->set('displayName', 'user1'); $person1->set('email', '*****@*****.**'); $person1->set('password', 'password'); $person1->save(); $lookup = $person1->getPropObject('rights')->getLookup(); $lookup->setValue(array($person1->getOID(), $group->getOID())); $lookup->save(); $person2 = new Person(); $person2->set('displayName', 'user2'); $person2->set('email', '*****@*****.**'); $person2->set('password', 'password'); $person2->save(); $lookup = $person2->getPropObject('rights')->getLookup(); $lookup->setValue(array($person2->getOID(), $group->getOID())); $lookup->save(); $person2->getPropObject('rights')->setValue($group->getOID()); $this->assertEquals(2, count($group->getPropObject('members')->getRelatedObjects('Alpha\\Model\\Rights')), 'testing the getRelatedObjects method with a MANY-TO-MANY relation'); $this->assertTrue($group->getPropObject('members')->getRelatedObjects('Alpha\\Model\\Rights')[0] instanceof Person, 'testing the getRelatedObjects method with a MANY-TO-MANY relation'); $article = new Article(); $article->set('title', 'unit test'); $article->set('description', 'unit test'); $article->set('content', 'unit test'); $article->set('author', 'unit test'); $article->save(); $comment1 = new ArticleComment(); $comment1->set('content', 'unit test'); $comment1->getPropObject('articleOID')->setValue($article->getOID()); $comment1->save(); $comment2 = new ArticleComment(); $comment2->set('content', 'unit test'); $comment2->getPropObject('articleOID')->setValue($article->getOID()); $comment2->save(); $this->assertEquals(2, count($article->getPropObject('comments')->getRelatedObjects()), 'testing the getRelatedObjects method with a ONE-TO-MANY relation'); $this->assertTrue($article->getPropObject('comments')->getRelatedObjects()[0] instanceof ArticleComment, 'testing the getRelatedObjects method with a ONE-TO-MANY relation'); }
/** * Testing that enum options are loaded correctly from the database. * * @since 1.0 */ public function testLoadEnumOptions() { $this->person->loadByAttribute('displayName', 'enumunittest', true); $this->assertEquals('Active', $this->person->getPropObject('state')->getValue(), 'Testing that enum options are loaded correctly from the database'); }
/** * Handle GET requests. * * @param Alpha\Util\Http\Request $request * * @return Alpha\Util\Http\Response * * @since 1.0 */ public function doGET($request) { self::$logger->debug('>>doGET($request=[' . var_export($request, true) . '])'); $config = ConfigProvider::getInstance(); $sessionProvider = $config->get('session.provider.name'); $session = SessionProviderFactory::getInstance($sessionProvider); // if there is nobody logged in, we will send them off to the Login controller to do so before coming back here if ($session->get('currentUser') === false) { self::$logger->info('Nobody logged in, invoking Login controller...'); $controller = new LoginController(); $controller->setName('LoginController'); $controller->setRequest($request); $controller->setUnitOfWork(array('Alpha\\Controller\\LoginController', 'Alpha\\Controller\\InstallController')); self::$logger->debug('<<__construct'); return $controller->doGET($request); } $params = $request->getParams(); $sessionProvider = $config->get('session.provider.name'); $session = SessionProviderFactory::getInstance($sessionProvider); $body = View::displayPageHead($this); $body .= '<h1>Installing the ' . $config->get('app.title') . ' application</h1>'; try { $body .= $this->createApplicationDirs(); } catch (\Exception $e) { $body .= View::displayErrorMessage($e->getMessage()); $body .= View::displayErrorMessage('Aborting.'); return new Response(500, $body, array('Content-Type' => 'text/html')); } // start a new database transaction ActiveRecord::begin(); /* * Create DEnum tables */ $DEnum = new DEnum(); $DEnumItem = new DEnumItem(); try { $body .= '<p>Attempting to create the DEnum tables...'; if (!$DEnum->checkTableExists()) { $DEnum->makeTable(); } self::$logger->info('Created the [' . $DEnum->getTableName() . '] table successfully'); if (!$DEnumItem->checkTableExists()) { $DEnumItem->makeTable(); } self::$logger->info('Created the [' . $DEnumItem->getTableName() . '] table successfully'); // create a default article DEnum category $DEnum = new DEnum('Alpha\\Model\\Article::section'); $DEnumItem = new DEnumItem(); $DEnumItem->set('value', 'Main'); $DEnumItem->set('DEnumID', $DEnum->getID()); $DEnumItem->save(); $body .= View::displayUpdateMessage('DEnums set up successfully.'); } catch (\Exception $e) { $body .= View::displayErrorMessage($e->getMessage()); $body .= View::displayErrorMessage('Aborting.'); self::$logger->error($e->getMessage()); ActiveRecord::rollback(); return new Response(500, $body, array('Content-Type' => 'text/html')); } /* * Loop over each business object in the system, and create a table for it */ $classNames = ActiveRecord::getBOClassNames(); $loadedClasses = array(); foreach ($classNames as $classname) { array_push($loadedClasses, $classname); } foreach ($loadedClasses as $classname) { try { $body .= '<p>Attempting to create the table for the class [' . $classname . ']...'; try { $BO = new $classname(); if (!$BO->checkTableExists()) { $BO->makeTable(); } else { if ($BO->checkTableNeedsUpdate()) { $missingFields = $BO->findMissingFields(); $count = count($missingFields); for ($i = 0; $i < $count; ++$i) { $BO->addProperty($missingFields[$i]); } } } } catch (FailedIndexCreateException $eice) { // this are safe to ignore for now as they will be auto-created later once all of the tables are in place self::$logger->warn($eice->getMessage()); } catch (FailedLookupCreateException $elce) { // this are safe to ignore for now as they will be auto-created later once all of the tables are in place self::$logger->warn($elce->getMessage()); } self::$logger->info('Created the [' . $BO->getTableName() . '] table successfully'); $body .= View::displayUpdateMessage('Created the [' . $BO->getTableName() . '] table successfully'); } catch (\Exception $e) { $body .= View::displayErrorMessage($e->getMessage()); $body .= View::displayErrorMessage('Aborting.'); self::$logger->error($e->getMessage()); ActiveRecord::rollback(); return new Response(500, $body, array('Content-Type' => 'text/html')); } } $body .= View::displayUpdateMessage('All business object tables created successfully!'); /* * Create the Admin and Standard groups */ $adminGroup = new Rights(); $adminGroup->set('name', 'Admin'); $standardGroup = new Rights(); $standardGroup->set('name', 'Standard'); try { try { $body .= '<p>Attempting to create the Admin and Standard groups...'; $adminGroup->save(); $standardGroup->save(); self::$logger->info('Created the Admin and Standard rights groups successfully'); $body .= View::displayUpdateMessage('Created the Admin and Standard rights groups successfully'); } catch (FailedIndexCreateException $eice) { // this are safe to ignore for now as they will be auto-created later once all of the tables are in place self::$logger->warn($eice->getMessage()); } catch (FailedLookupCreateException $elce) { // this are safe to ignore for now as they will be auto-created later once all of the tables are in place self::$logger->warn($elce->getMessage()); } } catch (\Exception $e) { $body .= View::displayErrorMessage($e->getMessage()); $body .= View::displayErrorMessage('Aborting.'); self::$logger->error($e->getMessage()); ActiveRecord::rollback(); return new Response(500, $body, array('Content-Type' => 'text/html')); } /* * Save the admin user to the database in the right group */ try { try { $body .= '<p>Attempting to save the Admin account...'; $admin = new Person(); $admin->set('displayName', 'Admin'); $admin->set('email', $session->get('currentUser')->get('email')); $admin->set('password', $session->get('currentUser')->get('password')); $admin->save(); self::$logger->info('Created the admin user account [' . $session->get('currentUser')->get('email') . '] successfully'); $adminGroup->loadByAttribute('name', 'Admin'); $lookup = $adminGroup->getMembers()->getLookup(); $lookup->setValue(array($admin->getID(), $adminGroup->getID())); $lookup->save(); self::$logger->info('Added the admin account to the Admin group successfully'); $body .= View::displayUpdateMessage('Added the admin account to the Admin group successfully'); } catch (FailedIndexCreateException $eice) { // this are safe to ignore for now as they will be auto-created later once all of the tables are in place self::$logger->warn($eice->getMessage()); } catch (FailedLookupCreateException $elce) { // this are safe to ignore for now as they will be auto-created later once all of the tables are in place self::$logger->warn($elce->getMessage()); } } catch (\Exception $e) { $body .= View::displayErrorMessage($e->getMessage()); $body .= View::displayErrorMessage('Aborting.'); self::$logger->error($e->getMessage()); ActiveRecord::rollback(); return new Response(500, $body, array('Content-Type' => 'text/html')); } $body .= '<br><p align="center"><a href="' . FrontController::generateSecureURL('act=Alpha\\Controller\\ListActiveRecordsController') . '">Administration Home Page</a></p><br>'; $body .= View::displayPageFoot($this); // commit ActiveRecord::commit(); self::$logger->info('Finished installation!'); self::$logger->action('Installed the application'); self::$logger->debug('<<doGET'); return new Response(200, $body, array('Content-Type' => 'text/html')); }
/** * Testing the getFriendlyClassName() method. * * @since 1.2.1 */ public function testGetFriendlyClassName() { $person = new Person(); $article = new Article(); $comment = new ArticleComment(); $this->assertEquals('Person', $person->getFriendlyClassName(), 'testing the getFriendlyClassName() method'); $this->assertEquals('Article', $article->getFriendlyClassName(), 'testing the getFriendlyClassName() method'); $this->assertEquals('ArticleComment', $comment->getFriendlyClassName(), 'testing the getFriendlyClassName() method'); }
/** * Handle POST requests (adds $currentUser Person to the session). * * @param Alpha\Util\Http\Request $request * * @return Alpha\Util\Http\Response * * @throws Alpha\Exception\IllegalArguementException * * @since 1.0 */ public function doPOST($request) { self::$logger->debug('>>doPOST($request=[' . var_export($request, true) . '])'); $params = $request->getParams(); if (!is_array($params)) { throw new IllegalArguementException('Bad $params [' . var_export($params, true) . '] passed to doPOST method!'); } $config = ConfigProvider::getInstance(); $body = ''; try { // check the hidden security fields before accepting the form POST data if (!$this->checkSecurityFields()) { throw new SecurityException('This page cannot accept post data from remote servers!'); } if (isset($params['loginBut'])) { // if the database has not been set up yet, accept a login from the config admin username/password if (!ActiveRecord::isInstalled()) { if ($params['email'] == $config->get('app.install.username') && password_verify($params['password'], password_hash($config->get('app.install.password'), PASSWORD_DEFAULT, ['cost' => 12]))) { self::$logger->info('Logging in [' . $params['email'] . '] at [' . date('Y-m-d H:i:s') . ']'); $admin = new Person(); $admin->set('displayName', 'Admin'); $admin->set('email', $params['email']); $admin->set('password', password_hash($params['password'], PASSWORD_DEFAULT, ['cost' => 12])); $admin->set('OID', '00000000001'); $sessionProvider = $config->get('session.provider.name'); $session = SessionProviderFactory::getInstance($sessionProvider); $session->set('currentUser', $admin); $response = new Response(301); if ($this->getNextJob() != '') { $response->redirect(FrontController::generateSecureURL('act=' . $this->getNextJob())); $this->clearUnitOfWorkAttributes(); } else { $response->redirect(FrontController::generateSecureURL('act=InstallController')); } return $response; } else { throw new ValidationException('Failed to login user ' . $params['email'] . ', the password is incorrect!'); } } else { // here we are attempting to load the person from the email address $this->personObject->loadByAttribute('email', $params['email'], true); ActiveRecord::disconnect(); // checking to see if the account has been disabled if (!$this->personObject->isTransient() && $this->personObject->get('state') == 'Disabled') { throw new SecurityException('Failed to login user ' . $params['email'] . ', that account has been disabled!'); } // check the password return $this->doLoginAndRedirect($params['password']); } $body .= View::displayPageHead($this); $body .= $this->personView->displayLoginForm(); } if (isset($params['resetBut'])) { // here we are attempting to load the person from the email address $this->personObject->loadByAttribute('email', $params['email']); ActiveRecord::disconnect(); // generate a new random password $newPassword = $this->personObject->generatePassword(); // now encrypt and save the new password, then e-mail the user $this->personObject->set('password', password_hash($newPassword, PASSWORD_DEFAULT, ['cost' => 12])); $this->personObject->save(); $message = 'The password for your account has been reset to ' . $newPassword . ' as you requested. You can now login to the site using your ' . 'e-mail address and this new password as before.'; $subject = 'Password change request'; $this->personObject->sendMail($message, $subject); $body .= View::displayUpdateMessage('The password for the user <strong>' . $params['email'] . '</strong> has been reset, and the new password ' . 'has been sent to that e-mail address.'); $body .= '<a href="' . $config->get('app.url') . '">Home Page</a>'; } } catch (ValidationException $e) { $body .= View::displayPageHead($this); $body .= View::displayErrorMessage($e->getMessage()); if (isset($params['reset'])) { $body .= $this->personView->displayResetForm(); } else { $body .= $this->personView->displayLoginForm(); } self::$logger->warn($e->getMessage()); } catch (SecurityException $e) { $body .= View::displayPageHead($this); $body .= View::displayErrorMessage($e->getMessage()); self::$logger->warn($e->getMessage()); } catch (RecordNotFoundException $e) { $body .= View::displayPageHead($this); $body .= View::displayErrorMessage('Failed to find the user \'' . $params['email'] . '\''); if (isset($params['reset'])) { $body .= $this->personView->displayResetForm(); } else { $body .= $this->personView->displayLoginForm(); } self::$logger->warn($e->getMessage()); } $body .= View::displayPageFoot($this); self::$logger->debug('<<doPOST'); return new Response(200, $body, array('Content-Type' => 'text/html')); }
/** * Testing the loadAllbyAttribute() method. * * @since 1.2.1 */ public function testLoadAllbyAttribute() { $group = new Rights(); $group->set('name', 'unittestgroup'); $group->save(); $person1 = new Person(); $person1->set('displayName', 'user1'); $person1->set('email', '*****@*****.**'); $person1->set('password', 'password'); $person1->save(); $lookup = $person1->getPropObject('rights')->getLookup(); $lookup->setValue(array($person1->getOID(), $group->getOID())); $lookup->save(); $person2 = new Person(); $person2->set('displayName', 'user2'); $person2->set('email', '*****@*****.**'); $person2->set('password', 'password'); $person2->save(); $lookup = $person2->getPropObject('rights')->getLookup(); $lookup->setValue(array($person2->getOID(), $group->getOID())); $lookup->save(); $lookup = new RelationLookup('Alpha\\Model\\Person', 'Alpha\\Model\\Rights'); $this->assertEquals(2, count($lookup->loadAllbyAttribute('rightID', $group->getOID())), 'testing the loadAllbyAttribute() method'); }
/** * Testing the doPOST method. */ public function testDoPOST() { $config = ConfigProvider::getInstance(); $sessionProvider = $config->get('session.provider.name'); $session = SessionProviderFactory::getInstance($sessionProvider); $person = new Person(); $person->dropTable(); $front = new FrontController(); $controller = new LoginController(); $securityParams = $controller->generateSecurityFields(); $params = array('loginBut' => true, 'var1' => $securityParams[0], 'var2' => $securityParams[1], 'email' => $config->get('app.install.username'), 'password' => $config->get('app.install.password')); $request = new Request(array('method' => 'POST', 'URI' => '/login', 'params' => $params)); $response = $front->process($request); $this->assertEquals(301, $response->getStatus(), 'Testing the doPOST method during install'); $person->makeTable(); $person = $this->createPersonObject('logintest'); $person->save(); $params = array('loginBut' => true, 'var1' => $securityParams[0], 'var2' => $securityParams[1], 'email' => '*****@*****.**', 'password' => 'passwordTest'); $request = new Request(array('method' => 'POST', 'URI' => '/login', 'params' => $params)); $response = $front->process($request); $this->assertEquals(301, $response->getStatus(), 'Testing the doPOST with correct password'); $params['password'] = '******'; $request = new Request(array('method' => 'POST', 'URI' => '/login', 'params' => $params)); $response = $front->process($request); $this->assertEquals(200, $response->getStatus(), 'Testing the doPOST with incorrect password'); $params = array('resetBut' => true, 'var1' => $securityParams[0], 'var2' => $securityParams[1], 'email' => '*****@*****.**'); $request = new Request(array('method' => 'POST', 'URI' => '/login', 'params' => $params)); $response = $front->process($request); $this->assertEquals(200, $response->getStatus(), 'Testing the doPOST during password reset'); $person->reload(); $this->assertNotEquals($person->get('password'), password_hash('passwordTest', PASSWORD_DEFAULT, ['cost' => 12]), 'Checking that the password has changed in the database'); }
/** * Testing that we can load dirty and new objects post commit. * * @since 1.0 */ public function testPostCommitLoad() { $this->person->set('email', '*****@*****.**'); $this->controller->markDirty($this->person); $person = $this->createPersonObject('newuser'); $person->set('email', '*****@*****.**'); $this->controller->markNew($person); try { $this->controller->commit(); } catch (FailedUnitCommitException $e) { $this->fail('Failed to commit the unit of work transaction for new and dirty objects'); } $newPerson = new Person(); try { $newPerson->loadByAttribute('email', '*****@*****.**'); } catch (RecordNotFoundException $e) { $this->fail('Failed to load the new person that we commited in the unit of work'); } $dirtyPerson = new Person(); try { $dirtyPerson->loadByAttribute('email', '*****@*****.**'); } catch (RecordNotFoundException $e) { $this->fail('Failed to load the dirty person that we commited in the unit of work'); } }