From fef6b43b7b9c566e8b58d942702123f5bf2567bc Mon Sep 17 00:00:00 2001 From: Ryan Rathsam Date: Thu, 18 May 2017 09:20:38 -0400 Subject: [PATCH] Acl: XDUser Changes - Bringing the format of XDUser up to speed before continuing with ACL modifications. Adding models that support the Acl transition - Adding a number of new models that act as: - a way to document and pin our code to a particular set of table columns for a particular code version - a shim between PDO result sets and the rest of our code as they have been built with the following use case in mind: $results = array(); $rows = $db->query("SELECT * FROM some_table;"); foreach($rows as $row) { $results []= new Model($row); } the model code takes care of mapping all of the columns to the correct properties. It works on a whitelist concept so any extraneous columns are ignored for the purposes property setting. - I added the @method annotations purely to make users lives a little easier as it explicitly lays out which functions are supported by each class. Meaning if they're new they don't need to dig into DBObject to find out what the $PROP_MAP does ( although they can obviously ). They can just rely on the class providing those methods. - Added a 'service' class Acls ( service naming just being the plural of the model they support ) that provides a number of helper functions / encapsulates a great deal about the underlying table structure allowing the user to provide a few bits of information and let the service take care of the rest. Porting XDUser changes from acls branch to this one - These changes update the portions of the XDUser api to use the new acl tables / relations where possible. They make use of the new Model / Service classes that were added in previous commits. Migrating isDeveloper to be based off of acls - isDeveloper was previously based off of the roles array, now it's based off of acls. Initializing _acls in the constructor of XDUser - the _acls property needs to be initialized when XDUser is. Updating the removeUser to use isPublicUser instead of active_role - Just migrating this like the other instances of comparison to ROLE_ID_PUBLIC While the return value cannot be false it could be empty - to prevent accessing an array entry that doesn't exist added a conditional that only allow the access to occur if there is 1 or more records returned. XDUserTest: tests the modified and newly added acl functions - Huge caveat: to run these tests you need a fully functional xdmod install. Both database and generated classes. - I have not included the generated coverage html but the % lines covered for the functions that were modified are as follows: - isDeveloper: 100% - saveUser: 95% - getToken: 100% - getTokenExpiration: 100% - removeUser: 96% - setInstitution: 90% - disassociateWithInstitution: 90% - setOrganizations: 90% - getRoles: 100% - setRoles: 100% - getPrimaryRole: 100% - getActiveRole: 100% - getAcls: 100% - setAcls: 100% - addAcl: 100% - hasAcl: 100% - hasAcls: 100% - getUserByUserName: 100% Namespace formatting fix - Removed the extra line after the namespace. Fixed invalid sql syntax - The SQL syntax for 'deleteAcl' was invalid. You are not allowed to alias tables in a DELETE statement. Simplifying the query / logic of addUserAcl - Instead of issuing two database queries, one to find and another one to insert. We instead INSERT the results of a SELECT that will only return results if the record that would be inserted does not exist ( WHERE cur.user_acl_id IS NULL ). Updating Acls function documentation - Updated / Added documentation where it was missing / incorrect. Updating XDUserTest to utilize pi - Open XDMoD does not have the program officer user so use pi instead. - Also update the default institution value to 0 as opposed to -1. Clarifying getPublicUser - minor code refactor to increase legibility per code review comment by @jpwhite4 Adding Component Test folder - Adding a place for Component Tests to live. i.e. tests that require access to the database but are not doing so via the REST interface. Adding sql script to create the Public User - We now have the code in place to deal with an actual Public User, so we'll be adding it during the execution of the acl-import pipeline. Adding component tests to shippable Updated the XDUserTest namespace - simple c/p mistake Updated so it reflects the current namespace. Testing shippable changes to accommodate component tests Add acl-import to be run during a fresh_install Resolve Initial Acls not being set - instead of directly assigning the incoming $role_set to _roles we instead utilize the function setRoles which will take care of keeping the acls in sync. - remove the initialization of _acls to an empty array() as this would override the work done by setRoles. - Also needed to remove the additional acl-import in integration_tests/scripts/bootstrap.sh as we need to see if the changes made to XDUser work as expected. Adding some jobviewer tests to exercise the Acl code - Added some integration tests to exercise the acl code via the single job viewer - job search end point. Updating Usr Tests - Missed the c/p from pi -> usr. Removing JobViewerTests, these belong in the supremm module Resolving spacing syntax issue restoring portal_settings.ini from ini.old - Adding a line per discussion with @jpwhite4 to restore the original portal_settings.ini ( from portal_settings.ini.old ). --- classes/Models/Acl.php | 156 + classes/Models/DBObject.php | 73 + classes/Models/GroupBy.php | 57 + classes/Models/Realm.php | 30 + classes/Models/Services/Acls.php | 783 +++ classes/Models/Statistic.php | 44 + classes/XDUser.php | 4251 +++++++++-------- configuration/etl/etl.d/acls-import.json | 8 + .../acls/xdmod/create_public_user.sql | 40 + .../xdmod/component_tests/bootstrap.php | 23 + .../xdmod/component_tests/lib/XDUserTest.php | 582 +++ .../xdmod/component_tests/phpunit.xml.dist | 21 + .../modules/xdmod/component_tests/runtests.sh | 13 + shippable.yml | 5 +- 14 files changed, 4148 insertions(+), 1938 deletions(-) create mode 100644 classes/Models/Acl.php create mode 100644 classes/Models/DBObject.php create mode 100644 classes/Models/GroupBy.php create mode 100644 classes/Models/Realm.php create mode 100644 classes/Models/Services/Acls.php create mode 100644 classes/Models/Statistic.php create mode 100644 configuration/etl/etl_sql.d/acls/xdmod/create_public_user.sql create mode 100644 open_xdmod/modules/xdmod/component_tests/bootstrap.php create mode 100644 open_xdmod/modules/xdmod/component_tests/lib/XDUserTest.php create mode 100644 open_xdmod/modules/xdmod/component_tests/phpunit.xml.dist create mode 100755 open_xdmod/modules/xdmod/component_tests/runtests.sh diff --git a/classes/Models/Acl.php b/classes/Models/Acl.php new file mode 100644 index 0000000000..420c2a6b43 --- /dev/null +++ b/classes/Models/Acl.php @@ -0,0 +1,156 @@ + 'aclId', + 'module_id' => 'moduleId', + 'acl_type_id' => 'aclTypeId', + 'name' => 'name', + 'display' => 'display', + 'enabled' => 'enabled', + + // Needed for getParameters + 'user_id' => 'userId' + ); + + /** + * @return array|null + * @throws \Exception + */ + public function getParameters() + { + $userId = $this->getUserId(); + if (!isset($userId)) { + throw new \Exception('Acl has no user_id. Cannot retrieve parameters'); + } + $aclId = $this->getAclId(); + if (!isset($aclId)) { + throw new \Exception('Acl has no acl_id. Cannot retrieve parameters'); + } + + $db = DB::factory('database'); + + $query =<<< SQL +SELECT DISTINCT + uagbp.user_id, + uagbp.acl_id, + gb.name, + '=', + uagbp.value +FROM user_acl_group_by_parameters uagbp + JOIN user_acls ua + ON uagbp.user_id = ua.user_id + AND uagbp.acl_id = ua.acl_id + JOIN group_bys gb + ON gb.group_by_id = uagbp.group_by_id +WHERE + ua.user_id = :user_id +AND ua.acl_id = :acl_id +SQL; + $rows = $db->query($query, array(':user_id' => $userId, ':acl_id' => $aclId)); + if (false !== $rows) { + $results = array_reduce($rows, function ($carry, $item) { + $carry[$item['name']] = $item['value']; + return $carry; + }, $rows); + return $results; + } + + return null; + } + + /** + * Determine if the user who has access to this acl + * + * @param $query_groupname + * @param null $realm_name + * @param null $group_by_name + * @param null $statistic_name + * @return bool + * @throws \Exception + */ + public function hasDataAccess($query_groupname, $realm_name = null, $group_by_name = null, $statistic_name = null) + { + $userId = $this->getUserId(); + if (null === $userId) { + throw new \Exception('Acl has no user_id. Cannot check data access'); + } + + $params = array( + ':user_id' => $userId + ); + + $hasRealm = isset($realm_name); + $hasGroupBy = isset($group_by_name); + $hasStatistic = isset($statistic_name); + + $query =<<query($query, $params); + + return $rows !== false && count($rows) > 0; + } +} diff --git a/classes/Models/DBObject.php b/classes/Models/DBObject.php new file mode 100644 index 0000000000..a515089a7d --- /dev/null +++ b/classes/Models/DBObject.php @@ -0,0 +1,73 @@ + columnName. + * + * And for those who enjoy working with their classes in an array type manner. + * ArrayAccess has been implemented such that 'offsetGet' corresponds to + * 'getCamelCasePropertyName()', 'offsetSet' corresponds to + * 'setCamelCasePropertyName($propertyName)' and 'offsetExists($offset)' + * ensures that the '$offset' is defined in the $PROP_MAP and that there + * is a property currently defined with a name that that matches '$offset'; + * + * @author Ryan Rathsam + */ +class DBObject +{ + + protected $PROP_MAP = array(); + + /** + * Default Constructor + * + * @param array $options the options used to configure this instance. + **/ + public function __construct($options = array()) + { + $properties = $this->PROP_MAP; + + foreach ($properties as $property => $value) { + if (array_key_exists($property, $options)) { + $this->$value = $options[$property]; + } + } + } + + /** + * @inheritDoc + **/ + public function __call($name, $arguments) + { + /* The following block of code dynamically generates 'getters' and + * 'setters' based on the properties the class currently supports. + * This frees child classes from needing to clutter their class space + * with boiler plate functions. + */ + + $var = lcfirst(substr($name, 3)); + if ((strncasecmp($name, 'get', 3) === 0) && + property_exists($this, $var) + ) { + return $this->$var; + } elseif ((strncasecmp($name, 'set', 3) === 0) && + (property_exists($this, $var)) + ) { + $this->$var = $arguments[0]; + } + } +} diff --git a/classes/Models/GroupBy.php b/classes/Models/GroupBy.php new file mode 100644 index 0000000000..76c9c77755 --- /dev/null +++ b/classes/Models/GroupBy.php @@ -0,0 +1,57 @@ + 'groupById', + 'module_id' => 'moduleId', + 'realm_id' => 'realmId', + 'name' => 'name', + 'display' => 'display', + 'description' => 'description', + 'schema_name'=> 'schemaName', + 'table_name' => 'tableName', + 'alias'=> 'alias', + 'id_column' => 'idColumn', + 'name_column' => 'nameColumn', + 'shortname_column' => 'shortnameColumn', + 'order_id_column' => 'orderIdColumn', + 'fk_column' => 'fkColumn', + 'class' => 'clazz' + ); +} diff --git a/classes/Models/Realm.php b/classes/Models/Realm.php new file mode 100644 index 0000000000..9fd82e851c --- /dev/null +++ b/classes/Models/Realm.php @@ -0,0 +1,30 @@ + 'realmId', + 'module_id' => 'moduleId', + 'name' => 'name', + 'display'=> 'display', + 'schema_name' => 'schemaName', + 'table_name' => 'tableName' + ); +} diff --git a/classes/Models/Services/Acls.php b/classes/Models/Services/Acls.php new file mode 100644 index 0000000000..21dfd7d271 --- /dev/null +++ b/classes/Models/Services/Acls.php @@ -0,0 +1,783 @@ +query("SELECT a.* FROM acls a"); + return array_reduce($results, function ($carry, $item) { + $carry [] = new Acl($item); + return $carry; + }, array()); + } + + /** + * Attempt to retrieve the acl identified by the '$aclId' provided. + * + * @param integer $aclId + * @return null|Acl null if an acl could not be found for the provided '$aclId' + * else a fully populated Acl. + * @throws Exception if the aclId is null + */ + public static function getAcl($aclId) + { + if (null === $aclId) { + throw new Exception('Must provide an acl id.'); + } + + $db = DB::factory('database'); + + $query = <<query($query, array(':acl_id' => $aclId)); + + if (count($results) > 0) { + return new Acl($results[0]); + } + return null; + } + + /** + * Attempt to create a database representation of the provided '$acl'. Note, + * the 'aclId' property of '$acl' must not be set. If it is then an + * exception will be thrown. + * + * @param Acl $acl that will be created + * @return Acl with the $aclId populated. + * @throws Exception if the provided acls aclId is not null + */ + public static function createAcl(Acl $acl) + { + if (null != $acl->getAclId()) { + throw new Exception('acl must not have been saved.'); + } + + $db = DB::factory('database'); + + $query = <<insert($query, array( + ':module_id' => $acl->getModuleId(), + ':acl_type_id' => $acl->getAclTypeId(), + ':name' => $acl->getName(), + ':display' => $acl->getDisplay(), + ':enabled' => $acl->getEnabled() + )); + + $acl->setAclId($aclId); + + return $acl; + } + + /** + * Attempt to update the database representation of the provided '$acl' such + * that the information in the database corresponds to the data in the + * object provided. + * + * @param Acl $acl to be used when updating the database table. + * @return bool true iff the number of rows updated equals 1. + * @throws Exception if the provided acl's aclId is null + */ + public static function updateAcl(Acl $acl) + { + if (null == $acl->getAclId()) { + throw new Exception('Acl must have an id to be updated.'); + } + + $db = DB::factory('database'); + + $query = <<execute($query, array( + ':module_id' => $acl->getModuleId(), + ':acl_type_id' => $acl->getAclTypeId(), + ':name' => $acl->getName(), + ':display' => $acl->getDisplay(), + ':enabled' => $acl->getEnabled() + )); + + return $rows === 1; + } + + /** + * Attempt to delete the acl identified by the provided '$aclId'. + * + * @param Acl $acl + * @return bool true iff the number of rows deleted = 1. + * @throws Exception if the provided acls aclId is null + */ + public static function deleteAcl(Acl $acl) + { + if (null == $acl->getAclId()) { + throw new Exception('Acl must have an id to be deleted.'); + } + + $db = DB::factory('database'); + + $query = "DELETE FROM acls WHERE acl_id = :acl_id"; + $rows = $db->execute($query, array( + ':acl_id' => $acl->getAclId() + )); + return $rows === 1; + } + + /** + * Retrieve a list of a user's current acls. + * + * @param XDUser $user + * @return array[] + * + * @throws Exception if the user's userId is null + */ + public static function listUserAcls(XDUser $user) + { + if (null == $user->getUserID()) { + throw new Exception('A valid user id must be provided.'); + } + + $db = DB::factory('database'); + + $userId = $user->getUserID(); + + $sql = <<query($sql, array('user_id' => $userId)); + } + + /** + * Attempt to relate the provided XDUser to the Acl identified by the $aclId. + * + * @param XDUser $user the user that should have the Acl identified by the + * provided $aclId related to it. + * @param integer $aclId the unique numeric identifier for the Acl to be + * added to the provided user. + * + * @return bool true if the insert was successful else false + * + * @throws Exception if the user's userId is null + * @throws Exception if the aclId is null + */ + public static function addUserAcl(XDUser $user, $aclId) + { + if (null == $user->getUserID()) { + throw new Exception('A valid user id must be provided.'); + } + + if (null === $aclId) { + throw new Exception('A valid acl id must be provided.'); + } + $db = DB::factory('database'); + $params = array( + ':user_id' => $user->getUserId(), + ':acl_id' => $aclId + ); + $query = <<execute($query, $params); + + return $rows === 1; + } + + /** + * Attempt to remove the relation between the provided user and acl. + * + * @param XDUser $user the user that will have their relation to acl + * removed. + * @param integer $aclId the unique identifier for the acl that will be removed + * from the provided user. + * + * @return boolean true if 1 or less rows were deleted as a result of this + * action. + * + * @throws Exception if the user's userId is null + * @throws Exception if the aclId is null + **/ + public static function deleteUserAcl(XDUser $user, $aclId) + { + if (null == $user->getUserID()) { + throw new Exception('A valid user id must be provided.'); + } + if (null === $aclId) { + throw new Exception('A valid acl id must be provided.'); + } + + $db = DB::factory('database'); + + $query = "DELETE FROM user_acls WHERE user_id = :user_id AND acl_id = :acl_id"; + $rows = $db->execute($query, array( + ':user_id' => $user->getUserId(), + ':acl_id' => $aclId + )); + return $rows <= 1; + } + + /** + * Attempt to determine if the provided user has a relation to the acl + * identified by the provided aclId. + * + * @param XDUser $user the user checked for a relation to aclId + * @param integer $aclId the id of the acl checked for a relation to user + * + * @return boolean true if there is one or more results returned + * + * @throws Exception if the users userId is null + * @throws Exception if the aclId provided is null + */ + public static function userHasAcl(XDUser $user, $aclId) + { + if (null == $user->getUserID()) { + throw new Exception('A valid user id must be provided.'); + } + + if (null === $aclId) { + throw new Exception('A valid acl id must be provided.'); + } + $db = DB::factory('database'); + + $userId = $user->getUserID(); + + $sql = <<query($sql, array('acl_id' => $aclId, 'user_id' => $userId)); + + return count($results) > 0; + } + + + /** + * Similar to userHasAcl but instead of checking if the user has a relation + * to a single acl, we instead check if they have a relation to each acl + * provided in the array acls. + * + * @param XDUser $user the user being interrogated for relations to the + * provided acls + * @param array $acls the array of acls being checked for a relation to + * user + * + * @returns boolean true if the user has all of the provided acls + * + * @throws Exception if the provided user's userId is null + **/ + public static function userHasAcls(XDUser $user, array $acls) + { + if (null === $user->getUserID()) { + throw new Exception('A valid user id must be provided.'); + } + $db = DB::factory('database'); + if (count($acls) < 1) { + return false; + } + + $handle = $db->handle(); + $userId = $user->getUserID(); + $aclIds = array_reduce($acls, function ($carry, Acl $item) use ($handle) { + $carry [] = $handle->quote($item->getAclId(), PDO::PARAM_INT); + }, array()); + + $sql = <<query($sql, array('user_id' => $userId, 'acl_ids' => $aclIds)); + + return count($results) > 0; + } + + /** + * Attempt to retrieve an array that will be used by the front end to disable particular + * menu options on a user by user basis. + * + * @param XDUser $user the user for whom the disabled menus are to be + * retrieved + * @param array $realms the realms to which the disabled menus are to be + * retrieved. + + * + * @returns array + * + * @throws Exception if the provided user's userId is null + * @throws Exception if the provided array of realms is empty + **/ + public static function getDisabledMenus(XDUser $user, array $realms) + { + if (null === $user->getUserID()) { + throw new Exception('A valid user id must be provided.'); + } + + if (count($realms) < 1) { + throw new Exception('At least one realm expected must be provided.'); + } + + $db = DB::factory('database'); + + // Needed because we have 'IN' clauses. + $handle = $db->handle(); + + // PDO can't handle 'IN' for prepared statements so create some suitable strings + // for substitution. ( making sure to quote where appropriate ). + $acls = implode(',', array_reduce($user->getAcls(), function ($carry, Acl $item) use ($handle) { + $carry [] = $handle->quote($item->getAclId(), PDO::PARAM_INT); + return $carry; + }, array())); + + $realmNames = implode(',', array_reduce($realms, function ($carry, $item) use ($handle) { + $value = null; + if ($item instanceof Realm) { + $value = $item->getName(); + } elseif (is_string($item)) { + $value = $item; + } else { + $value = (string)$item; + } + $carry [] = $handle->quote($value); + return $carry; + }, array())); + + $sql = <<getDisabledMenus()' we then take care of + * formatting the results as the XDUser->getDisabledMenus function + * expects by including the group_by name / ordering by group_by name + * and constructing an associative array based on said group_by name. + * The code in XDUser->getDisabledMenus is still responsible for detecting + * whether or not any given disabled menu is present for all other acls. + */ + $rows = $db->query($sql); + + $previousName = null; + foreach ($rows as $row) { + $name = $row['name']; + if ($name != $previousName) { + $previousName = $name; + } + if (!isset($results[$name])) { + $results[$name] = array(); + } + if ($row['id'] != null) { + $results[$name] [] = array( + 'id' => $row['id'], + 'group_by' => $row['group_by'], + 'realm' => $row['realm'] + ); + } + } + + return array_filter($results, function ($item) { + return count($item) > 0; + }); + } + + + /** + * Attempt to retrieve an Acl by providing it's 'name' attribute. + * Note: if there are Acls that share the same name, only the first one + * returned ( as determined by natural table ordering ) will be returned + * from this function. + * + * @param string $name the name of the Acl to retrieve + * @return Acl|null + * @throws Exception if the name provided is null + */ + public static function getAclByName($name) + { + if (null === $name) { + throw new Exception('A valid acl name is required'); + } + + $db = DB::factory('database'); + + $sql = "SELECT * FROM acls a WHERE a.name = :name"; + + $rows = $db->query($sql, array(':name' => $name)); + + if (count($rows) > 0) { + return new Acl($rows[0]); + } + + return null; + } + + /** + * Attempt to retrieve all descriptors for the provided user. + * + * @param XDUser $user the user to use when retrieving the descriptors. + * @return array + * @throws Exception if the user's userId is null + */ + public static function getDescriptorsForUser(XDUser $user) + { + if ($user->getUserID() == null) { + throw new Exception('A valid user must be provided.'); + } + $db = DB::factory('database'); + $query = <<query($query, array(':user_id' => $user->getUserID())); + if (count($rows) > 0) { + foreach ($rows as $row) { + $realm = $row['realm']; + + if (!array_key_exists($realm, $realms)) { + $realms[$realm] = array( + 'metrics' => array(), + 'dimensions' => array(), + 'text' => $realm + ); + } + $dimensions = &$realms[$realm]['dimensions']; + $metrics = &$realms[$realm]['metrics']; + + $dimensionName = $row['dimension_name']; + $metricName = $row['metric_name']; + + // Dimension Processing + if (isset($dimensionName) && !array_key_exists($dimensionName, $dimensions)) { + $dimensions[$dimensionName] = array( + 'info' => $row['dimension_info'], + 'text' => $row['dimension_text'] + ); + } + + // Statistic Processing + if (isset($metricName) && !array_key_exists($metricName, $metrics)) { + $metrics[$metricName] = array( + 'info' => $row['metric_info'], + 'text' => $row['metric_text'], + 'std_err' => $row['metric_std_err'] + ); + } + } + } + + return array('realms' => $realms); + } + + /** + * Attempt to retrieve the statistics that a user is permitted for a given + * realm and groupBy + * + * @param XDUser $user the user on whose behalf the permitted + * statistics are being requested. + * @param string $realmName the realm in which these statistics reside + * @param string $groupByName the group by to which these statistics are + * related + * + * @return array|Statistic[] + * + * @throws Exception if the provided user's userId is null + * @throws Exception if the provided $realmName is null + * @throws Exception if the provided $groupByName is null + */ + public static function getPermittedStatistics(XDUser $user, $realmName, $groupByName) + { + if (null === $user->getUserID()) { + throw new Exception('The user must have a userId'); + } + if (null === $realmName) { + throw new Exception('A valid realm is required.'); + } + + if (null === $groupByName) { + throw new Exception('A valid group by is required'); + } + + $db = DB::factory('database'); + $query = <<query($query, array( + ':realm_name' => $realmName, + ':group_by_name' => $groupByName, + ':user_id' => $user->getUserID() + )); + + if ($rows !== false && count($rows) > 0) { + return array_reduce($rows, function ($carry, $item) { + $carry [] = new Statistic($item); + return $carry; + }, array()); + } + return array(); + } + + /** + * Attempt to retrieve the group bys that are valid for the realm identified + * by the provided $realmName. + * + * @param string $realmName the string identifier to use when retrieving the group_by instances. + * + * @return array|GroupBy[] + * + * @throws Exception if the $realmName provided is null + */ + public static function getGroupBysForRealm($realmName) + { + if (null === $realmName) { + throw new Exception('A valid realm name must be provided. (null)'); + } + + $db = DB::factory('database'); + $query = <<< SQL +SELECT DISTINCT + gb.* +FROM group_bys gb + JOIN realms r ON gb.realm_id = r.realm_id +WHERE r.name = :realm_name +SQL; + $rows = $db->query($query, array( + ':realm_name' => $realmName + )); + if (count($rows) > 0) { + return array_reduce($rows, function ($carry, $item) { + $carry [] = new GroupBy($item); + return $carry; + }, array()); + } + return array(); + } + + /** + * Attempt to retrieve the descriptor param value specific to the provided + * user, acl and group_by. Note: if there is more than one param value that + * matches the parameters provided then only the first one ( as + * determined by natural table ordering ) will be returned by this function. + * + * @param XDUser $user the user to use when determining the param + * value + * @param string $aclName the name of the acl this descriptor param + * value is associated with + * @param string $groupByName the name of the group by this descriptor param + * value is associated with + * @return null|string null if the value is not found, else it's returned as + * a string + * @throws Exception if the user's userId is null + * @throws Exception if the provided acl name is null + * @throws Exception if the provided group by name is null + */ + public static function getDescriptorParamValue(XDUser $user, $aclName, $groupByName) + { + if (null == $user->getUserID()) { + throw new Exception('A valid user id must be supplied.'); + } + if (null === $aclName) { + throw new Exception('A valid acl name is required.'); + } + if (null === $groupByName) { + throw new Exception('A valid group by name is required.'); + } + $db = DB::factory('database'); + $query = <<query($query, array( + ':user_id' => $user->getUserID(), + ':acl_name' => $aclName, + ':group_by_name' => $groupByName + )); + if (count($rows) > 0) { + return $rows[0]['value']; + } + return null; + } + + /** + * Attempt to retrieve all descriptor param values for the provided user, + * acl and group by. + * + * @param XDUser $user the user to use when determining the param + * value + * @param string $aclName the name of the acl this descriptor param + * value is associated with + * @param string $groupByName the name of the group by this descriptor param + * value is associated with + * @return array|string[] + * @throws Exception if the user's userId is null + * @throws Exception if the aclName is null + * @throws Exception if the gropuByName is null + */ + public static function getDescriptorParamValues(XDUser $user, $aclName, $groupByName) + { + if (null == $user->getUserID()) { + throw new Exception('A valid user id must be supplied.'); + } + if (null === $aclName) { + throw new Exception('A valid acl name is required.'); + } + if (null === $groupByName) { + throw new Exception('A valid group by name is required.'); + } + + $query = <<query($query, array( + ':user_id' => $user->getUserID(), + ':acl_name' => $aclName, + ':group_by_name' => $groupByName + )); + if (count($rows) > 0) { + return array_reduce($rows, function ($carry, $item) { + $carry [] = $item['value']; + return $carry; + }, array()); + } + return array(); + } +} diff --git a/classes/Models/Statistic.php b/classes/Models/Statistic.php new file mode 100644 index 0000000000..9902c3b6b7 --- /dev/null +++ b/classes/Models/Statistic.php @@ -0,0 +1,44 @@ + 'statisticId', + 'module_id' => 'moduleId', + 'realm_id' => 'realmId', + 'name' => 'name', + 'display'=> 'display', + 'formula' => 'formula', + 'alias'=> 'alias', + 'unit' => 'unit', + 'decimals' => 'decimals', + 'description' => 'description', + 'visible' => 'visible' + ); +} diff --git a/classes/XDUser.php b/classes/XDUser.php index 1594ac9041..83017253a2 100644 --- a/classes/XDUser.php +++ b/classes/XDUser.php @@ -1,466 +1,482 @@ name] = $acl; + * @var Acl[] + */ + private $_acls; - $this->_pdo = DB::factory('database'); + /** + * A static reference to the public user. That is used as a singleton so + * that the public user need only be retrieved from the db once. Note that + * this is different from how the public user was previously used / + * utilized. Previously the public user only existed as an ephemeral object + * with no backing in the database. This was causing problems with the new + * Acl system ( having user -> acl relations explicitly defined ) so we + * now have a real (i.e. has a record in a table) public user w/ a real + * public acl. + * + * @var XDUser + */ + private static $_publicUser; - $userCheck = $this->_pdo->query("SELECT id FROM Users WHERE username=:username", array( - ':username' => $username, - )); + const PUBLIC_USER = 1; + const INTERNAL_USER = 2; - if (count($userCheck) > 0 && $username != NULL) { + // --------------------------- - $username = preg_replace('/^(.+);(.+)$/', '$1 ($2)', $username); + /* + * + * @constructor + * + * @param string $username + * @param string $password + * @param string $email_address + * @param string $first_name + * @param string $last_name + * @param array $role_set + * @param string $primary_role <--- reference to object returned from \User\aRole::factory(...) + * + */ - throw new Exception("User $username already exists"); + function __construct($username = NULL, $password = NULL, $email_address = NO_EMAIL_ADDRESS_SET, + $first_name = NULL, $middle_name = NULL, $last_name = NULL, + $role_set = array(ROLE_ID_USER), $primary_role = ROLE_ID_USER, $organization_id = NULL, $person_id = NULL + ) { - } + $this->_pdo = DB::factory('database'); - $this->_id = NULL; + $userCheck = $this->_pdo->query("SELECT id FROM Users WHERE username=:username", array( + ':username' => $username, + )); - $this->_account_is_active = true; + if (count($userCheck) > 0 && $username != NULL) { - $this->_username = $username; - $this->_password = $password; + $username = preg_replace('/^(.+);(.+)$/', '$1 ($2)', $username); - if (self::userExistsWithEmailAddress($email_address) != INVALID) { - throw new Exception("An XDMoD user with e-mail address $email_address exists"); - } + throw new Exception("User $username already exists"); - $this->_email = $email_address; + } - $this->_firstName = $first_name; - $this->_middleName = $middle_name; - $this->_lastName = $last_name; + $this->_id = NULL; - $this->_roles = $role_set; + $this->_account_is_active = true; - // Role Checking ==================== + $this->_username = $username; + $this->_password = $password; - if (count($this->_roles) == 0) { - throw new Exception("At least one role must be associated with this user"); - } + if (self::userExistsWithEmailAddress($email_address) != INVALID) { + throw new Exception("An XDMoD user with e-mail address $email_address exists"); + } - if ($this->_getFormalRoleName($primary_role) == NULL) { - throw new Exception("A valid primary role must be specified"); - } + $this->_email = $email_address; - foreach($this->_roles as $role) { + $this->_firstName = $first_name; + $this->_middleName = $middle_name; + $this->_lastName = $last_name; - if ($this->_getFormalRoleName($role) == NULL) { - throw new Exception("Unrecognized role $role"); - } + $this->setRoles($role_set); - } + // Role Checking ==================== - if (!in_array($primary_role, $this->_roles)) { - throw new Exception("Primary role $primary_role must be a member of the set of roles assigned to this user"); - } + if (count($this->_roles) == 0) { + throw new Exception("At least one role must be associated with this user"); + } - // ================================= + if ($this->_getFormalRoleName($primary_role) == NULL) { + throw new Exception("A valid primary role must be specified"); + } - $this->_timeCreated = date('Y-m-d H:i:s'); - $this->_timeUpdated = NULL; - $this->_timePasswordUpdated = NULL; + foreach ($this->_roles as $role) { - $this->_organizationID = $organization_id; + if ($this->_getFormalRoleName($role) == NULL) { + throw new Exception("Unrecognized role $role"); + } - // A person id of 0 is not allowed - $this->_personID = $person_id == 0 ? NULL : $person_id; //This user MUST have a person_id mapping + } - $this->_update_token = true; - $this->_token = NULL; + if (!in_array($primary_role, $this->_roles)) { + throw new Exception("Primary role $primary_role must be a member of the set of roles assigned to this user"); + } - // ================================= + // ================================= - $primary_role_name = $this->_getFormalRoleName($primary_role); + $this->_timeCreated = date('Y-m-d H:i:s'); + $this->_timeUpdated = NULL; + $this->_timePasswordUpdated = NULL; - // These roles cannot be used immediately after constructing a new XDUser (since a user id has not been defined at this point). - // If you are explicitly calling 'new XDUser(...)', saveUser() must be called on the newly created XDUser object before accessing - // these roles using getPrimaryRole() and getActiveRole() + $this->_organizationID = $organization_id; - $this->_primary_role = \User\aRole::factory($primary_role_name); - $this->_active_role = \User\aRole::factory($primary_role_name); + // A person id of 0 is not allowed + $this->_personID = $person_id == 0 ? NULL : $person_id; //This user MUST have a person_id mapping - }//construct + $this->_update_token = true; + $this->_token = NULL; - // --------------------------- + // ================================= - /* - * - * @function reloadUser (Retrieves updated information for the user from the database) - * - */ + $primary_role_name = $this->_getFormalRoleName($primary_role); - public function reloadUser() { + // These roles cannot be used immediately after constructing a new XDUser (since a user id has not been defined at this point). + // If you are explicitly calling 'new XDUser(...)', saveUser() must be called on the newly created XDUser object before accessing + // these roles using getPrimaryRole() and getActiveRole() - $this->getUserById($this->_id, $this); + $this->_primary_role = \User\aRole::factory($primary_role_name); + $this->_active_role = \User\aRole::factory($primary_role_name); + }//construct - }//reloadUser + // --------------------------- - // --------------------------- + /* + * + * @function reloadUser (Retrieves updated information for the user from the database) + * + */ - /* - * - * @function getProfile - * - * @return XDUserProfile - * @throws Exception if this user does not have an ID (due to the user data never being saved in the first place) - * e.g. A new user is created, yet not saved prior to calling getProfile() - * - */ + public function reloadUser() + { - public function getProfile() { + $this->getUserById($this->_id, $this); - if(!isset($this->_id)) { - throw new \Exception('This user must be saved first.'); - } + }//reloadUser - return new XDUserProfile($this->_id); + // --------------------------- - }//getProfile + /* + * + * @function getProfile + * + * @return XDUserProfile + * @throws Exception if this user does not have an ID (due to the user data never being saved in the first place) + * e.g. A new user is created, yet not saved prior to calling getProfile() + * + */ - // --------------------------- + public function getProfile() + { - /* - * - * @function userExistsWithUsername - * - * @param string $username - * - * @return int (if not INVALID, then the function returns the id of the respective account) - * - */ + if (!isset($this->_id)) { + throw new \Exception('This user must be saved first.'); + } - public static function userExistsWithUsername($username) { + return new XDUserProfile($this->_id); - $pdo = DB::factory('database'); + }//getProfile - $userCheck = $pdo->query("SELECT id FROM Users WHERE username=:username", array( - ':username' => $username, - )); + // --------------------------- - if (count($userCheck) > 0) { - return $userCheck[0]['id']; - } - else { - return INVALID; - } + /* + * + * @function userExistsWithUsername + * + * @param string $username + * + * @return int (if not INVALID, then the function returns the id of the respective account) + * + */ - }//userExistsWithUsername + public static function userExistsWithUsername($username) + { - // --------------------------- + $pdo = DB::factory('database'); - /* - * - * @function userExistsWithEmailAddress - * - * @param string $email_address - * @param boolean $pass_reset_mode (optional) - * - * $include_exception_addresses possible return values - * ------------------------------------------------------------------- - * FALSE positive value*, INVALID - * TRUE positive value*, INVALID, AMBIGUOUS - * - * (*) if a positive value is returned, then it is the id of the user holding that unique e-mail address - * - * @return int (if not INVALID or AMBIGUOUS, then the function returns the id of the respective account) - * (returns INVALID if no account is mapped to the e-mail address) - * (returns AMBIGUOUS if more than one account is mapped to the e-mail address) - * - */ + $userCheck = $pdo->query("SELECT id FROM Users WHERE username=:username", array( + ':username' => $username, + )); - public static function userExistsWithEmailAddress($email_address, $include_exception_addresses = FALSE) { + if (count($userCheck) > 0) { + return $userCheck[0]['id']; + } else { + return INVALID; + } - if ($email_address == NO_EMAIL_ADDRESS_SET){ + }//userExistsWithUsername - //Empty values for e-mail address are allowed - return INVALID; + // --------------------------- - } + /* + * + * @function userExistsWithEmailAddress + * + * @param string $email_address + * @param boolean $pass_reset_mode (optional) + * + * $include_exception_addresses possible return values + * ------------------------------------------------------------------- + * FALSE positive value*, INVALID + * TRUE positive value*, INVALID, AMBIGUOUS + * + * (*) if a positive value is returned, then it is the id of the user holding that unique e-mail address + * + * @return int (if not INVALID or AMBIGUOUS, then the function returns the id of the respective account) + * (returns INVALID if no account is mapped to the e-mail address) + * (returns AMBIGUOUS if more than one account is mapped to the e-mail address) + * + */ - $pdo = DB::factory('database'); + public static function userExistsWithEmailAddress($email_address, $include_exception_addresses = FALSE) + { - $user_check_query = "SELECT id FROM Users WHERE email_address=:email_address AND user_type != :user_type"; + if ($email_address == NO_EMAIL_ADDRESS_SET) { - if ($include_exception_addresses == FALSE){ + //Empty values for e-mail address are allowed + return INVALID; - // If a user is attempting to reset their password based on their e-mail address, it is important that - // the e-mail address does NOT map to more than one account (we cannot deal with multiple users mapped - // to a common e-mail address). $include_exception_addresses is set to TRUE only in the pass_reset - // controller of user_auth -- which would not append the following to the SELECT query: + } - $user_check_query .= " AND email_address NOT IN (SELECT email_address FROM ExceptionEmailAddresses)"; + $pdo = DB::factory('database'); - } + $user_check_query = "SELECT id FROM Users WHERE email_address=:email_address AND user_type != :user_type"; - // We don't want to acknowledge XSEDE-derived accounts... + if ($include_exception_addresses == FALSE) { - $userCheck = $pdo->query( - $user_check_query, - array( - 'email_address' => $email_address, - 'user_type' => XSEDE_USER_TYPE - ) - ); + // If a user is attempting to reset their password based on their e-mail address, it is important that + // the e-mail address does NOT map to more than one account (we cannot deal with multiple users mapped + // to a common e-mail address). $include_exception_addresses is set to TRUE only in the pass_reset + // controller of user_auth -- which would not append the following to the SELECT query: - if (count($userCheck) == 1) { - return $userCheck[0]['id']; - } - elseif (count($userCheck) > 1) { + $user_check_query .= " AND email_address NOT IN (SELECT email_address FROM ExceptionEmailAddresses)"; - // E-mail address maps to more than one account (present in ExceptionEmailAddresses table) - return AMBIGUOUS; + } - } - else { + // We don't want to acknowledge XSEDE-derived accounts... - // No user maps to $email_address - return INVALID; + $userCheck = $pdo->query( + $user_check_query, + array( + 'email_address' => $email_address, + 'user_type' => XSEDE_USER_TYPE + ) + ); - } + if (count($userCheck) == 1) { + return $userCheck[0]['id']; + } elseif (count($userCheck) > 1) { - }//userExistsWithEmailAddress + // E-mail address maps to more than one account (present in ExceptionEmailAddresses table) + return AMBIGUOUS; - // --------------------------- + } else { - /* - * - * @function getFieldOfScience - * - * @return int - * - */ + // No user maps to $email_address + return INVALID; - public function getFieldOfScience() { + } - return $this->_field_of_science; + }//userExistsWithEmailAddress - }//getFieldOfScience + // --------------------------- - // --------------------------- + /* + * + * @function getFieldOfScience + * + * @return int + * + */ - /* - * - * @function setFieldOfScience - * - * @param int $field_of_science - * - */ + public function getFieldOfScience() + { - public function setFieldOfScience($field_of_science) { + return $this->_field_of_science; - $this->_field_of_science = $field_of_science; + }//getFieldOfScience - }//setFieldOfScience + // --------------------------- - // --------------------------- + /* + * + * @function setFieldOfScience + * + * @param int $field_of_science + * + */ - /* - * - * @function getUserByToken - * - * @param string $token - * - * @return XDUser if $token maps to a user - * @return NULL if $token does not map to a user - * - */ + public function setFieldOfScience($field_of_science) + { - public static function getUserByToken ($token) { + $this->_field_of_science = $field_of_science; - $pdo = DB::factory('database'); + }//setFieldOfScience - $userCheck = $pdo->query("SELECT id FROM Users WHERE token LIKE BINARY :token", array( - ':token' => $token, - )); + // --------------------------- - if (count($userCheck) == 0) { - return NULL; - } + /* + * + * @function getUserByToken + * + * @param string $token + * + * @return XDUser if $token maps to a user + * @return NULL if $token does not map to a user + * + */ - return self::getUserByID($userCheck[0]['id']); + public static function getUserByToken($token) + { - }//getUserByToken + $pdo = DB::factory('database'); - // --------------------------- + $userCheck = $pdo->query("SELECT id FROM Users WHERE token LIKE BINARY :token", array( + ':token' => $token, + )); - /* - * - * @function getPublicUser - * - * - */ + if (count($userCheck) == 0) { + return NULL; + } - public static function getPublicUser() { + return self::getUserByID($userCheck[0]['id']); - $user = new self ( - 'Public User', // Username - NULL, // Password - NO_EMAIL_ADDRESS_SET, // E-Mail Address - 'Public', // First Name - '', // Middle Name - 'User', // Last Name - array(ROLE_ID_PUBLIC), // Role Set - ROLE_ID_PUBLIC, // Primary Role - NULL, // Organization ID - NULL // Person ID - ); + }//getUserByToken - //$user->setActiveRole(ROLE_ID_PUBLIC); - //$user->setPrimaryRole(ROLE_ID_PUBLIC); + // --------------------------- - return $user; + /** + * Attempt to retrieve an XDUser instance representation of the Public User. + * If, for some reason the Public User has not been created then this + * function will return null. + * cl + * @return null|XDUser + */ + public static function getPublicUser() + { + if (null === self::$_publicUser) { + self::$_publicUser = self::getUserByUserName('Public User'); + } + return self::$_publicUser; }//getPublicUser - // --------------------------- + // --------------------------- /** * Check if this user is a public user. * * @return boolean If this user is a public user, true. Otherwise, false. */ - public function isPublicUser() { - return $this->getPrimaryRole()->getIdentifier() === ROLE_ID_PUBLIC; + public function isPublicUser() + { + return array_key_exists(ROLE_ID_PUBLIC, $this->_acls); } - // --------------------------- + // --------------------------- - /* - * - * @function getUserByID - * - * @param int $uid - * @param XDUser REF $targetInstance (If NOT NULL, then re-populate $targetInstance with values) - * - * @return XDUser (If &$targetInstance IS NOT NULL, then this function can be treated as void) - * (If &$targetInstance IS NULL, then this function should be used as follows: $user = getUserByID(...)) - * - */ + /* + * + * @function getUserByID + * + * @param int $uid + * @param XDUser REF $targetInstance (If NOT NULL, then re-populate $targetInstance with values) + * + * @return XDUser (If &$targetInstance IS NOT NULL, then this function can be treated as void) + * (If &$targetInstance IS NULL, then this function should be used as follows: $user = getUserByID(...)) + * + */ - public static function getUserByID($uid, &$targetInstance = NULL) { + public static function getUserByID($uid, &$targetInstance = NULL) + { - $pdo = DB::factory('database'); + $pdo = DB::factory('database'); - $userCheck = $pdo->query(" + $userCheck = $pdo->query(" SELECT username, password, email_address, first_name, middle_name, last_name, time_created, time_last_updated, password_last_updated, account_is_active, organization_id, person_id, field_of_science, token, user_type FROM Users WHERE id=:id ", array( - ':id' => $uid, - )); + ':id' => $uid, + )); - if (count($userCheck) == 0) { - return NULL; - } + if (count($userCheck) == 0) { + return NULL; + } - $user = ($targetInstance == NULL) ? new self : $targetInstance; + $user = ($targetInstance == NULL) ? new self : $targetInstance; - if ($targetInstance == NULL) { - // If requesting another user object, make sure to not update the user's token unless - // issueNewToken() is explicitly invoked (we don't want to update the user's token by default upon calling saveUser()) - $user->_update_token = false; - } + if ($targetInstance == NULL) { + // If requesting another user object, make sure to not update the user's token unless + // issueNewToken() is explicitly invoked (we don't want to update the user's token by default upon calling saveUser()) + $user->_update_token = false; + } - $user->_id = $uid; + $user->_id = $uid; - $user->_account_is_active = ($userCheck[0]['account_is_active'] == '1'); + $user->_account_is_active = ($userCheck[0]['account_is_active'] == '1'); - $user->_username = $userCheck[0]['username']; - $user->_password = $userCheck[0]['password']; + $user->_username = $userCheck[0]['username']; + $user->_password = $userCheck[0]['password']; - $user->_email = $userCheck[0]['email_address']; + $user->_email = $userCheck[0]['email_address']; - $user->_firstName = $userCheck[0]['first_name']; - $user->_middleName = $userCheck[0]['middle_name']; - $user->_lastName = $userCheck[0]['last_name']; + $user->_firstName = $userCheck[0]['first_name']; + $user->_middleName = $userCheck[0]['middle_name']; + $user->_lastName = $userCheck[0]['last_name']; - $user->_timeCreated = $userCheck[0]['time_created']; - $user->_timeUpdated = $userCheck[0]['time_last_updated']; - $user->_timePasswordUpdated = $userCheck[0]['password_last_updated']; + $user->_timeCreated = $userCheck[0]['time_created']; + $user->_timeUpdated = $userCheck[0]['time_last_updated']; + $user->_timePasswordUpdated = $userCheck[0]['password_last_updated']; - $user->_organizationID = $userCheck[0]['organization_id']; - $user->_personID = $userCheck[0]['person_id']; + $user->_organizationID = $userCheck[0]['organization_id']; + $user->_personID = $userCheck[0]['person_id']; - $user->_field_of_science = $userCheck[0]['field_of_science']; - $user->_token = $userCheck[0]['token']; + $user->_field_of_science = $userCheck[0]['field_of_science']; + $user->_token = $userCheck[0]['token']; - // datatypes are not passed back unless using prepared statements so force to int - // See: http://stackoverflow.com/questions/1197005/how-to-get-numeric-types-from-mysql-using-pdo - $user->_user_type = (int) $userCheck[0]['user_type']; + // datatypes are not passed back unless using prepared statements so force to int + // See: http://stackoverflow.com/questions/1197005/how-to-get-numeric-types-from-mysql-using-pdo + $user->_user_type = (int)$userCheck[0]['user_type']; - $user->_roles = array(); + $user->_roles = array(); - $rolesResult = $pdo->query(" + $rolesResult = $pdo->query(" SELECT r.abbrev, r.description, @@ -473,283 +489,318 @@ public static function getUserByID($uid, &$targetInstance = NULL) { LEFT JOIN UserRoleParameters AS urp ON ur.user_id = urp.user_id AND ur.role_id = urp.role_id WHERE ur.user_id = :user_id ", array( - ':user_id' => $user->_id, - )); + ':user_id' => $user->_id, + )); + + foreach ($rolesResult as $roleSet) { + + if (!in_array($roleSet['abbrev'], $user->_roles)) { + $user->_roles[] = $roleSet['abbrev']; + } + + if ($roleSet['is_primary'] == '1') { + $user->_primary_role = \User\aRole::factory($roleSet['description']); + $user->_primary_role->configure($user, $roleSet['param_value']); + } - foreach($rolesResult as $roleSet) { + if ($roleSet['is_active'] == '1') { + $user->_active_role = \User\aRole::factory($roleSet['description']); + $user->_active_role->configure($user, $roleSet['param_value']); + } - if (!in_array($roleSet['abbrev'], $user->_roles)) { - $user->_roles[] = $roleSet['abbrev']; - } + }//foreach + + // BEGIN: ACL population + $query = <<query( + $query, + array( + 'user_id' => $uid + ) + ); - if ($roleSet['is_primary'] == '1') { - $user->_primary_role = \User\aRole::factory($roleSet['description']); - $user->_primary_role->configure($user, $roleSet['param_value']); - } - if ($roleSet['is_active'] == '1') { - $user->_active_role = \User\aRole::factory($roleSet['description']); - $user->_active_role->configure($user, $roleSet['param_value']); - } + $acls = array_reduce($results, function ($carry, $item) { + $acl = new Acl($item); + $carry [$acl->getName()] = $acl; + return $carry; + }, array()); - }//foreach + $user->setAcls($acls); + // END: ACL population - return $user; + return $user; - }//getUserByID + }//getUserByID - // --------------------------- + // --------------------------- - /* - * - * @function setPassword - * - * @param string $raw_password - * - */ + /* + * + * @function setPassword + * + * @param string $raw_password + * + */ - public function setPassword($raw_password) { + public function setPassword($raw_password) + { - return $this->_password = $raw_password; + return $this->_password = $raw_password; - }//setPassword + }//setPassword - // --------------------------- + // --------------------------- - /* - * - * @function getUsername - * - * @return string - * - */ + /* + * + * @function getUsername + * + * @return string + * + */ - public function getUsername() { + public function getUsername() + { - return $this->_username; + return $this->_username; - }//getUsername + }//getUsername - // --------------------------- + // --------------------------- - /* - * - * @function isDeveloper - * - * @return boolean - * - */ + /* + * + * @function isDeveloper + * + * @return boolean + * + */ - public function isDeveloper() { + public function isDeveloper() + { - return (in_array(ROLE_ID_DEVELOPER, $this->getRoles())); + return (in_array(ROLE_ID_DEVELOPER, $this->_acls)); - }//isDeveloper + }//isDeveloper - // --------------------------- + // --------------------------- - /* - * - * @function isManager - * - * @return boolean - * - */ + /* + * + * @function isManager + * + * @return boolean + * + */ - public function isManager() { + public function isManager() + { - return (in_array(ROLE_ID_MANAGER, $this->getRoles())); + return array_key_exists(ROLE_ID_MANAGER, $this->_acls); - }//isManager + }//isManager - // --------------------------- + // --------------------------- - /* - * - * @function isPrincipalInvestigator - * - * @param int $person_id - * - * @return boolean - * - */ + /* + * + * @function isPrincipalInvestigator + * + * @param int $person_id + * + * @return boolean + * + */ - public static function isPrincipalInvestigator($person_id) { + public static function isPrincipalInvestigator($person_id) + { - $pdo = DB::factory('database'); + $pdo = DB::factory('database'); - $piCheck = $pdo->query( - "SELECT person_id FROM modw.piperson WHERE person_id=:person_id", - array('person_id' => $person_id) - ); + $piCheck = $pdo->query( + "SELECT person_id FROM modw.piperson WHERE person_id=:person_id", + array('person_id' => $person_id) + ); - return (count($piCheck) == 1); + return (count($piCheck) == 1); - }//isPrincipalInvestigator + }//isPrincipalInvestigator - // --------------------------- + // --------------------------- - /* - * - * @function isCampusChampion - * - * @param int $person_id - * - * @returns false (boolean) if the person referenced by person_id is NOT a campus champion - * @returns the numerical organization id (int) if the person IS a campus champion - * - */ + /* + * + * @function isCampusChampion + * + * @param int $person_id + * + * @returns false (boolean) if the person referenced by person_id is NOT a campus champion + * @returns the numerical organization id (int) if the person IS a campus champion + * + */ - public static function isCampusChampion($person_id) { + public static function isCampusChampion($person_id) + { - $pdo = DB::factory('database'); + $pdo = DB::factory('database'); - $ccCheck = $pdo->query( + $ccCheck = $pdo->query( - "SELECT DISTINCT acct.id, acct.granttype_id + "SELECT DISTINCT acct.id, acct.granttype_id FROM modw.account AS acct, modw.peopleonaccount AS poa WHERE poa.person_id=:person_id AND acct.id = poa.account_id AND acct.granttype_id = 2", - array('person_id' => $person_id) + array('person_id' => $person_id) - ); + ); - if (count($ccCheck) > 0) { + if (count($ccCheck) > 0) { - $orgCheck = $pdo->query("SELECT organization_id FROM modw.person WHERE id=:person_id", array('person_id' => $person_id)); + $orgCheck = $pdo->query("SELECT organization_id FROM modw.person WHERE id=:person_id", array('person_id' => $person_id)); - return $orgCheck[0]['organization_id']; + return $orgCheck[0]['organization_id']; - } - else { + } else { - return false; + return false; - } + } - }//isCampusChampion + }//isCampusChampion - // --------------------------- + // --------------------------- - /* - * - * @function authenticate - * - * This function may only be used to authenticate users that have local user - * account credentials. Users must have non-empty usernames and passwords. - * - * @param string $uname - * @param string $pass <-- MD5 hash - * - * @return XDUser - * - */ + /* + * + * @function authenticate + * + * This function may only be used to authenticate users that have local user + * account credentials. Users must have non-empty usernames and passwords. + * + * @param string $uname + * @param string $pass <-- MD5 hash + * + * @return XDUser + * + */ - public static function authenticate($uname, $pass) { + public static function authenticate($uname, $pass) + { - if(strlen($uname) == 0 || strlen($pass) == 0) { - return NULL; - } + if (strlen($uname) == 0 || strlen($pass) == 0) { + return NULL; + } - $pdo = DB::factory('database'); + $pdo = DB::factory('database'); - $userCheck = $pdo->query("SELECT id + $userCheck = $pdo->query("SELECT id FROM Users WHERE username=:username AND password=MD5(:password) AND user_type NOT IN (:xsede_user_type, :federated_user_type)", - array( - 'username' => $uname, - 'password' => $pass, - 'xsede_user_type' => XSEDE_USER_TYPE, - 'federated_user_type' => FEDERATED_USER_TYPE - )); - if (count($userCheck) == 0) { - return NULL; - } - return self::getUserByID($userCheck[0]['id']); - - }//authenticate - - // --------------------------- - - /* - * - * @function isAuthenticated - * - * @param XDUser $user - * - * @return boolean - * - */ - - public static function isAuthenticated($user){ - return ($user != NULL); - } - - // --------------------------- - - /* - * - * @function issueNewToken - * - */ - - public function issueNewToken() { - $this->_update_token = true; - } - - // --------------------------- + array( + 'username' => $uname, + 'password' => $pass, + 'xsede_user_type' => XSEDE_USER_TYPE, + 'federated_user_type' => FEDERATED_USER_TYPE + ) + ); + if (count($userCheck) == 0) { + return NULL; + } + return self::getUserByID($userCheck[0]['id']); + + }//authenticate + + // --------------------------- + + /* + * + * @function isAuthenticated + * + * @param XDUser $user + * + * @return boolean + * + */ + + public static function isAuthenticated($user) + { + return ($user != NULL); + } + + // --------------------------- + + /* + * + * @function issueNewToken + * + */ + + public function issueNewToken() + { + $this->_update_token = true; + } + + // --------------------------- + /** * Returns a parameterized Update query for the 'User' table. If the * $updateToken parameter is set then it includes the 'token' * and the 'token_expiration' fields. * - * @param bool $updateToken signifies whether or not to include the 'token' + * @param bool $updateToken signifies whether or not to include the 'token' * related columns in the return value. - * @param bool $includePassword signifies whether or not to include the * 'password' related columns in the return value. * * @return string a parameterized query for the 'User' table */ - public function getUpdateQuery( $updateToken = false, $includePassword = false ) + public function getUpdateQuery($updateToken = false, $includePassword = false) { $result = 'UPDATE moddb.Users SET username = :username, email_address = :email_address, first_name = :first_name, middle_name = :middle_name, last_name = :last_name, account_is_active = :account_is_active, person_id = :person_id, organization_id = :organization_id, field_of_science = :field_of_science, user_type = :user_type WHERE id = :id'; - if ( $updateToken && $includePassword ) { + if ($updateToken && $includePassword) { $result = 'UPDATE moddb.Users SET username = :username, password = :password, email_address = :email_address, first_name = :first_name, middle_name = :middle_name, last_name = :last_name, account_is_active = :account_is_active, person_id = :person_id, organization_id = :organization_id, field_of_science = :field_of_science, token = :token, user_type = :user_type, password_last_updated = :password_last_updated WHERE id = :id'; - } else if ( !$updateToken && $includePassword ) { + } else if (!$updateToken && $includePassword) { $result = 'UPDATE moddb.Users SET username = :username, password = :password, email_address = :email_address, first_name = :first_name, middle_name = :middle_name, last_name = :last_name, account_is_active = :account_is_active, person_id = :person_id, organization_id = :organization_id, field_of_science = :field_of_science, user_type = :user_type, password_last_updated = :password_last_updated WHERE id = :id'; - } else if ( $updateToken && !$includePassword ) { + } else if ($updateToken && !$includePassword) { $result = 'UPDATE moddb.Users SET username = :usernam, email_address = :email_address, first_name = :first_name, middle_name = :middle_name, last_name = :last_name, account_is_active = :account_is_active, person_id = :person_id, organization_id = :organization_id, field_of_science = :field_of_science, token = :token, user_type = :user_type WHERE id = :id'; } return $result; } - /** - * Returns a parameterized Insert query for the 'User' table. If the - * $updateToken parameter is set then it includes the 'token' - * and the 'token_expiration' fields. - * - * @param bool $updateToken signifies whether or not to include the 'token' - * related columns in the return value. - * @param bool $includePassword signifies whether or not to include the - * 'password' related columns in the return value. - * - * @return string a parameterized query for the 'User' table - */ - public function getInsertQuery( $updateToken = false, $includePassword = false ) - { + /** + * Returns a parameterized Insert query for the 'User' table. If the + * $updateToken parameter is set then it includes the 'token' + * and the 'token_expiration' fields. + * + * @param bool $updateToken signifies whether or not to include the 'token' + * related columns in the return value. + * @param bool $includePassword signifies whether or not to include the + * 'password' related columns in the return value. + * + * @return string a parameterized query for the 'User' table + */ + public function getInsertQuery($updateToken = false, $includePassword = false) + { $result = 'INSERT INTO moddb.Users (username, email_address, first_name, middle_name, last_name, account_is_active, person_id, organization_id, field_of_science, user_type) VALUES (:username, :email_address, :first_name, :middle_name, :last_name, :account_is_active, :person_id, :organization_id, :field_of_science, :user_type)'; - if ( $updateToken && $includePassword ) { + if ($updateToken && $includePassword) { $result = 'INSERT INTO moddb.Users (username, password, password_last_updated, email_address, first_name, middle_name, last_name, account_is_active, person_id, organization_id, field_of_science, token, user_type) VALUES (:username, :password, :password_last_updated, :email_address, :first_name, :middle_name, :last_name, :account_is_active, :person_id, :organization_id, :field_of_science, :token, :user_type)'; - } else if ( !$updateToken && $includePassword ) { + } else if (!$updateToken && $includePassword) { $result = 'INSERT INTO moddb.Users (username, password, password_last_updated, email_address, first_name, middle_name, last_name, account_is_active, person_id, organization_id, field_of_science, user_type) VALUES (:username, :password, :password_last_updated, :email_address, :first_name, :middle_name, :last_name, :account_is_active, :person_id, :organization_id, :field_of_science, :user_type)'; - } else if ( $updateToken && !$includePassword ) { + } else if ($updateToken && !$includePassword) { $result = 'INSERT INTO moddb.Users (username, email_address, first_name, middle_name, last_name, account_is_active, person_id, organization_id, field_of_science, token, user_type) VALUES (:username, :email_address, :first_name, :middle_name, :last_name, :account_is_active, :person_id, :organization_id, :field_of_science, :token, :user_type)'; } return $result; - } + } /** * Accepts an array and outputs a meaningful string representation of said @@ -759,12 +810,12 @@ public function getInsertQuery( $updateToken = false, $includePassword = false ) * * @return string representation of the array parameter passed in. */ - public function arrayToString($array = array() ) + public function arrayToString($array = array()) { $result = 'Keys [ '; - $result .= implode(', ', array_keys($array)) .']'; + $result .= implode(', ', array_keys($array)) . ']'; $result .= 'Values [ '; - $result .= implode(', ', array_values($array)) .']'; + $result .= implode(', ', array_values($array)) . ']'; return $result; } @@ -779,7 +830,7 @@ public function arrayToString($array = array() ) public function saveUser() { /* BEGIN: VALIDATION */ - if ($this->_active_role->getIdentifier() == ROLE_ID_PUBLIC) { + if ($this->isPublicUser()) { throw new \Exception('The public role user cannot be saved.'); } @@ -802,8 +853,7 @@ public function saveUser() // holds a valid id, then an already saved user has the e-mail address. throw new Exception("An XDMoD user with e-mail address {$this->_email} exists"); - } - else { + } else { // This user has been saved, so we make sure the $id_of_user_holding_email_address is in fact this user's // id... otherwise throw the exception @@ -823,20 +873,18 @@ public function saveUser() $forUpdate = isset($this->_id); /* BEGIN: Query Data Population */ - if ( $forUpdate ) { + if ($forUpdate) { $update_data['id'] = $this->_id; } $update_data['username'] = $this->_username; - $includePassword = strlen($this->_password) <= CHARLIM_PASSWORD ; + $includePassword = strlen($this->_password) <= CHARLIM_PASSWORD; if ($includePassword) { - if($this->_password == "" || is_null($this->_password)) - { - $update_data['password'] = NULL; - } - else { - $update_data['password'] = md5($this->_password); - } - $update_data['password_last_updated'] = 'NOW()'; + if ($this->_password == "" || is_null($this->_password)) { + $update_data['password'] = NULL; + } else { + $update_data['password'] = md5($this->_password); + } + $update_data['password_last_updated'] = 'NOW()'; } $update_data['email_address'] = ($this->_email); $update_data['first_name'] = ($this->_firstName); @@ -865,7 +913,8 @@ public function saveUser() /* BEGIN: Execute the query */ if ($forUpdate) { - /* $rowCount = */$this->_pdo->execute($query, $update_data); + /* $rowCount = */ + $this->_pdo->execute($query, $update_data); } else { // NOTE: There may be a better way to do this (atomicity issue) ? $new_user_id = $this->_pdo->insert($query, $update_data); @@ -873,7 +922,7 @@ public function saveUser() $this->_id = $new_user_id; } } catch (\Exception $e) { - throw new Exception("Exception occured while inserting / updating. UpdateToken: [{$this->_update_token}] Query: [$query] data: [{$this->arrayToString($update_data)}]",null, $e); + throw new Exception("Exception occured while inserting / updating. UpdateToken: [{$this->_update_token}] Query: [$query] data: [{$this->arrayToString($update_data)}]", null, $e); } /* END: Execute the query */ @@ -882,12 +931,34 @@ public function saveUser() // Set token to expire in 30 days from now... $this->_pdo->execute( 'UPDATE Users SET token_expiration=DATE_ADD(NOW(), INTERVAL 30 DAY) WHERE id=:id', - array( 'id' => $this->_id ) + array('id' => $this->_id) ); $this->_update_token = false; } /* END: Update Token Information */ + /* BEGIN: ACL data processing */ + + // REMOVE: existing user -> acl relations + $this->_pdo->execute( + 'DELETE FROM user_acls WHERE user_id = :user_id', + array('user_id' => $this->_id) + ); + + // ADD: current user -> acl relations + foreach ($this->_acls as $acl) { + if (null !== $acl->getAclId()) { + $this->_pdo->execute( + 'INSERT INTO user_acls(user_id, acl_id) VALUES(:user_id, :acl_id)', + array( + 'user_id' => $this->_id, + 'acl_id' => $acl->getAclId() + ) + ); + } + } + /* END: ACL data processing */ + /* BEGIN: UserRole Updating */ // Rebuild roles data for user -------------- @@ -901,18 +972,18 @@ public function saveUser() $this->_pdo->execute( "INSERT INTO UserRoles VALUES(:id, :roleId, '0', '0')", array('id' => $this->_id, - 'roleId' => $roleId) + 'roleId' => $roleId) ); } $primaryRoleId = $this->_getRoleID($this->_primary_role->getIdentifier()); $this->_pdo->execute( "UPDATE UserRoles SET is_primary='1' WHERE user_id=:id AND role_id=:roleId", - array('id' => $this->_id, 'roleId' => $primaryRoleId ) + array('id' => $this->_id, 'roleId' => $primaryRoleId) ); // If the updater (e.g. Manager) has pulled out the (recently) active role for this user, reassign the active role to the primary role. - $active_role_id = ( in_array($this->_active_role->getIdentifier(), $this->_roles) ) ? + $active_role_id = (in_array($this->_active_role->getIdentifier(), $this->_roles)) ? $this->_getRoleID($this->_active_role->getIdentifier()) : $primaryRoleId; @@ -942,1879 +1013,2185 @@ public function saveUser() }//saveUser - // --------------------------- + // --------------------------- - /* - * - * @function getLastLoginTimestamp - * - * @return string - * - */ + /* + * + * @function getLastLoginTimestamp + * + * @return string + * + */ - public function getLastLoginTimestamp() { + public function getLastLoginTimestamp() + { - $results = $this->_pdo->query("SELECT init_time FROM SessionManager WHERE user_id=:user_id ORDER BY init_time DESC LIMIT 1", array( - ':user_id' => $this->_id, - )); + $results = $this->_pdo->query("SELECT init_time FROM SessionManager WHERE user_id=:user_id ORDER BY init_time DESC LIMIT 1", array( + ':user_id' => $this->_id, + )); - if (count($results) == 0) { return "Never logged in"; } + if (count($results) == 0) { + return "Never logged in"; + } - $init_time = $results[0]['init_time']; + $init_time = $results[0]['init_time']; - $time_frags = explode('.', $init_time); + $time_frags = explode('.', $init_time); - return date('m/d/Y, g:i:s A', $time_frags[0]); + return date('m/d/Y, g:i:s A', $time_frags[0]); - }//getLastLoginTimestamp + }//getLastLoginTimestamp - // --------------------------- + // --------------------------- - /* - * - * @function getToken - * - * @return string - * - */ + /* + * + * @function getToken + * + * @return string + * + */ - public function getToken() { + public function getToken() + { - if ($this->_active_role->getIdentifier() == ROLE_ID_PUBLIC) { - return ''; - } + if ($this->isPublicUser()) { + return ''; + } - $tokenResults = $this->_pdo->query("SELECT token FROM Users WHERE id=:id", array( - ':id' => $this->_id, - )); + $tokenResults = $this->_pdo->query("SELECT token FROM Users WHERE id=:id", array( + ':id' => $this->_id, + )); - return $tokenResults[0]['token']; + return $tokenResults[0]['token']; - }//getToken + }//getToken - // --------------------------- + // --------------------------- - /* - * - * @function getTokenExpiration - * - * @return string - * - */ + /* + * + * @function getTokenExpiration + * + * @return string + * + */ - public function getTokenExpiration() { + public function getTokenExpiration() + { - if ($this->_active_role->getIdentifier() == ROLE_ID_PUBLIC) { - return ''; - } + if ($this->isPublicUser()) { + return ''; + } - $tokenResults = $this->_pdo->query("SELECT token_expiration FROM Users WHERE id=:id", array( - ':id' => $this->_id, - )); + $tokenResults = $this->_pdo->query("SELECT token_expiration FROM Users WHERE id=:id", array( + ':id' => $this->_id, + )); - return $tokenResults[0]['token_expiration']; + return $tokenResults[0]['token_expiration']; - }//getTokenExpiration + }//getTokenExpiration - // --------------------------- + // --------------------------- - /* - * - * @function _getRoleID - * - * @param string $role_abbrev - * - * @return int - * - */ + /* + * + * @function _getRoleID + * + * @param string $role_abbrev + * + * @return int + * + */ - private function _getRoleID($role_abbrev) { + private function _getRoleID($role_abbrev) + { - $roleResults = $this->_pdo->query("SELECT role_id FROM Roles WHERE abbrev=:abbrev", array( - ':abbrev' => $role_abbrev, - )); + $roleResults = $this->_pdo->query("SELECT role_id FROM Roles WHERE abbrev=:abbrev", array( + ':abbrev' => $role_abbrev, + )); - return $roleResults[0]['role_id']; + return $roleResults[0]['role_id']; - }//_getRoleID + }//_getRoleID - // --------------------------- + // --------------------------- - /* - * - * @function removeUser - * - */ + /* + * + * @function removeUser + * + */ - public function removeUser() { + public function removeUser() + { - if ($this->_active_role->getIdentifier() == ROLE_ID_PUBLIC) { - throw new \Exception('Cannot remove public user'); - } + if ($this->isPublicUser()) { + throw new \Exception('Cannot remove public user'); + } - // Clean up any report-based data generated by the user - $this->_pdo->execute("DELETE FROM ChartPool WHERE user_id=:user_id", array( - ':user_id' => $this->_id, - )); - $this->_pdo->execute("DELETE FROM Reports WHERE user_id=:user_id", array( - ':user_id' => $this->_id, - )); - $this->_pdo->execute("DELETE FROM ReportCharts WHERE user_id=:user_id", array( - ':user_id' => $this->_id, - )); - - $this->_pdo->execute("DELETE FROM UserRoleParameters WHERE user_id=:user_id", array( - ':user_id' => $this->_id, - )); - $this->_pdo->execute("DELETE FROM UserRoles WHERE user_id=:user_id", array( - ':user_id' => $this->_id, - )); - - // Reset any associations to dependent users - $this->_pdo->execute("UPDATE UserRoleParameters SET promoter='-1' WHERE promoter=:promoter", array( - ':promoter' => $this->_id, - )); - - $this->_pdo->execute("DELETE FROM Users WHERE id=:id", array( - ':id' => $this->_id, - )); - - }//removeUser - - // --------------------------- - - /* - * - * @function getUserType; - * - * @return int (maps to one of the TYPE_* class constants at the top of this file) - * - */ - - public function getUserType() { - return $this->_user_type; - } - - // --------------------------- - - /* - * - * @function setUserType; - * - * @param int $userType - * - */ - - public function setUserType($userType) { - $this->_user_type = $userType; - } - - // --------------------------- - - /* - * - * @function getAccountStatus; - * - * @return boolean - * - */ - - public function getAccountStatus() { - return $this->_account_is_active; - } - - // --------------------------- - - /* - * - * @function setAccountStatus; - * - * @param boolean $status - * - */ - - public function setAccountStatus($status) { - $this->_account_is_active = $status; - } - - // --------------------------- - - /* - * - * @function getEmailAddress - * - * @return string - * - */ - - public function getEmailAddress() { - return $this->_email; - } - - // --------------------------- - - /* - * - * @function setEmailAddress - * - * @param string $email_address - * - */ - - public function setEmailAddress($email_address) { - $this->_email = $email_address; - } - - // --------------------------- - - /* - * - * @function getFormalName - * - * @return string - * - */ - - public function getFormalName($includeMiddleName = false) { - $formalName = $this->_firstName; - if ($includeMiddleName) { - $formalName .= ' ' . $this->_middleName; - } - $formalName .= ' ' . $this->_lastName; - return $formalName; - } - - // --------------------------- - - /* - * - * @function getFirstName - * - * @return string - * - */ - - public function getFirstName() { - return $this->_firstName; - } - - // --------------------------- - - /* - * - * @function setFirstName - * - * @param string $firstName - * - */ - - public function setFirstName($firstName) { - $this->_firstName = $firstName; - } - - // --------------------------- - - /* - * - * @function getLastName - * - * @return string - * - */ - - public function getLastName() { - return $this->_lastName; - } - - // --------------------------- - - /* - * - * @function setLastName - * - * @param string $lastName - * - */ - - public function setLastName($lastName) { - $this->_lastName = $lastName; - } - - // --------------------------- - - /* - * - * @function enumAllAvailableRoles - * - * @param int $organization_id - * - * - */ - - public function enumAllAvailableRoles() { - - if (empty($this->_id)) { - - // It is likely that the public user ended up here - return array(); - - } - - // Program Officer - - $role_query_1 = "SELECT r.description, r.abbrev AS param_value, urp.is_primary, urp.is_active " . - "FROM moddb.UserRoles AS urp, moddb.Roles AS r " . - "WHERE r.role_id = urp.role_id AND user_id=:user_id " . - "AND r.description = 'Program Officer'"; - $role_query_1_params = array( - ':user_id' => $this->_id, - ); - - // Center Director and Center Staff - - $role_query_2 = "SELECT CONCAT(r.description, ' - ', o.abbrev) AS description, CONCAT(r.abbrev, ':', urp.param_value) AS param_value, urp.is_primary, urp.is_active " . - "FROM moddb.UserRoleParameters AS urp, moddb.Roles AS r, modw.organization AS o " . - "WHERE urp.param_value = o.id AND r.role_id = urp.role_id AND urp.user_id=:user_id AND r.description != 'Campus Champion'" . - "ORDER BY r.description, o.abbrev"; - $role_query_2_params = array( - ':user_id' => $this->_id, - ); - - // Campus Champion - - $role_query_3 = "SELECT CONCAT(r.description, ' - ', o.name) AS description, CONCAT(r.abbrev, ':', urp.param_value) AS param_value, urp.is_primary, ur.is_active " . - "FROM moddb.UserRoleParameters AS urp, moddb.UserRoles AS ur, moddb.Roles AS r, modw.organization AS o " . - "WHERE urp.param_value = o.id AND ur.role_id = r.role_id AND ur.user_id =:ur_user_id AND r.role_id = urp.role_id " . - "AND urp.user_id=:urp_user_id AND r.description = 'Campus Champion'" . - "ORDER BY r.description, o.abbrev"; - $role_query_3_params = array( - ':ur_user_id' => $this->_id, - ':urp_user_id' => $this->_id, - ); - - // Principal Investigator - - $role_query_4 = "SELECT r.description, r.abbrev AS param_value, urp.is_primary, urp.is_active " . - "FROM moddb.UserRoles AS urp, moddb.Roles AS r " . - "WHERE r.role_id = urp.role_id AND user_id=:user_id " . - "AND r.description = 'Principal Investigator'"; - $role_query_4_params = array( - ':user_id' => $this->_id, - ); - - // User - - $role_query_5 = "SELECT r.description, r.abbrev AS param_value, urp.is_primary, urp.is_active " . - "FROM moddb.UserRoles AS urp, moddb.Roles AS r " . - "WHERE r.role_id = urp.role_id AND user_id=:user_id " . - "AND r.description = 'User'"; - $role_query_5_params = array( - ':user_id' => $this->_id, - ); + // Clean up any report-based data generated by the user + $this->_pdo->execute("DELETE FROM ChartPool WHERE user_id=:user_id", array( + ':user_id' => $this->_id, + )); + $this->_pdo->execute("DELETE FROM Reports WHERE user_id=:user_id", array( + ':user_id' => $this->_id, + )); + $this->_pdo->execute("DELETE FROM ReportCharts WHERE user_id=:user_id", array( + ':user_id' => $this->_id, + )); - $available_roles = array_merge( - $this->_pdo->query($role_query_1, $role_query_1_params), - $this->_pdo->query($role_query_2, $role_query_2_params), - $this->_pdo->query($role_query_3, $role_query_3_params), - $this->_pdo->query($role_query_4, $role_query_4_params), - $this->_pdo->query($role_query_5, $role_query_5_params) - ); + $this->_pdo->execute("DELETE FROM UserRoleParameters WHERE user_id=:user_id", array( + ':user_id' => $this->_id, + )); - return $available_roles; + $this->_pdo->execute("DELETE FROM user_acl_group_by_parameters WHERE user_id=:user_id", array( + ':user_id' => $this->_id + )); - }//enumAllAvailableRoles + $this->_pdo->execute("DELETE FROM UserRoles WHERE user_id=:user_id", array( + ':user_id' => $this->_id, + )); - // --------------------------- + // Make sure to remove the acl relations + $this->_pdo->execute("DELETE FROM user_acls WHERE user_id = :user_id", array( + ':user_id' => $this->_id + )); - /* - * - * @function setInstitution - * - * @param int $organization_id - * - * - */ + // Reset any associations to dependent users + $this->_pdo->execute("UPDATE UserRoleParameters SET promoter='-1' WHERE promoter=:promoter", array( + ':promoter' => $this->_id, + )); - public function setInstitution($institution_id, $is_primary = false) { + $this->_pdo->execute("DELETE FROM Users WHERE id=:id", array( + ':id' => $this->_id, + )); - // This feature currently applies to campus champions... + }//removeUser - if (empty($this->_id)) { - throw new \Exception("This user must be saved prior to calling setInstitution()"); - } + // --------------------------- - $primary_flag = $is_primary ? 1 : 0; + /* + * + * @function getUserType; + * + * @return int (maps to one of the TYPE_* class constants at the top of this file) + * + */ - $cleanupStatement = "DELETE FROM UserRoleParameters " . - "WHERE user_id=:user_id AND role_id=6 AND param_name='institution'"; + public function getUserType() + { + return $this->_user_type; + } - $insertStatement = "INSERT INTO UserRoleParameters " . - "(user_id, role_id, param_name, param_op, param_value, is_primary, is_active, promoter) " . - "VALUES (:user_id, 6, 'institution', '=', :param_value, :is_primary, 1, -1)"; + // --------------------------- - $this->_pdo->execute($cleanupStatement, array( - ':user_id' => $this->_id, - )); - $this->_pdo->execute($insertStatement, array( - ':user_id' => $this->_id, - ':param_value' => $institution_id, - ':is_primary' => $primary_flag, - )); + /* + * + * @function setUserType; + * + * @param int $userType + * + */ - }//setInstitution + public function setUserType($userType) + { + $this->_user_type = $userType; + } - // --------------------------- + // --------------------------- - /* - * - * @function disassociateWithOrganizations - * - * @param int $organization_id - * - * - */ + /* + * + * @function getAccountStatus; + * + * @return boolean + * + */ - public function disassociateWithInstitution() { + public function getAccountStatus() + { + return $this->_account_is_active; + } + + // --------------------------- + + /* + * + * @function setAccountStatus; + * + * @param boolean $status + * + */ + + public function setAccountStatus($status) + { + $this->_account_is_active = $status; + } + + // --------------------------- + + /* + * + * @function getEmailAddress + * + * @return string + * + */ + + public function getEmailAddress() + { + return $this->_email; + } + + // --------------------------- + + /* + * + * @function setEmailAddress + * + * @param string $email_address + * + */ + + public function setEmailAddress($email_address) + { + $this->_email = $email_address; + } + + // --------------------------- + + /* + * + * @function getFormalName + * + * @return string + * + */ + + public function getFormalName($includeMiddleName = false) + { + $formalName = $this->_firstName; + if ($includeMiddleName) { + $formalName .= ' ' . $this->_middleName; + } + $formalName .= ' ' . $this->_lastName; + return $formalName; + } + + // --------------------------- + + /* + * + * @function getFirstName + * + * @return string + * + */ + + public function getFirstName() + { + return $this->_firstName; + } + + // --------------------------- + + /* + * + * @function setFirstName + * + * @param string $firstName + * + */ - // This feature currently applies to campus champions... + public function setFirstName($firstName) + { + $this->_firstName = $firstName; + } + + // --------------------------- + + /* + * + * @function getLastName + * + * @return string + * + */ - if (empty($this->_id)) { - throw new \Exception("This user must be saved prior to calling disassociateWithInstitution()"); - } + public function getLastName() + { + return $this->_lastName; + } - $cleanupStatement = "DELETE FROM UserRoleParameters " . - "WHERE user_id=:user_id AND role_id=6 AND param_name='institution'"; + // --------------------------- - $this->_pdo->execute($cleanupStatement, array( - ':user_id' => $this->_id, - )); + /* + * + * @function setLastName + * + * @param string $lastName + * + */ - }//disassociateWithInstitution + public function setLastName($lastName) + { + $this->_lastName = $lastName; + } - // --------------------------- + // --------------------------- - /* - * - * @function getActiveRoleID - * - * @returns string (the id of the active role) (see ROLES section in constants.php) - * - */ + /* + * + * @function enumAllAvailableRoles + * + * @param int $organization_id + * + * + */ - public function getActiveRoleID() { + public function enumAllAvailableRoles() + { - return $this->_active_role->getIdentifier(); + if (empty($this->_id)) { - }//getActiveRoleID + // It is likely that the public user ended up here + return array(); - // --------------------------- + } - private function _getActiveProvider($role_id) { + // Program Officer - $active_provider = $this->_pdo->query("SELECT param_value FROM UserRoleParameters " . - "WHERE user_id=:user_id AND role_id=:role_id AND param_name='provider' AND is_active=1", array( - ':user_id' => $this->_id, - ':role_id' => $role_id, - )); + $role_query_1 = "SELECT r.description, r.abbrev AS param_value, urp.is_primary, urp.is_active " . + "FROM moddb.UserRoles AS urp, moddb.Roles AS r " . + "WHERE r.role_id = urp.role_id AND user_id=:user_id " . + "AND r.description = 'Program Officer'"; + $role_query_1_params = array( + ':user_id' => $this->_id, + ); - if (count($active_provider) > 0) { - return $active_provider[0]['param_value']; - } - else { - return NULL; - } + // Center Director and Center Staff - }//_getActiveProvider + $role_query_2 = "SELECT CONCAT(r.description, ' - ', o.abbrev) AS description, CONCAT(r.abbrev, ':', urp.param_value) AS param_value, urp.is_primary, urp.is_active " . + "FROM moddb.UserRoleParameters AS urp, moddb.Roles AS r, modw.organization AS o " . + "WHERE urp.param_value = o.id AND r.role_id = urp.role_id AND urp.user_id=:user_id AND r.description != 'Campus Champion'" . + "ORDER BY r.description, o.abbrev"; + $role_query_2_params = array( + ':user_id' => $this->_id, + ); - public function getActiveRoleSettings() { + // Campus Champion - $mainRole = $this->_pdo->query("SELECT r.abbrev, r.role_id FROM Roles AS r, UserRoles AS ur WHERE r.role_id = ur.role_id AND ur.user_id=:user_id AND ur.is_active=1", array( - ':user_id' => $this->_id, - )); + $role_query_3 = "SELECT CONCAT(r.description, ' - ', o.name) AS description, CONCAT(r.abbrev, ':', urp.param_value) AS param_value, urp.is_primary, ur.is_active " . + "FROM moddb.UserRoleParameters AS urp, moddb.UserRoles AS ur, moddb.Roles AS r, modw.organization AS o " . + "WHERE urp.param_value = o.id AND ur.role_id = r.role_id AND ur.user_id =:ur_user_id AND r.role_id = urp.role_id " . + "AND urp.user_id=:urp_user_id AND r.description = 'Campus Champion'" . + "ORDER BY r.description, o.abbrev"; + $role_query_3_params = array( + ':ur_user_id' => $this->_id, + ':urp_user_id' => $this->_id, + ); - $mainRoleID = $mainRole[0]['role_id']; - $mainRole = $mainRole[0]['abbrev']; + // Principal Investigator - $activeCenter = -1; + $role_query_4 = "SELECT r.description, r.abbrev AS param_value, urp.is_primary, urp.is_active " . + "FROM moddb.UserRoles AS urp, moddb.Roles AS r " . + "WHERE r.role_id = urp.role_id AND user_id=:user_id " . + "AND r.description = 'Principal Investigator'"; + $role_query_4_params = array( + ':user_id' => $this->_id, + ); - if ($mainRole == ROLE_ID_CENTER_DIRECTOR || $mainRole == ROLE_ID_CENTER_STAFF) { + // User - $activeCenter = $this->_pdo->query("SELECT param_value FROM UserRoleParameters WHERE user_id=:user_id AND role_id=:role_id AND is_active=1", array( + $role_query_5 = "SELECT r.description, r.abbrev AS param_value, urp.is_primary, urp.is_active " . + "FROM moddb.UserRoles AS urp, moddb.Roles AS r " . + "WHERE r.role_id = urp.role_id AND user_id=:user_id " . + "AND r.description = 'User'"; + $role_query_5_params = array( ':user_id' => $this->_id, - ':role_id' => $mainRoleID, - )); + ); + + $available_roles = array_merge( + $this->_pdo->query($role_query_1, $role_query_1_params), + $this->_pdo->query($role_query_2, $role_query_2_params), + $this->_pdo->query($role_query_3, $role_query_3_params), + $this->_pdo->query($role_query_4, $role_query_4_params), + $this->_pdo->query($role_query_5, $role_query_5_params) + ); - if (count($activeCenter) > 0) - $activeCenter = $activeCenter[0]['param_value']; - else - $activeCenter = -1; + return $available_roles; - } + }//enumAllAvailableRoles - return array('main_role' => $mainRole, 'active_center' => $activeCenter); + // --------------------------- - }//getActiveRoleSettings + /* + * + * @function setInstitution + * + * @param int $organization_id + * + * + */ - // --------------------------- + public function setInstitution($institution_id, $is_primary = false) + { - /* - * - * @function setOrganizations - * - * @param array $organization_ids (an array of elements of the form 'organization_id' => '0 or 1') - * (If the value is 0, then the organization is not primary. 1 if otherwise.) - * @param string $active_role_id (The active role pending a save to the database) - * @param string $role (use either ROLE_ID_CENTER_DIRECTOR or ROLE_ID_CENTER_STAFF) - * - * - */ + // This feature currently applies to campus champions... - public function setOrganizations($organization_ids = array(), $role = ROLE_ID_CENTER_DIRECTOR, $reassignActiveToPrimary = false) { + if (empty($this->_id)) { + throw new \Exception("This user must be saved prior to calling setInstitution()"); + } - // This feature currently applies to center directors and center staff members... + $primary_flag = $is_primary ? 1 : 0; - if (empty($this->_id)) { - throw new \Exception("This user must be saved prior to calling setOrganization()"); - } + $cleanupStatement = "DELETE FROM UserRoleParameters " . + "WHERE user_id=:user_id AND role_id=6 AND param_name='institution'"; - if ($role != ROLE_ID_CENTER_DIRECTOR && $role != ROLE_ID_CENTER_STAFF) { - throw new \Exception("This user must be saved prior to calling setOrganization()"); - } + $insertStatement = "INSERT INTO UserRoleParameters " . + "(user_id, role_id, param_name, param_op, param_value, is_primary, is_active, promoter) " . + "VALUES (:user_id, 6, 'institution', '=', :param_value, :is_primary, 1, -1)"; - $role_id = $this->_getRoleID($role); + $this->_pdo->execute($cleanupStatement, array( + ':user_id' => $this->_id, + )); + $this->_pdo->execute($insertStatement, array( + ':user_id' => $this->_id, + ':param_value' => $institution_id, + ':is_primary' => $primary_flag, + )); + + $aclName = 'cd'; + + $aclCleanup = <<_pdo->execute($aclCleanup, array( + ':user_id' => $this->_id, + ':acl_name' => $aclName + )); - // ------------------------------------------------------- + $this->_pdo->execute($aclInsert, array( + ':user_id' => $this->_id, + ':acl_name' => $aclName, + ':value' => $institution_id + )); - $this->_pdo->execute("DELETE FROM UserRoleParameters " . - "WHERE user_id=:user_id AND role_id=:role_id AND param_name='provider'", array( - ':user_id' => $this->_id, - ':role_id' => $role_id, - )); + }//setInstitution - // ======================================= + // --------------------------- - $active_is_in_set = false; - $primary_is_in_set = false; + /* + * + * @function disassociateWithOrganizations + * + * @param int $organization_id + * + * + */ - $active_organization = NULL; + public function disassociateWithInstitution() + { - foreach ($organization_ids as $organization_id => $config) { + // This feature currently applies to campus champions... - $active_flag = 0; - $primary_flag = 0; + if (empty($this->_id)) { + throw new \Exception("This user must be saved prior to calling disassociateWithInstitution()"); + } - if (($config['active'] == true) && ($reassignActiveToPrimary == false)) { - $active_flag = 1; - $active_is_in_set = true; - } + $cleanupStatement = "DELETE FROM UserRoleParameters " . + "WHERE user_id=:user_id AND role_id=6 AND param_name='institution'"; - if ($config['primary'] == true) { + $this->_pdo->execute($cleanupStatement, array( + ':user_id' => $this->_id, + )); + $this->_pdo->execute(<< $this->_id + )); - $primary_flag = 1; - $primary_is_in_set = true; + }//disassociateWithInstitution - if ($reassignActiveToPrimary == true) { - $active_flag = 1; - $active_is_in_set = true; - } + // --------------------------- + + /* + * + * @function getActiveRoleID + * + * @returns string (the id of the active role) (see ROLES section in constants.php) + * + */ + + public function getActiveRoleID() + { - } + return $this->_active_role->getIdentifier(); - if ($active_flag == 1) { - $active_organization = $organization_id; - } + }//getActiveRoleID + + // --------------------------- - $insertStatement = "INSERT INTO UserRoleParameters " . - "(user_id, role_id, param_name, param_op, param_value, is_primary, is_active, promoter) " . - "VALUES (:user_id, :role_id, 'provider', '=', :param_value, :is_primary, :is_active, -1)"; + private function _getActiveProvider($role_id) + { - $this->_pdo->execute($insertStatement, array( + $active_provider = $this->_pdo->query("SELECT param_value FROM UserRoleParameters " . + "WHERE user_id=:user_id AND role_id=:role_id AND param_name='provider' AND is_active=1", array( ':user_id' => $this->_id, ':role_id' => $role_id, - ':param_value' => $organization_id, - ':is_primary' => $primary_flag, - ':is_active' => $active_flag, - )); + )); - }//foreach + if (count($active_provider) > 0) { + return $active_provider[0]['param_value']; + } else { + return NULL; + } - // ======================================= + }//_getActiveProvider - if ($active_is_in_set == true) { - $this->setActiveRole($role, $active_organization); - } + public function getActiveRoleSettings() + { - if ($primary_is_in_set == true) { - $this->setPrimaryRole($role); - } + $mainRole = $this->_pdo->query("SELECT r.abbrev, r.role_id FROM Roles AS r, UserRoles AS ur WHERE r.role_id = ur.role_id AND ur.user_id=:user_id AND ur.is_active=1", array( + ':user_id' => $this->_id, + )); - }//setOrganizations + $mainRoleID = $mainRole[0]['role_id']; + $mainRole = $mainRole[0]['abbrev']; - // --------------------------- + $activeCenter = -1; - /* - * - * @function enumCenterStaffSites - * - */ + if ($mainRole == ROLE_ID_CENTER_DIRECTOR || $mainRole == ROLE_ID_CENTER_STAFF) { - public function enumCenterStaffSites() { + $activeCenter = $this->_pdo->query("SELECT param_value FROM UserRoleParameters WHERE user_id=:user_id AND role_id=:role_id AND is_active=1", array( + ':user_id' => $this->_id, + ':role_id' => $mainRoleID, + )); - // This feature currently applies to center staff members... + if (count($activeCenter) > 0) + $activeCenter = $activeCenter[0]['param_value']; + else + $activeCenter = -1; - if (empty($this->_id)) { - throw new \Exception("This user must be saved prior to calling enumCenterStaffSites()"); - } + } - $sites = $this->_pdo->query("SELECT param_value AS provider, is_primary FROM moddb.UserRoleParameters WHERE role_id=5 AND param_name='provider' AND user_id=:user_id", array( - ':user_id' => $this->_id, - )); + return array('main_role' => $mainRole, 'active_center' => $activeCenter); - return $sites; + }//getActiveRoleSettings - }//enumCenterStaffSites + // --------------------------- - // --------------------------- + /* + * + * @function setOrganizations + * + * @param array $organization_ids (an array of elements of the form 'organization_id' => '0 or 1') + * (If the value is 0, then the organization is not primary. 1 if otherwise.) + * @param string $active_role_id (The active role pending a save to the database) + * @param string $role (use either ROLE_ID_CENTER_DIRECTOR or ROLE_ID_CENTER_STAFF) + * + * + */ - /* - * - * @function enumCenterDirectorSites - * - */ + public function setOrganizations($organization_ids = array(), $role = ROLE_ID_CENTER_DIRECTOR, $reassignActiveToPrimary = false) + { - public function enumCenterDirectorSites() { + // This feature currently applies to center directors and center staff members... - // This feature currently applies to center directors... + if (empty($this->_id)) { + throw new \Exception("This user must be saved prior to calling setOrganization()"); + } - if (empty($this->_id)) { - throw new \Exception("This user must be saved prior to calling enumCenterDirectorSites()"); - } + if ($role != ROLE_ID_CENTER_DIRECTOR && $role != ROLE_ID_CENTER_STAFF) { + throw new \Exception("This user must be saved prior to calling setOrganization()"); + } - $sites = $this->_pdo->query("SELECT param_value AS provider, is_primary FROM moddb.UserRoleParameters WHERE role_id=1 AND param_name='provider' AND user_id=:user_id", array( - ':user_id' => $this->_id, - )); + $role_id = $this->_getRoleID($role); + if (null === $role_id) { + throw new Exception("Unable to retrieve id for role: $role"); + } + $acl = Acls::getAclByName($role); - return $sites; + // ------------------------------------------------------- - }//enumCenterDirectorSites + $this->_pdo->execute("DELETE FROM UserRoleParameters " . + "WHERE user_id=:user_id AND role_id=:role_id AND param_name='provider'", array( + ':user_id' => $this->_id, + ':role_id' => $role_id, + )); + $this->_pdo->execute( + "DELETE FROM user_acl_group_by_parameters WHERE user_id = :user_id AND acl_id = :acl_id AND group_by_id IN (SELECT gb.group_by_id FROM group_bys gb WHERE gb.name = 'provider')", + array( + ':user_id' => $this->_id, + ':acl_id' => $acl->getAclId() + ) + ); + // ======================================= - // --------------------------- + $active_is_in_set = false; + $primary_is_in_set = false; - /* - * - * @function disassociateWithOrganizations - * - * @param int $organization_id - * - * - */ + $active_organization = NULL; - public function disassociateWithOrganizations() { + foreach ($organization_ids as $organization_id => $config) { - // This feature currently applies to center directors... + $active_flag = 0; + $primary_flag = 0; - if (empty($this->_id)) { - throw new \Exception("This user must be saved prior to calling disassociateWithOrganizations()"); - } + if (($config['active'] == true) && ($reassignActiveToPrimary == false)) { + $active_flag = 1; + $active_is_in_set = true; + } - $cleanupStatement = "DELETE FROM UserRoleParameters WHERE user_id=:user_id AND role_id=1 AND param_name='provider'"; + if ($config['primary'] == true) { - $this->_pdo->execute($cleanupStatement, array( - ':user_id' => $this->_id, - )); + $primary_flag = 1; + $primary_is_in_set = true; - }//disassociateWithOrganizations + if ($reassignActiveToPrimary == true) { + $active_flag = 1; + $active_is_in_set = true; + } - // --------------------------- + } - /* - * - * @function getInstitution - * - * @return array - * - * - */ + if ($active_flag == 1) { + $active_organization = $organization_id; + } - public function getInstitution() { + $insertStatement = "INSERT INTO UserRoleParameters " . + "(user_id, role_id, param_name, param_op, param_value, is_primary, is_active, promoter) " . + "VALUES (:user_id, :role_id, 'provider', '=', :param_value, :is_primary, :is_active, -1)"; - // This feature currently applies to campus champions... + $this->_pdo->execute($insertStatement, array( + ':user_id' => $this->_id, + ':role_id' => $role_id, + ':param_value' => $organization_id, + ':is_primary' => $primary_flag, + ':is_active' => $active_flag, + )); + $this->_pdo->execute( + << $this->_id, + ':acl_id' => $acl->getAclId(), + ':value' => $organization_id + ) + ); + }//foreach - if (empty($this->_id)) { - throw new \Exception("This user must be saved prior to calling getInstitution()"); - } + // ======================================= - $query = "SELECT param_value FROM UserRoleParameters WHERE user_id=:user_id AND param_name='institution'"; + if ($active_is_in_set == true) { + $this->setActiveRole($role, $active_organization); + } - $results = $this->_pdo->query($query, array( - ':user_id' => $this->_id, - )); + if ($primary_is_in_set == true) { + $this->setPrimaryRole($role); + } - return (count($results) > 0) ? $results[0]['param_value'] : '-1'; + }//setOrganizations - }//getInstitution + // --------------------------- + + /* + * + * @function enumCenterStaffSites + * + */ - // --------------------------- + public function enumCenterStaffSites() + { - public function isCenterDirectorOfOrganization($organization_id) { + // This feature currently applies to center staff members... - $results = $this->_pdo->query( - "SELECT COUNT(*) AS num_matches FROM UserRoleParameters WHERE user_id=:user_id AND role_id=:role_id AND param_name=:param_name AND param_value=:param_value", - array( - 'user_id' => $this->_id, - 'role_id' => \xd_roles\getRoleIDFromIdentifier(ROLE_ID_CENTER_DIRECTOR), - 'param_name' => 'provider', - 'param_value' => $organization_id - ) - ); + if (empty($this->_id)) { + throw new \Exception("This user must be saved prior to calling enumCenterStaffSites()"); + } - $matches = $results[0]['num_matches']; + $sites = $this->_pdo->query("SELECT param_value AS provider, is_primary FROM moddb.UserRoleParameters WHERE role_id=5 AND param_name='provider' AND user_id=:user_id", array( + ':user_id' => $this->_id, + )); - return ($matches != 0); + return $sites; - }//isCenterDirectorOfOrganization + }//enumCenterStaffSites + + // --------------------------- - // --------------------------- + /* + * + * @function enumCenterDirectorSites + * + */ - /* - * - * @function getActiveOrganization - * - * @return int (corresponding to the primary organization) - * - * - */ + public function enumCenterDirectorSites() + { - public function getPrimaryOrganization() { + // This feature currently applies to center directors... - // This feature currently applies to center directors... + if (empty($this->_id)) { + throw new \Exception("This user must be saved prior to calling enumCenterDirectorSites()"); + } - if (empty($this->_id)) { - throw new \Exception("This user must be saved prior to calling getPrimaryOrganization()"); - } + $sites = $this->_pdo->query("SELECT param_value AS provider, is_primary FROM moddb.UserRoleParameters WHERE role_id=1 AND param_name='provider' AND user_id=:user_id", array( + ':user_id' => $this->_id, + )); - $query = "SELECT urp.param_value FROM UserRoleParameters AS urp, Roles AS r WHERE urp.role_id = r.role_id AND r.abbrev='cd' AND urp.user_id=:user_id AND urp.param_name='provider' AND urp.is_primary=1"; + return $sites; - $results = $this->_pdo->query($query, array( - ':user_id' => $this->_id, - )); + }//enumCenterDirectorSites - return (count($results) > 0) ? $results[0]['param_value'] : '-1'; + // --------------------------- - }//getPrimaryOrganization + /* + * + * @function disassociateWithOrganizations + * + * @param int $organization_id + * + * + */ - // --------------------------- + public function disassociateWithOrganizations() + { - /* - * - * @function getActiveOrganization - * - * @return int (corresponding to the active organization) - * - * - */ + // This feature currently applies to center directors... - public function getActiveOrganization() { + if (empty($this->_id)) { + throw new \Exception("This user must be saved prior to calling disassociateWithOrganizations()"); + } - // This feature currently applies to center directors... + $cleanupStatement = "DELETE FROM UserRoleParameters WHERE user_id=:user_id AND role_id=1 AND param_name='provider'"; - if (empty($this->_id)) { - throw new \Exception("This user must be saved prior to calling getActiveOrganization()"); - } + $this->_pdo->execute($cleanupStatement, array( + ':user_id' => $this->_id, + )); - $query = "SELECT urp.param_value FROM UserRoleParameters AS urp, Roles AS r WHERE urp.role_id = r.role_id AND r.abbrev='cd' AND urp.user_id=:user_id AND urp.param_name='provider' AND urp.is_active=1"; + }//disassociateWithOrganizations - $results = $this->_pdo->query($query, array( - ':user_id' => $this->_id, - )); + // --------------------------- - return (count($results) > 0) ? $results[0]['param_value'] : '-1'; + /* + * + * @function getInstitution + * + * @return array + * + * + */ - }//getActiveOrganization + public function getInstitution() + { + // This feature currently applies to campus champions... - // --------------------------- + if (empty($this->_id)) { + throw new \Exception("This user must be saved prior to calling getInstitution()"); + } - /* - * - * @function getOrganizationCollection - * - * @return array of integers (where each int represents an organization that user is affiliated with as a center staff member or center director) - * - * - */ + $query = "SELECT param_value FROM UserRoleParameters WHERE user_id=:user_id AND param_name='institution'"; - public function getOrganizationCollection($center_staff_or_director = ROLE_ID_CENTER_STAFF) { + $results = $this->_pdo->query($query, array( + ':user_id' => $this->_id, + )); - // This feature currently applies to center staff / center directors... + return (count($results) > 0) ? $results[0]['param_value'] : '-1'; - if (empty($this->_id)) { - throw new \Exception("This user must be saved prior to calling getOrganizationCollection()"); - } + }//getInstitution - $query = "SELECT urp.param_value FROM UserRoleParameters AS urp, Roles AS r WHERE urp.role_id = r.role_id AND r.abbrev=:abbrev AND urp.user_id=:user_id AND urp.param_name='provider'"; + // --------------------------- - $center_collection = array(); + public function isCenterDirectorOfOrganization($organization_id) + { - $results = $this->_pdo->query($query, array( - ':abbrev' => $center_staff_or_director, - ':user_id' => $this->_id, - )); + $results = $this->_pdo->query( + "SELECT COUNT(*) AS num_matches FROM UserRoleParameters WHERE user_id=:user_id AND role_id=:role_id AND param_name=:param_name AND param_value=:param_value", + array( + 'user_id' => $this->_id, + 'role_id' => \xd_roles\getRoleIDFromIdentifier(ROLE_ID_CENTER_DIRECTOR), + 'param_name' => 'provider', + 'param_value' => $organization_id + ) + ); - foreach ($results as $center_data) { - $center_collection[] = $center_data['param_value']; - } + $matches = $results[0]['num_matches']; - return $center_collection; + return ($matches != 0); - }//getOrganizationCollection + }//isCenterDirectorOfOrganization - // --------------------------- + // --------------------------- - /* - * - * @function getRoles - * - * @param string $flag ('formal' or 'informal') - * - * @return array - * - */ + /* + * + * @function getActiveOrganization + * + * @return int (corresponding to the primary organization) + * + * + */ - public function getRoles($flag = 'informal') { + public function getPrimaryOrganization() + { - if ($flag == 'informal'){ return $this->_roles; } + // This feature currently applies to center directors... - if ($flag == 'formal') { + if (empty($this->_id)) { + throw new \Exception("This user must be saved prior to calling getPrimaryOrganization()"); + } - $query = "SELECT r.description, r.abbrev FROM Roles AS r, UserRoles AS ur "; - $query .= "WHERE r.role_id = ur.role_id AND ur.user_id = :user_id ORDER BY ur.is_primary DESC"; + $query = "SELECT urp.param_value FROM UserRoleParameters AS urp, Roles AS r WHERE urp.role_id = r.role_id AND r.abbrev='cd' AND urp.user_id=:user_id AND urp.param_name='provider' AND urp.is_primary=1"; - $results = $this->_pdo->query($query, array( + $results = $this->_pdo->query($query, array( ':user_id' => $this->_id, - )); + )); - $roles = array(); + return (count($results) > 0) ? $results[0]['param_value'] : '-1'; - foreach($results as $roleSet) { + }//getPrimaryOrganization + + // --------------------------- + + /* + * + * @function getActiveOrganization + * + * @return int (corresponding to the active organization) + * + * + */ - $roles[$roleSet['description']] = $roleSet['abbrev']; + public function getActiveOrganization() + { - } + // This feature currently applies to center directors... - return $roles; + if (empty($this->_id)) { + throw new \Exception("This user must be saved prior to calling getActiveOrganization()"); + } - } + $query = "SELECT urp.param_value FROM UserRoleParameters AS urp, Roles AS r WHERE urp.role_id = r.role_id AND r.abbrev='cd' AND urp.user_id=:user_id AND urp.param_name='provider' AND urp.is_active=1"; - }//getRoles + $results = $this->_pdo->query($query, array( + ':user_id' => $this->_id, + )); - // --------------------------- + return (count($results) > 0) ? $results[0]['param_value'] : '-1'; - /* - * - * @function setRoles - * - * @param array $role_set - * - */ + }//getActiveOrganization - public function setRoles($role_set) { - $this->_roles = $role_set; - } - // --------------------------- + // --------------------------- - /* - * - * @function getPrimaryRole - * - * @return string - * - */ + /* + * + * @function getOrganizationCollection + * + * @return array of integers (where each int represents an organization that user is affiliated with as a center staff member or center director) + * + * + */ - public function getPrimaryRole() { + public function getOrganizationCollection($center_staff_or_director = ROLE_ID_CENTER_STAFF) + { - if ($this->_primary_role->getIdentifier() == ROLE_ID_PUBLIC) { - return $this->_primary_role; - } + // This feature currently applies to center staff / center directors... - if ($this->_id == NULL) { - throw new Exception('You must call saveUser() on this newly created XDUser prior to using getPrimaryRole()'); - } + if (empty($this->_id)) { + throw new \Exception("This user must be saved prior to calling getOrganizationCollection()"); + } - return $this->_primary_role; + $query = "SELECT urp.param_value FROM UserRoleParameters AS urp, Roles AS r WHERE urp.role_id = r.role_id AND r.abbrev=:abbrev AND urp.user_id=:user_id AND urp.param_name='provider'"; - }//getPrimaryRole + $center_collection = array(); - // --------------------------- + $results = $this->_pdo->query($query, array( + ':abbrev' => $center_staff_or_director, + ':user_id' => $this->_id, + )); - /* - * - * @function setPrimaryRole - * - * @param string $primary_role - * - */ + foreach ($results as $center_data) { + $center_collection[] = $center_data['param_value']; + } - public function setPrimaryRole($primary_role) { + return $center_collection; - $primary_role_name = $this->_getFormalRoleName($primary_role); + }//getOrganizationCollection - if ($primary_role_name == NULL) { - throw new Exception("Attempting to set an invalid primary role"); - } + // --------------------------- - $this->_primary_role = \User\aRole::factory($primary_role_name); + /* + * + * @function getRoles + * + * @param string $flag ('formal' or 'informal') + * + * @return array + * + */ - if ($this->_id != NULL) { - $this->_primary_role->configure($this); - } + public function getRoles($flag = 'informal') + { - }//setPrimaryRole + if ($flag == 'informal') { + $roles = array_reduce($this->_acls, function ($carry, Acl $item) { + $carry[] = $item->getName(); + return $carry; + }, array()); + return $roles; + } - // --------------------------- + if ($flag == 'formal') { + $query = <<_pdo->query($query, array( + ':user_id' => $this->_id, + )); - /* - * - * @function getActiveRole - * - * @return aRole subclass instance - * - */ + $roles = array(); - public function getActiveRole() { + foreach ($results as $roleSet) { - if ($this->_active_role->getIdentifier() == ROLE_ID_PUBLIC) { - return $this->_active_role; - } + $roles[$roleSet['display']] = $roleSet['name']; - if ($this->_id == NULL) { - throw new Exception('You must call saveUser() on this newly created XDUser prior to using getActiveRole()'); - } + } - return $this->_active_role; + return $roles; + } - }//getActiveRole + }//getRoles + // --------------------------- - public function setCachedActiveRole($role) { + /* + * + * @function setRoles + * + * @param array $role_set + * + */ + + public function setRoles($role_set) + { + $this->_roles = $role_set; + // Make sure to also set the Acls + $acls = array_reduce($role_set, function ($carry, $roleName) { + $acl = Acls::getAclByName($roleName); + if ($acl !== null) { + $carry [] = $acl; + } + return $carry; + }, array()); + $this->setAcls($acls); + } + + // --------------------------- + + /* + * + * @function getPrimaryRole + * + * @return string + * + */ + + public function getPrimaryRole() + { + + if ($this->_id == NULL) { + throw new Exception('You must call saveUser() on this newly created XDUser prior to using getPrimaryRole()'); + } + + return $this->_primary_role; + + }//getPrimaryRole + + // --------------------------- + + /* + * + * @function setPrimaryRole + * + * @param string $primary_role + * + */ + + public function setPrimaryRole($primary_role) + { + + $primary_role_name = $this->_getFormalRoleName($primary_role); + + if ($primary_role_name == NULL) { + throw new Exception("Attempting to set an invalid primary role"); + } + + $this->_primary_role = \User\aRole::factory($primary_role_name); + + if ($this->_id != NULL) { + $this->_primary_role->configure($this); + } + + }//setPrimaryRole + + // --------------------------- + + /* + * + * @function getActiveRole + * + * @return aRole subclass instance + * + */ + + public function getActiveRole() + { + if ($this->_id == NULL) { + throw new Exception('You must call saveUser() on this newly created XDUser prior to using getActiveRole()'); + } + + return $this->_active_role; + + }//getActiveRole + + + public function setCachedActiveRole($role) + { + + $this->_cachedActiveRole = $role; + + } + + public function getCachedActiveRole() + { + + return $this->_cachedActiveRole; + + } + + // --------------------------- + + /* + * + * @function getMostPrivilegedRole + * + * @return aRole subclass instance + * + */ + + public function getMostPrivilegedRole() + { + + // XDUser::enumAllAvailableRoles already orders the roles in terms of 'visibility' / 'highest privilege' + // so just acquire the first item in the set. + + $availableRoles = $this->enumAllAvailableRoles(); + if (count($availableRoles) > 0) { + + $roleData = explode(':', $availableRoles[0]['param_value']); + $roleData = array_pad($roleData, 2, NULL); + + return $this->assumeActiveRole($roleData[0], $roleData[1]); + + } else { + + return $this->getActiveRole(); + + } + + }//getMostPrivilegedRole + + /* @function getAllRoles + * + * Returns an array containing all roles that a user is assigned + * + * @param boolean $includePublicRole (Optional) If true, the roles returned + * will include the public role. + * (Defaults to false.) + */ + function getAllRoles($includePublicRole = false) + { + $allroles = array(); - $this->_cachedActiveRole = $role; + foreach ($this->enumAllAvailableRoles() as $availableRole) { + $roleData = array_pad(explode(':', $availableRole['param_value']), 2, NULL); + $allroles[] = $this->assumeActiveRole($roleData[0], $roleData[1]); + } - } + if ($includePublicRole) { + $allroles[] = $this->assumeActiveRole(ROLE_ID_PUBLIC); + } - public function getCachedActiveRole() { + return $allroles; + } - return $this->_cachedActiveRole; + // --------------------------- - } + /* + * + * @function _isValidOrganizationID + * + * @param int $role_id + * @param int $organization_id + * + * @return boolean + * + */ - // --------------------------- + private function _isValidOrganizationID($role_id, $organization_id) + { - /* - * - * @function getMostPrivilegedRole - * - * @return aRole subclass instance - * - */ + $results = $this->_pdo->query("SELECT COUNT(*) AS num_matches FROM UserRoleParameters WHERE user_id=:user_id AND role_id=:role_id AND param_value=:organization_id", + array( + 'user_id' => $this->_id, + 'role_id' => $role_id, + 'organization_id' => $organization_id + ) + ); - public function getMostPrivilegedRole() { + return ($results[0]['num_matches'] != 0); - // XDUser::enumAllAvailableRoles already orders the roles in terms of 'visibility' / 'highest privilege' - // so just acquire the first item in the set. + }//_isValidOrganizationID - $availableRoles = $this->enumAllAvailableRoles(); - if(count($availableRoles) > 0) - { + // --------------------------- - $roleData = explode(':', $availableRoles[0]['param_value']); - $roleData = array_pad($roleData, 2, NULL); + /* + * + * @function _getRoleIDFromIdentifier + * + * @param string $identifier (see constants.php, ROLE_ID_... constants) + * + * @return int (the numerical id corresponding to the role identifier passed in) + * + */ - return $this->assumeActiveRole($roleData[0], $roleData[1]); + private function _getRoleIDFromIdentifier($identifier) + { - }else - { + $role_data = $this->_pdo->query("SELECT role_id FROM Roles WHERE abbrev=:abbrev", array( + ':abbrev' => $identifier, + )); - return $this->getActiveRole(); + if (count($role_data) == 0) { + //throw new Exception('Invalid role identifier specified -- '.$identifier); + return -1; + } - } + return $role_data[0]['role_id']; - }//getMostPrivilegedRole + }//_getRoleIDFromIdentifier - /* @function getAllRoles - * - * Returns an array containing all roles that a user is assigned - * - * @param boolean $includePublicRole (Optional) If true, the roles returned - * will include the public role. - * (Defaults to false.) - */ - function getAllRoles($includePublicRole = false) - { - $allroles = array(); + // --------------------------- - foreach($this->enumAllAvailableRoles() as $availableRole) - { - $roleData = array_pad(explode(':', $availableRole['param_value']), 2, NULL); - $allroles[] = $this->assumeActiveRole($roleData[0], $roleData[1]); - } + /* + * + * @function assumeActiveRole + * + * Allows this user to take on a role, yet does not 'record' this fact into the database (a 'virtual' role, if you will) + * + * @param int $active_role (see constants.php, ROLE_ID_... constants) + * @param int $role_param [depending on the role, a specific value tied to that role that behaves as an additional filter (e.g. organization / institution id) + * + * + */ - if ($includePublicRole) { - $allroles[] = $this->assumeActiveRole(ROLE_ID_PUBLIC); - } + public function assumeActiveRole($active_role, $role_param = NULL) + { - return $allroles; - } + if (empty($active_role)) $active_role = ROLE_ID_PUBLIC; - // --------------------------- + $active_role_name = $this->_getFormalRoleName($active_role); - /* - * - * @function _isValidOrganizationID - * - * @param int $role_id - * @param int $organization_id - * - * @return boolean - * - */ + $virtual_active_role = \User\aRole::factory($active_role_name); + $virtual_active_role->configure($this, $role_param); - private function _isValidOrganizationID($role_id, $organization_id) { + return $virtual_active_role; - $results = $this->_pdo->query("SELECT COUNT(*) AS num_matches FROM UserRoleParameters WHERE user_id=:user_id AND role_id=:role_id AND param_value=:organization_id", - array( - 'user_id' => $this->_id, - 'role_id' => $role_id, - 'organization_id' => $organization_id - ) - ); + }//assumeActiveRole - return ($results[0]['num_matches'] != 0); + // --------------------------- - }//_isValidOrganizationID + /* + * + * @function setActiveRole (NOTE: When using setActiveRole(), ensure that a subsequent call to saveUser() is made) + * + * @param int $active_role (see constants.php, ROLE_ID_... constants) + * @param int $role_param [required depending on what role is being set as active] + * + */ - // --------------------------- + public function setActiveRole($active_role, $role_param = NULL) + { - /* - * - * @function _getRoleIDFromIdentifier - * - * @param string $identifier (see constants.php, ROLE_ID_... constants) - * - * @return int (the numerical id corresponding to the role identifier passed in) - * - */ + $active_role_name = $this->_getFormalRoleName($active_role); - private function _getRoleIDFromIdentifier($identifier) { + if ($active_role_name == NULL) { + throw new Exception("Attempting to set an invalid active role"); + } - $role_data = $this->_pdo->query("SELECT role_id FROM Roles WHERE abbrev=:abbrev", array( - ':abbrev' => $identifier, - )); + $role_id = $this->_getRoleIDFromIdentifier($active_role); - if (count($role_data) == 0) { - //throw new Exception('Invalid role identifier specified -- '.$identifier); - return -1; - } + $campus_champion_role_id = $this->_getRoleIDFromIdentifier(ROLE_ID_CAMPUS_CHAMPION); - return $role_data[0]['role_id']; + if ($active_role == ROLE_ID_CENTER_DIRECTOR || $active_role == ROLE_ID_CENTER_STAFF) { - }//_getRoleIDFromIdentifier + if ($role_param == NULL) { + throw new Exception("An additional parameter must be passed for this role (organization id)"); + } - // --------------------------- + if ($this->_isValidOrganizationID($role_id, $role_param) == true) { - /* - * - * @function assumeActiveRole - * - * Allows this user to take on a role, yet does not 'record' this fact into the database (a 'virtual' role, if you will) - * - * @param int $active_role (see constants.php, ROLE_ID_... constants) - * @param int $role_param [depending on the role, a specific value tied to that role that behaves as an additional filter (e.g. organization / institution id) - * - * - */ + $this->_pdo->execute("UPDATE moddb.UserRoleParameters SET is_active=0 WHERE user_id=:user_id AND role_id != :role_id", array( + ':user_id' => $this->_id, + ':role_id' => $campus_champion_role_id, + )); + $this->_pdo->execute("UPDATE moddb.UserRoleParameters SET is_active=1 WHERE user_id=:user_id AND role_id=:role_id AND param_value=:param_value", array( + ':user_id' => $this->_id, + ':role_id' => $role_id, + ':param_value' => $role_param, + )); - public function assumeActiveRole($active_role, $role_param = NULL) { + } else { - if (empty($active_role)) $active_role = ROLE_ID_PUBLIC; + throw new Exception("An invalid organization id has been specified for the role you are attempting to make active"); - $active_role_name = $this->_getFormalRoleName($active_role); + } - $virtual_active_role = \User\aRole::factory($active_role_name); - $virtual_active_role->configure($this, $role_param); + } else { - return $virtual_active_role; + $this->_pdo->execute("UPDATE moddb.UserRoleParameters SET is_active=0 WHERE user_id=:user_id AND role_id != :role_id", array( + ':user_id' => $this->_id, + ':role_id' => $campus_champion_role_id, + )); - }//assumeActiveRole + } - // --------------------------- + $this->_pdo->execute("UPDATE moddb.UserRoles SET is_active=0 WHERE user_id=:user_id", array( + ':user_id' => $this->_id, + )); + $this->_pdo->execute("UPDATE moddb.UserRoles SET is_active=1 WHERE user_id=:user_id AND role_id=:role_id", array( + ':user_id' => $this->_id, + ':role_id' => $role_id, + )); - /* - * - * @function setActiveRole (NOTE: When using setActiveRole(), ensure that a subsequent call to saveUser() is made) - * - * @param int $active_role (see constants.php, ROLE_ID_... constants) - * @param int $role_param [required depending on what role is being set as active] - * - */ + $this->_active_role = \User\aRole::factory($active_role_name); - public function setActiveRole($active_role, $role_param = NULL) { + if ($this->_id != NULL) { + $this->_active_role->configure($this); + } - $active_role_name = $this->_getFormalRoleName($active_role); + }//setActiveRole - if ($active_role_name == NULL) { - throw new Exception("Attempting to set an invalid active role"); - } - $role_id = $this->_getRoleIDFromIdentifier($active_role); + // --------------------------- - $campus_champion_role_id = $this->_getRoleIDFromIdentifier(ROLE_ID_CAMPUS_CHAMPION); + /* + * + * @function assignActiveRoleToPrimary (Re-assigns the user's active role to their primary role (failover)) + * + */ - if ($active_role == ROLE_ID_CENTER_DIRECTOR || $active_role == ROLE_ID_CENTER_STAFF) { + public function assignActiveRoleToPrimary() + { - if ($role_param == NULL) { - throw new Exception("An additional parameter must be passed for this role (organization id)"); - } + $this->_pdo->execute("UPDATE moddb.UserRoles SET is_active=is_primary WHERE user_id=:user_id", array( + ':user_id' => $this->_id, + )); + $this->_pdo->execute("UPDATE moddb.UserRoleParameters SET is_active=is_primary WHERE user_id=:user_id", array( + ':user_id' => $this->_id, + )); - if ($this->_isValidOrganizationID($role_id, $role_param) == true) { + }//assignActiveRoleToPrimary - $this->_pdo->execute("UPDATE moddb.UserRoleParameters SET is_active=0 WHERE user_id=:user_id AND role_id != :role_id", array( - ':user_id' => $this->_id, - ':role_id' => $campus_champion_role_id, - )); - $this->_pdo->execute("UPDATE moddb.UserRoleParameters SET is_active=1 WHERE user_id=:user_id AND role_id=:role_id AND param_value=:param_value", array( - ':user_id' => $this->_id, - ':role_id' => $role_id, - ':param_value' => $role_param, - )); - } - else { + // --------------------------- - throw new Exception("An invalid organization id has been specified for the role you are attempting to make active"); + /* + * + * @function getUserID + * + * @return int + * + */ - } + public function getUserID() + { + return (empty($this->_id)) ? '0' : $this->_id; + } - } - else { + // -------------------------------------------------- - $this->_pdo->execute("UPDATE moddb.UserRoleParameters SET is_active=0 WHERE user_id=:user_id AND role_id != :role_id", array( - ':user_id' => $this->_id, - ':role_id' => $campus_champion_role_id, - )); + // @function getPromoter + // + // @param int $role_id (consult the ROLE_ID.. constants in constants.php) + // @param int $organization_id + // + // @returns id (the id of the user who promoted this user to center director) + // + // If the value returned is -1, then either: + // - The promoter's account has been removed from the system + // - The center director is a primary center director - } - $this->_pdo->execute("UPDATE moddb.UserRoles SET is_active=0 WHERE user_id=:user_id", array( - ':user_id' => $this->_id, - )); - $this->_pdo->execute("UPDATE moddb.UserRoles SET is_active=1 WHERE user_id=:user_id AND role_id=:role_id", array( - ':user_id' => $this->_id, - ':role_id' => $role_id, - )); + public function getPromoter($role_id, $organization_id) + { - $this->_active_role = \User\aRole::factory($active_role_name); + $pdo = DB::factory('database'); - if ($this->_id != NULL) { - $this->_active_role->configure($this); - } + $promoterResults = $pdo->query( + "SELECT promoter FROM UserRoleParameters WHERE user_id=:user_id AND role_id=:role_id AND param_value=:param_value", + array( + 'user_id' => $this->_id, + 'role_id' => \xd_roles\getRoleIDFromIdentifier($role_id), + 'param_value' => $organization_id + ) + ); - }//setActiveRole + if (count($promoterResults) == 0) return -1; + return $promoterResults[0]['promoter']; - // --------------------------- + }//getPromoter - /* - * - * @function assignActiveRoleToPrimary (Re-assigns the user's active role to their primary role (failover)) - * - */ + // --------------------------- - public function assignActiveRoleToPrimary() { + /* + * + * @function getPersonID + * + * @param bool $default (If FALSE *and* the user object being looked at corresponds to the logged in user, consider the 'assumed_person_id' and return it if it exists) + * (If TRUE *and* the user object being looked at corresponds to the logged in user, return the stored person id) + * + * @return string + * + */ - $this->_pdo->execute("UPDATE moddb.UserRoles SET is_active=is_primary WHERE user_id=:user_id", array( - ':user_id' => $this->_id, - )); - $this->_pdo->execute("UPDATE moddb.UserRoleParameters SET is_active=is_primary WHERE user_id=:user_id", array( - ':user_id' => $this->_id, - )); + public function getPersonID($default = FALSE) + { - }//assignActiveRoleToPrimary + // NOTE: RESTful services do not operate on the concept of a session, so we need to check for $_SESSION[..] entities using isset + if (isset($_SESSION['xdUser']) && ($_SESSION['xdUser'] == $this->_id) && ($default == FALSE)) { - // --------------------------- + // The user object pertains to the user logged in.. - /* - * - * @function getUserID - * - * @return int - * - */ + if (isset($_SESSION['assumed_person_id'])) { + return $_SESSION['assumed_person_id']; + } - public function getUserID() { - return (empty($this->_id)) ? '0' : $this->_id; - } + } - // -------------------------------------------------- + return (empty($this->_personID)) ? '0' : $this->_personID; - // @function getPromoter - // - // @param int $role_id (consult the ROLE_ID.. constants in constants.php) - // @param int $organization_id - // - // @returns id (the id of the user who promoted this user to center director) - // - // If the value returned is -1, then either: - // - The promoter's account has been removed from the system - // - The center director is a primary center director + }//getPersonID + // --------------------------- - public function getPromoter($role_id, $organization_id) { + /* + * + * @function setPersonID + * + * @param string $person_id + * + */ - $pdo = DB::factory('database'); + public function setPersonID($person_id) + { + $this->_personID = $person_id; + } - $promoterResults = $pdo->query( - "SELECT promoter FROM UserRoleParameters WHERE user_id=:user_id AND role_id=:role_id AND param_value=:param_value", - array( - 'user_id' => $this->_id, - 'role_id' => \xd_roles\getRoleIDFromIdentifier($role_id), - 'param_value' => $organization_id - ) - ); + // --------------------------- - if (count($promoterResults) == 0) return -1; + /* + * + * @function getCreationTimestamp + * + * @return string + * + */ - return $promoterResults[0]['promoter']; + public function getCreationTimestamp() + { + return $this->_formalizeTimestamp($this->_timeCreated); + } - }//getPromoter + // --------------------------- - // --------------------------- + /* + * + * @function getPasswordLastUpdatedTimestamp + * + * @return string + * + */ - /* - * - * @function getPersonID - * - * @param bool $default (If FALSE *and* the user object being looked at corresponds to the logged in user, consider the 'assumed_person_id' and return it if it exists) - * (If TRUE *and* the user object being looked at corresponds to the logged in user, return the stored person id) - * - * @return string - * - */ + public function getPasswordLastUpdatedTimestamp() + { + return $this->_timePasswordUpdated; + } - public function getPersonID($default = FALSE) { + // --------------------------- - // NOTE: RESTful services do not operate on the concept of a session, so we need to check for $_SESSION[..] entities using isset + /* + * + * @function getUpdateTimestamp + * + * @return string + * + */ - if (isset($_SESSION['xdUser']) && ($_SESSION['xdUser'] == $this->_id) && ($default == FALSE)){ + public function getUpdateTimestamp() + { + return $this->_formalizeTimestamp($this->_timeUpdated); + } - // The user object pertains to the user logged in.. + // --------------------------- - if (isset($_SESSION['assumed_person_id'])){ - return $_SESSION['assumed_person_id']; - } + /* + * + * @function _formalizeTimestamp + * (transforms the DB stored timestamp into a more readable format) + * + * @return string + * + */ - } + private function _formalizeTimestamp($db_timestamp) + { - return (empty($this->_personID)) ? '0' : $this->_personID; + if (!isset($db_timestamp)) return "??"; - }//getPersonID + list($db_date, $db_time) = explode(' ', $db_timestamp); - // --------------------------- + list($year, $month, $day) = explode('-', $db_date); - /* - * - * @function setPersonID - * - * @param string $person_id - * - */ + $formal_date = $month . '/' . $day . '/' . $year; - public function setPersonID($person_id) { - $this->_personID = $person_id; - } + // ------------------------ - // --------------------------- + list($m_hour, $min, $sec) = explode(':', $db_time); - /* - * - * @function getCreationTimestamp - * - * @return string - * - */ + $meridiem = ($m_hour > 11) ? 'PM' : 'AM'; - public function getCreationTimestamp() { - return $this->_formalizeTimestamp($this->_timeCreated); - } + $s_hour = ($m_hour > 12) ? $m_hour - 12 : $m_hour; + if ($s_hour == 0) $s_hour = 12; - // --------------------------- + $formal_time = $s_hour . ':' . $min . ':' . $sec; - /* - * - * @function getPasswordLastUpdatedTimestamp - * - * @return string - * - */ + return $formal_date . ', ' . $formal_time . ' ' . $meridiem; - public function getPasswordLastUpdatedTimestamp() { - return $this->_timePasswordUpdated; - } + }//_formalizeTimestamp - // --------------------------- + // --------------------------- - /* - * - * @function getUpdateTimestamp - * - * @return string - * - */ + /* + * @function _getFormalRoleName + * (determines the formal description of a role based on its abbreviation) + * + * @return string representing the formal role name if the abbreviation is recognized + * @return NULL otherwise + * + */ - public function getUpdateTimestamp() { - return $this->_formalizeTimestamp($this->_timeUpdated); - } + public function _getFormalRoleName($role_abbrev) + { - // --------------------------- + if ($role_abbrev == ROLE_ID_PUBLIC) { + return 'Public'; + } - /* - * - * @function _formalizeTimestamp - * (transforms the DB stored timestamp into a more readable format) - * - * @return string - * - */ + if ($role_abbrev == NULL) { + return 'Public'; + } - private function _formalizeTimestamp($db_timestamp) { + $pdo = DB::factory('database'); - if (!isset($db_timestamp)) return "??"; + $roleData = $pdo->query("SELECT description FROM Roles WHERE abbrev=:abbrev", array( + ':abbrev' => $role_abbrev, + )); - list($db_date, $db_time) = explode(' ', $db_timestamp); + if (count($roleData) == 0) { + return 'Public'; + } - list($year, $month, $day) = explode('-', $db_date); + return $roleData[0]['description']; - $formal_date = $month.'/'.$day.'/'.$year; + }//_getFormalRoleName - // ------------------------ + // -------------------------------- - list($m_hour, $min, $sec) = explode(':', $db_time); + /* + * + * @function _generateToken + * (returns a unique random string used for authentication against the REST service) + * + * @return string + * + */ - $meridiem = ($m_hour > 11) ? 'PM' : 'AM'; + private function _generateToken() + { - $s_hour = ($m_hour > 12) ? $m_hour - 12 : $m_hour; - if ($s_hour == 0) $s_hour = 12; + $characters = '0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ'; - $formal_time = $s_hour.':'.$min.':'.$sec; + $string = ''; - return $formal_date.', '.$formal_time.' '.$meridiem; + for ($p = 0; $p < 32; $p++) { + $string .= $characters[mt_rand(0, strlen($characters) - 1)]; + } - }//_formalizeTimestamp + $results = $this->_pdo->query("SELECT * FROM Users WHERE token=:token", array( + ':token' => $string, + )); - // --------------------------- + if (count($results) == 0) + return $string; + else + return $this->_generateToken(); - /* - * @function _getFormalRoleName - * (determines the formal description of a role based on its abbreviation) - * - * @return string representing the formal role name if the abbreviation is recognized - * @return NULL otherwise - * - */ + }//_generateToken - public function _getFormalRoleName($role_abbrev) { - if ($role_abbrev == ROLE_ID_PUBLIC) { - return 'Public'; - } + // -------------------------------- - if ($role_abbrev == NULL){ - return 'Public'; - } + /* + * + * @function validateRID + * (determines whether the reset identifier (RID) is valid -- used for account password updating) + * + * @param string $rid + * + * @return array: if first element in the array is VALID, then the array structure will be (VALID, id, first_name) + * if first element in the array is INVALID, then the array structure will be (INVALID) + * + */ - $pdo = DB::factory('database'); + public static function validateRID($rid) + { - $roleData = $pdo->query("SELECT description FROM Roles WHERE abbrev=:abbrev", array( - ':abbrev' => $role_abbrev, - )); + $pdo = DB::factory('database'); - if (count($roleData) == 0) { - return 'Public'; - } + $accountCheck = $pdo->query("SELECT id, first_name FROM Users WHERE MD5(CONCAT(username, password_last_updated)) = :rid", array( + ':rid' => $rid, + )); - return $roleData[0]['description']; + if (count($accountCheck) > 0) { + return array('status' => VALID, 'user_id' => $accountCheck[0]['id'], 'user_first_name' => $accountCheck[0]['first_name']); + } else { + return array('status' => INVALID); + } - }//_getFormalRoleName + }//validateRID - // -------------------------------- - /* - * - * @function _generateToken - * (returns a unique random string used for authentication against the REST service) - * - * @return string - * - */ + public function getRoleCategories() + { - private function _generateToken() { + $availableRoles = $this->enumAllAvailableRoles(); + $userRoles = array(); + $userHasProgramOfficerRole = false; - $characters = '0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ'; + $center_ids = array(); - $string = ''; + foreach ($availableRoles as $role) { - for ($p = 0; $p < 32; $p++) { - $string .= $characters[mt_rand(0, strlen($characters) - 1)]; - } + if ($role['param_value'] == ROLE_ID_PROGRAM_OFFICER) { + $userHasProgramOfficerRole = true; + } - $results = $this->_pdo->query("SELECT * FROM Users WHERE token=:token", array( - ':token' => $string, - )); + $userRoles[$role['param_value']] = $role['description']; - if (count($results) == 0) - return $string; - else - return $this->_generateToken(); + $roleMetaData = explode(':', $role['param_value']); - }//_generateToken + if (count($roleMetaData) == 2) { + $center_ids[] = $roleMetaData[1]; - // -------------------------------- + } - /* - * - * @function validateRID - * (determines whether the reset identifier (RID) is valid -- used for account password updating) - * - * @param string $rid - * - * @return array: if first element in the array is VALID, then the array structure will be (VALID, id, first_name) - * if first element in the array is INVALID, then the array structure will be (INVALID) - * - */ + }//foreach - public static function validateRID($rid) { + // --------------------------------------- - $pdo = DB::factory('database'); + $rpCategories = array(); - $accountCheck = $pdo->query("SELECT id, first_name FROM Users WHERE MD5(CONCAT(username, password_last_updated)) = :rid", array( - ':rid' => $rid, - )); + $pdo = DB::factory('datawarehouse'); + $rps = $pdo->query( + "SELECT DISTINCT + o.organization_id AS id, + short_name + FROM + serviceprovider o + ORDER BY short_name" + ); - if (count($accountCheck) > 0) { - return array('status' => VALID, 'user_id' => $accountCheck[0]['id'], 'user_first_name' => $accountCheck[0]['first_name']); - } - else { - return array('status' => INVALID); - } + $role_parameters = $this->getActiveRole()->getParameters(); - }//validateRID + // If there is only one service provider, don't display any. + if (count($rps) > 1) { + foreach ($rps as $rp) { + if (isset($role_parameters['provider']) && $role_parameters['provider'] == $rp['id']) continue; //ignore the rp that is linked to the role + $rpCategories['rp_' . $rp['id']] = $rp['short_name'];//.' - '.$rp['name']; + } + } + $roleCategories = $this->getActiveRole()->getRoleCategories(false);//toms wants XSEDE to show no matter if you are po or not. - public function getRoleCategories() { + /* + foreach($roleCategories as $key => $value) + { + if($key == 'my') + { + $roleCategories[$key] = $this->getActiveRole()->getFormalName(); + } + } + */ - $availableRoles = $this->enumAllAvailableRoles(); - $userRoles = array(); - $userHasProgramOfficerRole = false; + $roleCategories = array_reverse($roleCategories); + $roleCategories = array_merge($roleCategories, $rpCategories); - $center_ids = array(); - foreach ($availableRoles as $role) { + $filteredRoleCategories = array(); - if ($role['param_value'] == ROLE_ID_PROGRAM_OFFICER){ $userHasProgramOfficerRole = true; } + foreach ($roleCategories as $k => $v) { - $userRoles[$role['param_value']] = $role['description']; + $resourceProviderMetaData = explode('_', $k); - $roleMetaData = explode(':', $role['param_value']); + if (count($resourceProviderMetaData) == 1) { - if (count($roleMetaData) == 2) { + $filteredRoleCategories[$k] = $v; - $center_ids[] = $roleMetaData[1]; + } else if (!in_array($resourceProviderMetaData[1], $center_ids)) { - } + $filteredRoleCategories[$k] = $v; - }//foreach + } - // --------------------------------------- + }//foreach ($roleCategories as $k => $v) - $rpCategories = array(); - $pdo = DB::factory('datawarehouse'); - $rps = $pdo->query( - "SELECT distinct - o.organization_id as id, - short_name - FROM - serviceprovider o - order by short_name" - ); + $roleCategories = array_merge($userRoles, array('separator'), $filteredRoleCategories); - $role_parameters = $this->getActiveRole()->getParameters(); + return json_encode($roleCategories); - // If there is only one service provider, don't display any. - if (count($rps) > 1) { - foreach($rps as $rp) - { - if(isset($role_parameters['provider']) && $role_parameters['provider'] == $rp['id'])continue; //ignore the rp that is linked to the role - $rpCategories['rp_'.$rp['id']] = $rp['short_name'];//.' - '.$rp['name']; - } - } + } - $roleCategories = $this->getActiveRole()->getRoleCategories(false);//toms wants XSEDE to show no matter if you are po or not. + // XSEDE-Centric functionality ========================================================= - /* - foreach($roleCategories as $key => $value) - { - if($key == 'my') - { - $roleCategories[$key] = $this->getActiveRole()->getFormalName(); - } - } - */ + /* + * @function initializeXSEDEUser + * + * Manifests a XDUser from an XSEDE account (referenced by XSEDE username and the CN of the certificate) + * + * @param String $username (The XSEDE username (username;Formal Name) + * + * @returns an XDUser object + * + */ - $roleCategories = array_reverse($roleCategories); - $roleCategories = array_merge($roleCategories, $rpCategories); + public static function initializeXSEDEUser($username) + { + list($xsede_username, $formal_name) = explode(';', $username); + list($first_name, $last_name) = explode(' ', $formal_name, 2); - $filteredRoleCategories = array(); + $person_id = self::resolvePersonIDFromXSEDEUsername($xsede_username); - foreach ($roleCategories as $k => $v) { + $email_address = self::_getXSEDEEmailAddressFromPersonID($person_id); - $resourceProviderMetaData = explode('_', $k); + $user = new self( + $username, + NULL, // password + NO_EMAIL_ADDRESS_SET, // e-mail address + $first_name, + NULL, // middle name + $last_name + ); - if (count($resourceProviderMetaData) == 1) { + $user->setUserType(XSEDE_USER_TYPE); // XSEDE User + $user->setPersonID($person_id); - $filteredRoleCategories[$k] = $v; + $user->setEmailAddress($email_address); - } - else if (!in_array($resourceProviderMetaData[1], $center_ids)) { + $user->saveUser(); - $filteredRoleCategories[$k] = $v; + // Role detection ------------------------------- - } + $user_role_set = array(ROLE_ID_USER); - }//foreach ($roleCategories as $k => $v) + if (self::isPrincipalInvestigator($person_id) === true) { + // Add PI role to the to-be-created user + $user_role_set[] = ROLE_ID_PRINCIPAL_INVESTIGATOR; - $roleCategories = array_merge($userRoles, array('separator'), $filteredRoleCategories); + $cc_org_id = self::isCampusChampion($person_id); - return json_encode($roleCategories); + if ($cc_org_id !== false) { - } + // Add CC role to the to-be-created user + $user_role_set[] = ROLE_ID_CAMPUS_CHAMPION; - // XSEDE-Centric functionality ========================================================= + $user->setInstitution($cc_org_id); - /* - * @function initializeXSEDEUser - * - * Manifests a XDUser from an XSEDE account (referenced by XSEDE username and the CN of the certificate) - * - * @param String $username (The XSEDE username (username;Formal Name) - * - * @returns an XDUser object - * - */ + } - public static function initializeXSEDEUser($username) { + } - list($xsede_username, $formal_name) = explode(';', $username); - list($first_name, $last_name) = explode(' ', $formal_name, 2); + $user->setRoles($user_role_set); - $person_id = self::resolvePersonIDFromXSEDEUsername($xsede_username); + // ---------------------------------------------- - $email_address = self::_getXSEDEEmailAddressFromPersonID($person_id); + $user->saveUser(); - $user = new self( - $username, - NULL, // password - NO_EMAIL_ADDRESS_SET, // e-mail address - $first_name, - NULL, // middle name - $last_name - ); + return $user; - $user->setUserType(XSEDE_USER_TYPE); // XSEDE User - $user->setPersonID($person_id); + }//initializeXSEDEUser - $user->setEmailAddress($email_address); + // -------------------------------- - $user->saveUser(); + /* + * @function deriveUserFromXSEDEUser + * + * Maps an XSEDE user to an XDUser + * + * @param String $username (The XSEDE username (username;Formal Name) + * + * @returns an XDUser object + * + */ - // Role detection ------------------------------- + public static function deriveUserFromXSEDEUser($username) + { - $user_role_set = array(ROLE_ID_USER); + $pdo = DB::factory('database'); - if (self::isPrincipalInvestigator($person_id) === true) { + $userCheck = $pdo->query( + "SELECT id FROM Users WHERE username=:username AND user_type=:user_type", + array( + 'username' => $username, + 'user_type' => XSEDE_USER_TYPE + ) + ); - // Add PI role to the to-be-created user - $user_role_set[] = ROLE_ID_PRINCIPAL_INVESTIGATOR; + if (count($userCheck) == 0) { + return NULL; + } - $user->setActiveRole(ROLE_ID_PRINCIPAL_INVESTIGATOR); + return self::getUserByID($userCheck[0]['id']); - $cc_org_id = self::isCampusChampion($person_id); + }//deriveUserFromXSEDEUser - if ($cc_org_id !== false) { + // -------------------------------- - // Add CC role to the to-be-created user - $user_role_set[] = ROLE_ID_CAMPUS_CHAMPION; + /* + * @function XSEDEUserExists + * + * Determines whether an XSEDE user is already established in our accounts registry + * + * @param String $username (The XSEDE username (username;Formal Name) + * + * @returns boolean + * + */ - $user->setInstitution($cc_org_id); + public static function XSEDEUserExists($username) + { - } + $pdo = DB::factory('database'); - } + $userCheck = $pdo->query( + 'SELECT id FROM moddb.Users WHERE username = :username AND user_type=:user_type', + array( + 'username' => $username, + 'user_type' => XSEDE_USER_TYPE + ) + ); - $user->setRoles($user_role_set); + return (count($userCheck) > 0); - // ---------------------------------------------- + }//XSEDEUserExists - $user->saveUser(); + // -------------------------------- - return $user; + /* + * @function isXSEDEUser + * + * Determines whether the user is an XSEDE-oriented user + * + * @returns boolean + * + */ - }//initializeXSEDEUser + public function isXSEDEUser() + { - // -------------------------------- + return ($this->getUserType() == XSEDE_USER_TYPE); - /* - * @function deriveUserFromXSEDEUser - * - * Maps an XSEDE user to an XDUser - * - * @param String $username (The XSEDE username (username;Formal Name) - * - * @returns an XDUser object - * - */ + }//isXSEDEUser - public static function deriveUserFromXSEDEUser($username) { + // -------------------------------- - $pdo = DB::factory('database'); + /* + * @function getXSEDEUsername + * + * Resolves the XSEDE username from the XDMoD-formatted username + * + * @returns String (the XSEDE username) + * + */ - $userCheck = $pdo->query( - "SELECT id FROM Users WHERE username=:username AND user_type=:user_type", - array( - 'username' => $username, - 'user_type' => XSEDE_USER_TYPE - ) - ); + public function getXSEDEUsername() + { - if (count($userCheck) == 0) { - return NULL; - } + if (strpos($this->getUsername(), ';') !== false) { - return self::getUserByID($userCheck[0]['id']); + list($xsede_username, $formal_name) = explode(';', $this->getUsername(), 2); - }//deriveUserFromXSEDEUser + return $xsede_username; - // -------------------------------- + } else { + throw new \Exception('The user is not a valid XSEDE user'); + } - /* - * @function XSEDEUserExists - * - * Determines whether an XSEDE user is already established in our accounts registry - * - * @param String $username (The XSEDE username (username;Formal Name) - * - * @returns boolean - * - */ + }//getXSEDEUsername - public static function XSEDEUserExists($username) { + // -------------------------------- - $pdo = DB::factory('database'); + /* + * @function resolvePersonIDFromXSEDEUsername + * + * Determines the person id from the XSEDE username + * + * @param String $username (The XSEDE username) + * + * @returns int (the person id corresponding to the username) + * + * @throws Exception if the username cannot be mapped to a person id (which may happen if the state of the production tgcdb is 'ahead' of our local copy) + * + * (Verified by Dave Hart) -- Every XSEDE user has a record in acct.system_accounts which pertains to the 'portal.teragrid' resource + * + */ - $userCheck = $pdo->query( - 'SELECT id FROM moddb.Users WHERE username = :username AND user_type=:user_type', - array( - 'username' => $username, - 'user_type' => XSEDE_USER_TYPE - ) - ); + public static function resolvePersonIDFromXSEDEUsername($username) + { - return (count($userCheck) > 0); + $pdo = DB::factory('database'); - }//XSEDEUserExists + $result = $pdo->query( + 'SELECT sa.person_id FROM modw.systemaccount AS sa, modw.resourcefact AS r WHERE sa.username=:username AND sa.resource_id = r.id AND r.name="portal.teragrid"', + array( + 'username' => $username + ) + ); - // -------------------------------- + if (count($result) == 0) { + throw new \Exception("Cannot locate information for user $username"); + } - /* - * @function isXSEDEUser - * - * Determines whether the user is an XSEDE-oriented user - * - * @returns boolean - * - */ + return $result[0]['person_id']; - public function isXSEDEUser() { + }//resolvePersonIDFromXSEDEUsername - return ($this->getUserType() == XSEDE_USER_TYPE); + // -------------------------------- - }//isXSEDEUser + /* + * @function _getXSEDEEmailAddressFromPersonID + * + * Determines the email address for an XSEDE user based on his/her person id + * + * @param int $person_id (The XSEDE person id) + * + * @returns string (the corresponding email address) + * If no e-mail address can be found (or the person id does not validate), then NO_EMAIL_ADDRESS_SET is returned + * + */ - // -------------------------------- + private static function _getXSEDEEmailAddressFromPersonID($person_id) + { - /* - * @function getXSEDEUsername - * - * Resolves the XSEDE username from the XDMoD-formatted username - * - * @returns String (the XSEDE username) - * - */ + $pdo = DB::factory('database'); - public function getXSEDEUsername() { + $result = $pdo->query( + 'SELECT email_address FROM modw.person WHERE id=:person_id', + array( + 'person_id' => $person_id + ) + ); - if (strpos($this->getUsername(), ';') !== false) { + return (count($result) > 0 && !empty($result[0]['email_address'])) ? $result[0]['email_address'] : NO_EMAIL_ADDRESS_SET; - list($xsede_username, $formal_name) = explode(';', $this->getUsername(), 2); + }//_getXSEDEEmailAddressFromPersonID - return $xsede_username; - } - else { - throw new \Exception('The user is not a valid XSEDE user'); - } - - }//getXSEDEUsername + public function getDisabledMenus($realms) + { + // Get the set of disabled menus for each role the user has. + $disabledMenusByRole = array(); - // -------------------------------- + foreach ($this->_roles as $role_abbrev) { - /* - * @function resolvePersonIDFromXSEDEUsername - * - * Determines the person id from the XSEDE username - * - * @param String $username (The XSEDE username) - * - * @returns int (the person id corresponding to the username) - * - * @throws Exception if the username cannot be mapped to a person id (which may happen if the state of the production tgcdb is 'ahead' of our local copy) - * - * (Verified by Dave Hart) -- Every XSEDE user has a record in acct.system_accounts which pertains to the 'portal.teragrid' resource - * - */ + if ($role_abbrev == 'dev') continue; - public static function resolvePersonIDFromXSEDEUsername($username) { + $role = \User\aRole::factory($this->_getFormalRoleName($role_abbrev)); + $disabledMenusByRole[$role_abbrev] = $role->getDisabledMenus($realms); - $pdo = DB::factory('database'); + } + $role = \User\aRole::factory($this->_getFormalRoleName('pub')); + $disabledMenusByRole['pub'] = $role->getDisabledMenus($realms); - $result = $pdo->query( - 'SELECT sa.person_id FROM modw.systemaccount AS sa, modw.resourcefact AS r WHERE sa.username=:username AND sa.resource_id = r.id AND r.name="portal.teragrid"', - array( - 'username' => $username - ) - ); + // If the user only has one role, return that role's menus immediately. + if (count($disabledMenusByRole) === 1) { + return reset($disabledMenusByRole); + } - if (count($result) == 0) { - throw new \Exception("Cannot locate information for user $username"); - } - - return $result[0]['person_id']; - - }//resolvePersonIDFromXSEDEUsername + // Select only menus that are disabled for every role the user has. + // (If any role has no disabled menus, an empty list can be returned + // immediately, as there can be no menus that will be available for + // every role.) + $returnData = array(); + foreach ($disabledMenusByRole as $role => $roleDisabledMenus) { + if (empty($roleDisabledMenus)) { + return $returnData; + } + } - // -------------------------------- + $checkedMenus = array(); + foreach ($disabledMenusByRole as $role => $roleDisabledMenus) { + foreach ($roleDisabledMenus as $roleDisabledMenu) { + $roleDisabledMenuId = $roleDisabledMenu['id']; + if (array_key_exists($roleDisabledMenuId, $checkedMenus)) { + continue; + } - /* - * @function _getXSEDEEmailAddressFromPersonID - * - * Determines the email address for an XSEDE user based on his/her person id - * - * @param int $person_id (The XSEDE person id) - * - * @returns string (the corresponding email address) - * If no e-mail address can be found (or the person id does not validate), then NO_EMAIL_ADDRESS_SET is returned - * - */ + $menuDisabledForAllRoles = true; + foreach ($disabledMenusByRole as $checkedRole => $checkedRoleDisabledMenus) { + if ($role === $checkedRole) { + continue; + } + + $checkedDisabledMenuFound = false; + foreach ($checkedRoleDisabledMenus as $checkedRoleDisabledMenu) { + if ($checkedRoleDisabledMenu['id'] === $roleDisabledMenuId) { + $checkedDisabledMenuFound = true; + break; + } + } + + if (!$checkedDisabledMenuFound) { + $menuDisabledForAllRoles = false; + break; + } + } - private static function _getXSEDEEmailAddressFromPersonID($person_id) { + $checkedMenus[$roleDisabledMenuId] = true; + if ($menuDisabledForAllRoles) { + $returnData[] = $roleDisabledMenu; + } + } + } - $pdo = DB::factory('database'); + return $returnData; + } - $result = $pdo->query( - 'SELECT email_address FROM modw.person WHERE id=:person_id', - array( - 'person_id' => $person_id - ) - ); - - return (count($result) > 0 && !empty($result[0]['email_address'])) ? $result[0]['email_address'] : NO_EMAIL_ADDRESS_SET; + /** + * Retrieve the Acls for this user. + * + * @param bool $names defaults to `false`. If true, then the names of the + * acls will be returned instead of the Acl objects themselves. + * @return Acl[]|string[] + */ + public function getAcls($names = false) + { + return (false === $names) + ? $this->_acls + : array_keys($this->_acls); + } // getAcls - }//_getXSEDEEmailAddressFromPersonID + /** + * Overwrite this users current set of acls with the provided ones. + * + * @param array[] $acls + */ + public function setAcls(array $acls) + { + $this->_acls = $acls; + } // setAcls + /** + * Add the provided acl to this users set of acls if they do not already + * have it. If the overwrite parameter is provided as true then it will be + * added ( or overwrite the existing acl ) regardless of whether or not the + * user currently has it. + * + * @param Acl $acl + * @param bool $overwrite + */ + public function addAcl(Acl $acl, $overwrite = false) + { + if ( ( !array_key_exists($acl->getName(), $this->_acls) && !$overwrite ) || + $overwrite === true + ) { + $this->_acls[$acl->getName()] = $acl; + } + } // addAcl - public function getDisabledMenus($realms) - { - // Get the set of disabled menus for each role the user has. - $disabledMenusByRole = array(); + /** + * Remove the provided acl from this users set of acls. + * + * @param Acl $acl + */ + public function removeAcl(Acl $acl) + { + if (array_key_exists($acl->getName(), $this->_acls)) { + unset($this->_acls[$acl->getName()]); + } + } // removeAcl - foreach($this->_roles as $role_abbrev) - { - - if ($role_abbrev == 'dev') continue; - - $role = \User\aRole::factory($this->_getFormalRoleName($role_abbrev)); - $disabledMenusByRole[$role_abbrev] = $role->getDisabledMenus($realms); - - } - $role = \User\aRole::factory($this->_getFormalRoleName('pub')); - $disabledMenusByRole['pub'] = $role->getDisabledMenus($realms); + /** + * Determine whether or not this user has a relation to the provided Acl. + * The acl + * + * @param Acl|string $acl + * @param string $property the name of the getter to use when determining if + * the user has the provided acl or not. Defaults to 'name'. + * + * @return bool true iff the acl is found in this users set of acls. + * @throws Exception if the provided acl is anything but an Acl or string. + */ + public function hasAcl($acl, $property = 'name') + { + $isAcl = $acl instanceof Acl; + $isString = is_string($acl); + $getter = 'get' . ucfirst($property); + if (false === $isAcl && false === $isString) { + $aclClass = get_class($acl); + throw new Exception("Unknown acl type encountered. Expected Acl or string got $aclClass."); + } + $value = $isAcl ? $acl->$getter() : $acl; + return array_key_exists($value, $this->_acls); + } // hasAcl - // If the user only has one role, return that role's menus immediately. - if (count($disabledMenusByRole) === 1) { - return reset($disabledMenusByRole); - } - - // Select only menus that are disabled for every role the user has. - // (If any role has no disabled menus, an empty list can be returned - // immediately, as there can be no menus that will be available for - // every role.) - $returnData = array(); - foreach ($disabledMenusByRole as $role => $roleDisabledMenus) { - if (empty($roleDisabledMenus)) { - return $returnData; - } - } - - $checkedMenus = array(); - foreach ($disabledMenusByRole as $role => $roleDisabledMenus) { - foreach ($roleDisabledMenus as $roleDisabledMenu) { - $roleDisabledMenuId = $roleDisabledMenu['id']; - if (array_key_exists($roleDisabledMenuId, $checkedMenus)) { - continue; - } - $menuDisabledForAllRoles = true; - foreach ($disabledMenusByRole as $checkedRole => $checkedRoleDisabledMenus) { - if ($role === $checkedRole) { - continue; - } - - $checkedDisabledMenuFound = false; - foreach ($checkedRoleDisabledMenus as $checkedRoleDisabledMenu) { - if ($checkedRoleDisabledMenu['id'] === $roleDisabledMenuId) { - $checkedDisabledMenuFound = true; - break; - } - } - - if (!$checkedDisabledMenuFound) { - $menuDisabledForAllRoles = false; - break; - } - } + /** + * Determine whether or not this user has a relation to all of the provided + * Acls. + * + * @param Acl[]|string[] $acls an array of Acls or an array of strings + * @param string $property the name of the getter to use when determining if + * the user has the provided set of acls or not. Defaults to 'name' + * + * @return bool true iff all of the acls are found in this users set of acls + * @throws Exception if any of the provided acls are not a string or Acl + */ + public function hasAcls(array $acls, $property = 'name') + { + $total = 0; + foreach ($acls as $acl) { + $found = $this->hasAcl($acl, $property); + $total += $found ? 1 : 0; + } + return $total === count($acls); + } // hasAcls - $checkedMenus[$roleDisabledMenuId] = true; - if ($menuDisabledForAllRoles) { - $returnData[] = $roleDisabledMenu; - } - } - } + /** + * Attempt to retrieve an XDUser instance based on the provided $username. + * + * @param string $username the identifier to use when attempting to retrieve + * the XDUser instance. + * + * @return null|XDUser null if the user cannot be found or if null is provided + * as the username, else an instantiated XDUser instance. + **/ + public static function getUserByUserName($username) + { + if (null === $username) { + return null; + } - return $returnData; - } + // Note: due to the complexity of getUserById ( and it being the sole + // repository of user creation logic ) we just retrieve the userId and + // feed that to the getUserById function. + $query = <<query($query, array(':username' => $username)); + if (count($row) > 0) { + $uid = $row[0]['id']; + return self::getUserByID($uid); + } + return null; + } // getUserByUserName }//XDUser diff --git a/configuration/etl/etl.d/acls-import.json b/configuration/etl/etl.d/acls-import.json index 886a1f6996..77ef60c4b8 100644 --- a/configuration/etl/etl.d/acls-import.json +++ b/configuration/etl/etl.d/acls-import.json @@ -23,6 +23,14 @@ } }, "acls-import": [ + { + "name": "acls.import.xdmod.public_user", + "description": "Imports the Public User if it does not already exist.", + "sql_file_list": [ + "acls/xdmod/create_public_user.sql" + ], + "enabled": true + }, { "name": "acls.import.xdmod.user_acls", "description": "Imports the records that relate which Users should have which Acls for xdmod", diff --git a/configuration/etl/etl_sql.d/acls/xdmod/create_public_user.sql b/configuration/etl/etl_sql.d/acls/xdmod/create_public_user.sql new file mode 100644 index 0000000000..9494cf3561 --- /dev/null +++ b/configuration/etl/etl_sql.d/acls/xdmod/create_public_user.sql @@ -0,0 +1,40 @@ +-- Create the public user if it doesn't already exist +INSERT INTO Users(username, email_address, first_name, last_name, time_created, time_last_updated, account_is_active, person_id, organization_id, field_of_science, user_type) +SELECT inc.* +FROM ( + SELECT + 'Public User' AS username, + 'public@ccr.xdmod.org' AS email_address, + 'Public' AS first_name, + 'User' AS last_name, + NOW() AS time_created, + NOW() AS time_last_updated, + TRUE AS account_is_active, + -1 AS person_id, + 0 AS organization_id, + 0 AS field_of_science, + ut.id AS user_type + FROM UserTypes ut + WHERE ut.type = 'Internal' +) inc +LEFT JOIN Users cur + ON cur.username = inc.username AND + cur.email_address = inc.email_address +WHERE cur.id IS NULL; + +-- Create the association between the public user and the public acl. +INSERT INTO user_acls(user_id, acl_id) +SELECT inc.* +FROM ( + SELECT + u.id AS user_id, + a.acl_id AS acl_id + FROM Users u, acls a + WHERE u.username = 'Public User' AND + a.name = 'pub' +) inc +LEFT JOIN user_acls cur + ON cur.user_id = inc.user_id AND + cur.acl_id = inc.acl_id +WHERE cur.user_acl_id IS NULL; + diff --git a/open_xdmod/modules/xdmod/component_tests/bootstrap.php b/open_xdmod/modules/xdmod/component_tests/bootstrap.php new file mode 100644 index 0000000000..5fc64410ff --- /dev/null +++ b/open_xdmod/modules/xdmod/component_tests/bootstrap.php @@ -0,0 +1,23 @@ +assertTrue($user !== null); + } + + public function testPublicUserIsPublicUser() + { + $user = XDUser::getPublicUser(); + + $this->assertTrue($user->isPublicUser()); + } + + public function testNonPublicUserIsNotPublicUser() + { + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $this->assertFalse($user->isPublicUser()); + } + + public function testIsDeveloperInvalid() + { + $user = XDUser::getUserByUserName(self::PUBLIC_USER_NAME); + $this->assertFalse($user->isDeveloper()); + } + + public function testIsManagerInvalid() + { + $user = XDUser::getUserByUserName(self::PUBLIC_USER_NAME); + $this->assertFalse($user->isManager()); + } + + public function testGetTokenAsPublic() + { + $user = XDUser::getPublicUser(); + $token = $user->getToken(); + $this->assertEquals('', $token); + } + + public function testGetTokenAsNonPublic() + { + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + $token = $user->getToken(); + $this->assertNotEquals('', $token); + } + + public function testGetTokenExpirationAsPublic() + { + $user = XDUser::getPublicUser(); + $expiration = $user->getTokenExpiration(); + $this->assertEquals('', $expiration); + } + + public function testGetTokenExpirationAsNonPublic() + { + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + $expiration = $user->getTokenExpiration(); + $this->assertNotEquals('', $expiration); + } + + public function testSetOrganizationsValid() + { + // NOTE: there is no validation of the organization id + + // TACC original is 561 ( IU ) + $validOrganizationId = 476; + $defaultConfig = array('active' => true, 'primary' => true); + + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + // RETRIEVE: the initial organizations + $originalOrganizations = $user->getOrganizationCollection(self::CENTER_DIRECTOR_ACL_NAME); + $this->assertTrue(count($originalOrganizations) > 0); + + // SET: the new one in it's place. + $user->setOrganizations( + array( + $validOrganizationId => $defaultConfig + ), + self::CENTER_DIRECTOR_ACL_NAME + ); + + // RETRIEVE: them again, this should now be the new one. + $newOrganizations = $user->getOrganizationCollection(self::CENTER_DIRECTOR_ACL_NAME); + $this->assertNotEmpty($newOrganizations); + $this->assertTrue(in_array($validOrganizationId, $newOrganizations)); + + $original = array(); + foreach(array_values($originalOrganizations) as $organizationId) { + $original[$organizationId] = $defaultConfig; + } + + // RESET: the organizations to the original. + $user->setOrganizations($original, self::CENTER_DIRECTOR_ACL_NAME); + } + + public function testSetInstitution() + { + $validInstitutionId = 476; + + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $originalInstitution = $user->getInstitution(); + $this->assertTrue($originalInstitution !== null); + $this->assertNotEquals('0', $originalInstitution); + + $user->setInstitution($validInstitutionId); + + $newInstitution = $user->getInstitution(); + $this->assertTrue($newInstitution !== null); + $this->assertEquals($validInstitutionId, $newInstitution); + + $user->setInstitution($originalInstitution); + + $checkInstitution = $user->getInstitution(); + $this->assertEquals($originalInstitution, $checkInstitution); + } + + public function testDisassociateWithInstitution() + { + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $originalInstitution = $user->getInstitution(); + + $user->disassociateWithInstitution(); + + $newInstitution = $user->getInstitution(); + $this->assertEquals('-1', $newInstitution); + + $user->setInstitution($originalInstitution); + + $institution = $user->getInstitution(); + + $this->assertEquals($originalInstitution, $institution); + } + + public function testSetOrganizationsEmpty() + { + $defaultConfig = array('active' => true, 'primary' => true); + + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $originalOrganizations = $user->getOrganizationCollection(self::CENTER_DIRECTOR_ACL_NAME); + + $this->assertTrue($originalOrganizations !== null); + $this->assertTrue(count($originalOrganizations) > 0); + + $user->setOrganizations(array(), self::CENTER_DIRECTOR_ACL_NAME); + + $newOrganizations = $user->getOrganizationCollection(self::CENTER_DIRECTOR_ACL_NAME); + $this->assertEmpty($newOrganizations); + + $original = array(); + foreach(array_values($originalOrganizations) as $organizationId) { + $original[$organizationId] = $defaultConfig; + } + $user->setOrganizations($original, self::CENTER_DIRECTOR_ACL_NAME); + + $organizations = $user->getOrganizationCollection(self::CENTER_DIRECTOR_ACL_NAME); + $this->assertEquals($originalOrganizations, $organizations); + } + + public function testGetRolesPublic() + { + $user = XDUser::getPublicUser(); + + $roles = $user->getRoles(); + + $this->assertTrue($roles !== null); + $this->assertTrue(count($roles) === 1); + $this->assertTrue(in_array(self::PUBLIC_ACL_NAME, $roles)); + } + + public function testGetRolesInformalEqualsGetAclNames() + { + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $roles = $user->getRoles(); + $acls = $user->getAcls(true); + + $this->assertEquals($roles, $acls); + } + + public function testGetRolesFormal() + { + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + $roles = $user->getRoles('formal'); + + $this->assertNotNull($roles); + $this->assertTrue(count($roles) > 0); + foreach($roles as $roleDisplay => $roleAbbrev) { + $abbrevLength = strlen($roleAbbrev); + $displayLength = strlen($roleDisplay); + $this->assertTrue($displayLength >= $abbrevLength); + } + } + + public function testGetRolesCasual() + { + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + $roles = $user->getRoles('casual'); + $this->assertNull($roles); + } + + public function testSetRolesEmpty() + { + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $originalRoles = $user->getRoles(); + + $this->assertTrue(count($originalRoles) > 0); + $this->assertTrue(in_array(self::CENTER_DIRECTOR_ACL_NAME, $originalRoles)); + + $user->setRoles(array()); + $user->saveUser(); + + $newRoles = $user->getRoles(); + $this->assertEmpty($newRoles); + + $user->setRoles($originalRoles); + $user->saveUser(); + + $roles = $user->getRoles(); + $this->assertEquals($originalRoles, $roles); + $this->assertTrue(in_array(self::CENTER_DIRECTOR_ACL_NAME, $roles)); + } + + public function testGetAcls() + { + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + $self = $this; + $acls = $user->getAcls(); + + $this->assertTrue(count($acls) > 0); + + foreach ($acls as $acl) { + $class = get_class($acl); + $isAcl = $class === 'Models\Acl'; + $this->assertTrue($isAcl); + } + } + + public function testGetAclNames() + { + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $acls = $user->getAcls(true); + $this->assertTrue(count($acls) > 0); + $this->assertTrue(in_array(self::CENTER_DIRECTOR_ACL_NAME, $acls)); + } + + public function testSetAclsEmpty() + { + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $originalAcls = $user->getAcls(); + $this->assertTrue(count($originalAcls) > 0); + + $user->setAcls(array()); + $user->saveUser(); + + $newAcls = $user->getAcls(); + $this->assertTrue(count($newAcls) === 0); + + $user->setAcls($originalAcls); + $user->saveUser(); + + $acls = $user->getAcls(); + $this->assertEquals($originalAcls, $acls); + } + + public function testAddNewAcl() + { + $newAcl = Acls::getAclByName(self::PRINCIPAL_INVESTIGTOR_ACL_NAME); + $this->assertNotNull($newAcl); + + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $originalAcls = $user->getAcls(true); + $this->assertTrue(count($originalAcls) > 0); + $this->assertFalse(in_array($newAcl->getName(), $originalAcls)); + + $user->addAcl($newAcl); + $user->saveUser(); + + $newAcls = $user->getAcls(true); + $this->assertTrue(count($originalAcls) > 0); + $this->assertTrue(in_array($newAcl->getName(), $newAcls)); + + $user->removeAcl($newAcl); + $user->saveUser(); + + $acls = $user->getAcls(true); + $this->assertTrue(count($originalAcls) > 0); + $this->assertFalse(in_array($newAcl->getName(), $acls)); + } + + public function testAddExistingAclNoOverwrite() + { + $existingAcl = Acls::getAclByName(self::CENTER_DIRECTOR_ACL_NAME); + + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $originalAcls = $user->getAcls(true); + $this->assertTrue(count($originalAcls) > 0); + $this->assertTrue(in_array($existingAcl->getName(), $originalAcls)); + + $user->addAcl($existingAcl); + $user->saveUser(); + + $newAcls = $user->getAcls(true); + $this->assertTrue(count($originalAcls) > 0); + $this->assertTrue(in_array($existingAcl->getName(), $newAcls)); + $this->assertEquals($originalAcls, $newAcls); + } + + + public function testAddExistingAclOverwrite() + { + $existingAcl = Acls::getAclByName(self::CENTER_DIRECTOR_ACL_NAME); + + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $originalAcls = $user->getAcls(true); + $this->assertTrue(count($originalAcls) > 0); + $this->assertTrue(in_array($existingAcl->getName(), $originalAcls)); + + $user->addAcl($existingAcl, true); + $user->saveUser(); + + $newAcls = $user->getAcls(true); + $this->assertTrue(count($originalAcls) > 0); + $this->assertTrue(in_array($existingAcl->getName(), $newAcls)); + $this->assertEquals($originalAcls, $newAcls); + } + + public function testHasAclExists() + { + $existingAcl = Acls::getAclByName(self::CENTER_DIRECTOR_ACL_NAME); + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $hasAcl = $user->hasAcl($existingAcl); + $this->assertTrue($hasAcl); + } + + public function testHasAclNotExists() + { + $existingAcl = Acls::getAclByName(self::PRINCIPAL_INVESTIGTOR_ACL_NAME); + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $hasAcl = $user->hasAcl($existingAcl); + $this->assertFalse($hasAcl); + } + + public function testHasAclsExists() + { + $acls = array(); + $acls []= Acls::getAclByName(self::CENTER_DIRECTOR_ACL_NAME); + $acls []= Acls::getAclByName('usr'); + + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $hasAcls = $user->hasAcls($acls); + $this->assertTrue($hasAcls); + } + + public function testHasAclsNotExists() + { + $acls = array('dev', 'mgr'); + + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $hasAcls = $user->hasAcls($acls); + $this->assertFalse($hasAcls); + } + + public function testHasAclsPartialExists() + { + $acls = array('dev', 'cd'); + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + + $hasAcls = $user->hasAcls($acls); + $this->assertFalse($hasAcls); + } + + public function testGetUserByUserNameValid() + { + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + $this->assertNotNull($user); + $this->assertNotNull($user->getUserID()); + } + + public function testGetUserByUserNameInvalid() + { + $user = XDUser::getUserByUserName("bilbo"); + $this->assertNull($user); + } + + public function testGetUserByUserNameEmptyString() + { + $user = XDUser::getUserByUserName(""); + $this->assertNull($user); + } + + public function testGetUserByUserNameNull() + { + $user = XDUser::getUserByUserName(null); + $this->assertNull($user); + } + + /** + * @expectedException Exception + **/ + public function testHasAclWithNonAclTypeShouldThrowException() + { + $acl = new \StdClass; + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + $user->hasAcl($acl); + } + + public function testUserIsManager() + { + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + $isManager = $user->isManager(); + $this->assertFalse($isManager); + } + + public function testGetPrimaryRoleWithPublicUser() + { + $user = XDUser::getPublicUser(); + $primaryRole = $user->getPrimaryRole(); + + $this->assertNotNull($primaryRole); + } + + /** + * @expectedException Exception + **/ + public function testGetPrimaryRoleWithNewUser() + { + $user = new XDUser('test', null, 'test@ccr.xdmod.org', 'test', 'a', 'user'); + $primaryRole = $user->getPrimaryRole(); + } + + public function testGetActiveRoleWithPublicUser() + { + $user = XDUser::getPublicUser(); + $activeRole = $user->getActiveRole(); + + $this->assertNotNull($activeRole); + } + + /** + * @expectedException Exception + **/ + public function testGetActiveRoleWithNewUserShouldFail() + { + $user = new XDUser('test', null, 'test@ccr.xdmod.org', 'test', 'a', 'user'); + $activeRole = $user->getActiveRole(); + } + + /** + * Expect that it should complain about not having a valid user type. + * + * @expectedException Exception + **/ + public function testCreateUserWithoutUserTypeShouldFail() + { + $user = new XDUser('test', null, 'test@ccr.xdmod.org', 'test', 'a', 'user'); + + $this->assertEquals('0', $user->getUserID()); + + $user->saveUser(); + + $this->assertNotNull($user->getUserID()); + } + + public function testCreateUser() + { + $user = new XDUser('test', null, 'test@ccr.xdmod.org', 'test', 'a', 'user'); + + $this->assertEquals('0', $user->getUserID()); + + $user->setUserType(XSEDE_USER_TYPE); + + $user->saveUser(); + + $this->assertNotNull($user->getUserID()); + } + + /** + * Expect that it should complain about there already being a test user. + * + * @expectedException Exception + **/ + public function testCreateUserWithExistingUserNameShouldFail() + { + $anotherUser = new XDUser('test', null, 'test@ccr.xdmod.org', 'test', 'a', 'user'); + $anoterUser->setUserType(XSEDE_USER_TYPE); + $anotherUser->saveUser(); + } + + /** + * @expectedException Exception + **/ + public function testCreateUserWithExistingEmailShouldFail() + { + $anotherUser = new XDUser('test2', null, 'public@ccr.xdmod.org', 'public', 'a', 'user'); + } + + /** + * @expectedException Exception + **/ + public function testSaveUserWithSameEmailAndNotXsedeTypeAndNoIdShouldFail() + { + $anotherUser = new XDUser('test2', null, 'public@ccr.xdmod.org', 'public', 'a', 'user'); + $anotherUser->setUserType(DEMO_USER_TYPE); + $anotherUser->saveUser(); + } + + public function testRemoveUser() + { + $user = XDUser::getUserByUserName('test'); + + $this->assertNotNull($user); + + $user->removeUser(); + } + + /** + * Cannot remove the public user + * + * @expectedException Exception + **/ + public function testRemovePublicUserShouldFail() + { + $user = XDUser::getPublicUser(); + + $user->removeUser(); + } + + /** + * @expectedException Exception + **/ + public function testSavePublicUserShouldFail() + { + $user = XDUser::getPublicUser(); + $user->saveUser(); + } + + /** + * @expectedException Exception + **/ + public function testSaveUserWithDefaultUserType() + { + $user = XDUser::getUserByUserName(self::CENTER_DIRECTOR_USER_NAME); + $user->setUserType(0); + $user->saveUser(); + } +} diff --git a/open_xdmod/modules/xdmod/component_tests/phpunit.xml.dist b/open_xdmod/modules/xdmod/component_tests/phpunit.xml.dist new file mode 100644 index 0000000000..578d81b697 --- /dev/null +++ b/open_xdmod/modules/xdmod/component_tests/phpunit.xml.dist @@ -0,0 +1,21 @@ + + diff --git a/open_xdmod/modules/xdmod/component_tests/runtests.sh b/open_xdmod/modules/xdmod/component_tests/runtests.sh new file mode 100755 index 0000000000..3d22d6d8c9 --- /dev/null +++ b/open_xdmod/modules/xdmod/component_tests/runtests.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +PHPUNITARGS="$@" + +cd $(dirname $0) +phpunit="$(readlink -f ../../../../vendor/bin/phpunit)" + +if [ ! -x "$phpunit" ]; then + echo phpunit not found, run \"composer install\" 1>&2 + exit 127 +fi + +$phpunit ${PHPUNITARGS} . diff --git a/shippable.yml b/shippable.yml index 76b2c8a520..df3c8742cb 100644 --- a/shippable.yml +++ b/shippable.yml @@ -18,6 +18,9 @@ build: - composer install --no-progress - cp ~/assets/secrets open_xdmod/modules/xdmod/integration_tests/.secrets - ./open_xdmod/modules/xdmod/integration_tests/runtests.sh --log-junit `pwd`/shippable/testresults/results.xml + - cp ./configuration/portal_settings.ini ./configuration/portal_settings.ini.old + - cp -f /etc/xdmod/portal_settings.ini ./configuration/portal_settings.ini + - ./open_xdmod/modules/xdmod/component_tests/runtests.sh --log-junit `pwd`/shippable/testresults/componentresults.xml + - mv ./configuration/portal_settings.ini.old ./configuration/portal_settings.ini on_failure: - cat /var/log/xdmod/* - \ No newline at end of file