allowGuest = $allowGuest; $this->connectionFactory = $connectionFactory; $this->connectionOptions = $connectionOptions; $this->usersTable = $usersTableInfo['TableName']; $this->users_UserId = $usersTableInfo['UserId']; $this->users_UserName = $usersTableInfo['UserName']; $this->users_Password = $usersTableInfo['Password']; $this->userPermsTable = $userPermsTableInfo['TableName']; $this->userPerms_UserId = $userPermsTableInfo['UserId']; $this->userPerms_PageName = $userPermsTableInfo['PageName']; $this->userPerms_Grant = $userPermsTableInfo['Grant']; $this->tableCaptions = $tableCaptions; $this->passwordHasher = $passwordHasher; $this->adminGrantCache = array(); } private function RetrieveSecurityInfo($userName, $dataSourceName) { $queryBuilder = new SelectCommand($this->connectionFactory->CreateEngCommandImp()); $queryBuilder->AddField($this->usersTable, $this->users_UserId, FieldType::Number, 'users_user_id'); $queryBuilder->AddField($this->usersTable, $this->users_UserName, FieldType::String, 'users_user_name'); $queryBuilder->AddField($this->userPermsTable, $this->userPerms_UserId, FieldType::Number, 'userperms_user_id'); $queryBuilder->AddField($this->userPermsTable, $this->userPerms_PageName, FieldType::String, 'userperms_pagename'); $queryBuilder->AddField($this->userPermsTable, $this->userPerms_Grant, FieldType::String, 'userperms_grant'); $queryBuilder->SetSourceTableName($this->userPermsTable); $queryBuilder->AddJoin(JoinKind::LeftOuter, $this->usersTable, 'userperms_user_id', $this->users_UserId); if ($userName == 'guest') { $queryBuilder->AddFieldFilter('userperms_user_id', new FieldFilter('-1', '=')); } else { $queryBuilder->AddCompositeFieldFilter('OR', array( 'users_user_name', 'userperms_user_id' ), array( new FieldFilter($userName, 'ILIKE'), new FieldFilter('0', '=') )); } $queryBuilder->AddCompositeFieldFilter('OR', array( 'userperms_pagename', 'userperms_pagename' ), array( new FieldFilter($dataSourceName, 'ILIKE'), new FieldFilter('', '=') )); $dataset = new QueryDataset($this->connectionFactory, $this->connectionOptions, $queryBuilder->GetSQL(), array(), array(), array(), 'user_grants'); $dataset->AddField(new StringField('userperms_grant'), false); $result = null; $dataset->Open(); $selectGrant = false; $updateGrant = false; $insertGrant = false; $deleteGrant = false; $adminGrant = false; while ($dataset->Next()) { $grant = $dataset->GetFieldValueByName('userperms_grant'); $selectGrant = $selectGrant || StringUtils::SameText($grant, 'select'); $updateGrant = $updateGrant || StringUtils::SameText($grant, 'update'); $insertGrant = $insertGrant || StringUtils::SameText($grant, 'insert'); $deleteGrant = $deleteGrant || StringUtils::SameText($grant, 'delete'); $adminGrant = $adminGrant || StringUtils::SameText($grant, 'admin'); if ($adminGrant) { $result = new AdminDataSourceSecurityInfo(); break; } } $dataset->Close(); return !is_null($result) ? $result : new DataSourceSecurityInfo($selectGrant, $updateGrant, $insertGrant, $deleteGrant); } /** * @param $userName * @param $dataSourceName * @return IDataSourceSecurityInfo */ public function GetSecurityInfo($userName, $dataSourceName) { $result = null; if (isset($this->securityCache[$userName])) if (isset($this->securityCache[$userName][$dataSourceName])) $result = $this->securityCache[$userName][$dataSourceName]; if (is_null($result)) { $result = $this->RetrieveSecurityInfo($userName, $dataSourceName); if (!isset($this->securityCache[$userName])) $this->securityCache[$userName] = array(); if (!isset($this->securityCache[$userName][$dataSourceName])) $this->securityCache[$userName][$dataSourceName] = $result; } return $result; } private function CreateUsersDataset() { $usersDataset = new TableDataset($this->connectionFactory, $this->connectionOptions, $this->usersTable); $usersDataset->AddField(new IntegerField($this->users_UserId), true); $usersDataset->AddField(new StringField($this->users_UserName), false); $usersDataset->AddField(new StringField($this->users_Password), false); return $usersDataset; } private function CreateUserGrantsDataset() { $result = new TableDataset($this->connectionFactory, $this->connectionOptions, $this->userPermsTable); $result->AddField(new IntegerField($this->userPerms_UserId), true); $result->AddField(new StringField($this->userPerms_PageName), true); $result->AddField(new StringField($this->userPerms_Grant), true); return $result; } /** * {@inheritdoc} */ public function CanAddUser() { return true; } /** * {@inheritdoc} */ public function AddUser($id, $userName, $password) { $usersDataset = $this->CreateUsersDataset(); $usersDataset->Insert(); $usersDataset->SetFieldValueByName($this->users_UserId, $id); $usersDataset->SetFieldValueByName($this->users_UserName, $userName); $usersDataset->SetFieldValueByName($this->users_Password, $this->passwordHasher->GetHash($password)); $usersDataset->Post(); } /** * {@inheritdoc} */ public function CanChangeUserName() { return true; } /** * {@inheritdoc} */ public function ChangeUserName($user_id, $userName) { $usersDataset = $this->CreateUsersDataset(); $usersDataset->SetSingleRecordState(array($user_id)); $usersDataset->Open(); if ($usersDataset->Next()) { $usersDataset->Edit(); $usersDataset->SetFieldValueByName($this->users_UserName, $userName); $usersDataset->Post(); } $usersDataset->Close(); return $userName; } /** * {@inheritdoc} */ public function CanChangeUserPassword() { return true; } /** * {@inheritdoc} */ public function ChangeUserPassword($user_id, $password) { $usersDataset = $this->CreateUsersDataset(); $usersDataset->SetSingleRecordState(array($user_id)); $usersDataset->Open(); if ($usersDataset->Next()) { $usersDataset->Edit(); $usersDataset->SetFieldValueByName($this->users_Password, $this->passwordHasher->GetHash($password)); $usersDataset->Post(); } $usersDataset->Close(); } /** * {@inheritdoc} */ public function CanRemoveUser() { return true; } /** * {@inheritdoc} */ public function RemoveUser($userId) { $usersDataset = $this->CreateUsersDataset(); $usersDataset->SetSingleRecordState(array($userId)); $usersDataset->Open(); if ($usersDataset->Next()) { $usersDataset->Delete(); } else { throw new Exception('User with user id = ' . $userId . ' does not exists.'); } $usersDataset->Close(); } /** * @param string $userName * @return boolean */ public function RetrieveAdminGrant($userName) { $queryBuilder = new SelectCommand($this->connectionFactory->CreateEngCommandImp()); $queryBuilder->AddField($this->usersTable, $this->users_UserId, FieldType::Number, 'users_user_id'); $queryBuilder->AddField($this->usersTable, $this->users_UserName, FieldType::String, 'users_user_name'); $queryBuilder->AddField($this->userPermsTable, $this->userPerms_UserId, FieldType::Number, 'userperms_user_id'); $queryBuilder->AddField($this->userPermsTable, $this->userPerms_PageName, FieldType::String, 'userperms_pagename'); $queryBuilder->AddField($this->userPermsTable, $this->userPerms_Grant, FieldType::String, 'userperms_grant'); $queryBuilder->SetSourceTableName($this->userPermsTable); $queryBuilder->AddJoin(JoinKind::Inner, $this->usersTable, 'userperms_user_id', $this->users_UserId); $queryBuilder->AddFieldFilter('users_user_name', new FieldFilter($userName, 'ILIKE')); $queryBuilder->AddFieldFilter('userperms_grant', new FieldFilter('ADMIN', 'ILIKE')); $queryBuilder->AddCompositeFieldFilter('OR', array('userperms_pagename', 'userperms_pagename'), array(new FieldFilter('', 'ILIKE'), new IsNullFieldFilter())); $dataset = new QueryDataset($this->connectionFactory, $this->connectionOptions, $queryBuilder->GetSQL(), array(), array(), array(), 'user_grants'); $dataset->AddField(new StringField('userperms_grant'), false); $dataset->Open(); if ($dataset->Next()) { $dataset->Close(); return true; } $dataset->Close(); return false; } public function HasAdminGrant($userName) { if (!isset($this->adminGrantCache[$userName])) $this->adminGrantCache[$userName] = $this->RetrieveAdminGrant($userName); return $this->adminGrantCache[$userName]; } /** * @param int $userId * @param Captions $captions * @return array */ public function GetUserGrants($userId, Captions $captions) { $queryBuilder = new SelectCommand($this->connectionFactory->CreateEngCommandImp()); $queryBuilder->AddField($this->usersTable, $this->users_UserId, FieldType::Number, 'users_user_id'); $queryBuilder->AddField($this->usersTable, $this->users_UserName, FieldType::String, 'users_user_name'); $queryBuilder->AddField($this->userPermsTable, $this->userPerms_UserId, FieldType::Number, 'userperms_user_id'); $queryBuilder->AddField($this->userPermsTable, $this->userPerms_PageName, FieldType::String, 'userperms_pagename'); $queryBuilder->AddField($this->userPermsTable, $this->userPerms_Grant, FieldType::String, 'userperms_grant'); $queryBuilder->SetSourceTableName($this->userPermsTable); $queryBuilder->AddJoin(JoinKind::LeftOuter, $this->usersTable, 'userperms_user_id', $this->users_UserId); $queryBuilder->AddFieldFilter('userperms_user_id', new FieldFilter($userId, '=')); $dataset = new QueryDataset($this->connectionFactory, $this->connectionOptions, $queryBuilder->GetSQL(), array(), array(), array(), 'user_grants'); $dataset->AddField(new StringField('userperms_grant'), false); $dataset->AddField(new StringField('userperms_pagename'), false); $dataset->Open(); $pages = array(); $pages[''] = array( 'name' => '', 'caption' => $captions->GetMessageString('Application'), 'selectGrant' => false, 'updateGrant' => false, 'insertGrant' => false, 'deleteGrant' => false, 'adminGrant' => false ); foreach($this->tableCaptions as $name => $caption) $pages[$name] = array( 'name' => $name, 'caption' => $captions->RenderText($caption), 'selectGrant' => false, 'updateGrant' => false, 'insertGrant' => false, 'deleteGrant' => false, 'adminGrant' => false ); while ($dataset->Next()) { $grant = $dataset->GetFieldValueByName('userperms_grant'); $pageName = $dataset->GetFieldValueByName('userperms_pagename'); if (isset($pages[$pageName])) { $pages[$pageName]['selectGrant'] = $pages[$pageName]['selectGrant'] || StringUtils::SameText($grant, 'select'); $pages[$pageName]['updateGrant'] = $pages[$pageName]['updateGrant'] || StringUtils::SameText($grant, 'update'); $pages[$pageName]['insertGrant'] = $pages[$pageName]['insertGrant'] || StringUtils::SameText($grant, 'insert'); $pages[$pageName]['deleteGrant'] = $pages[$pageName]['deleteGrant'] || StringUtils::SameText($grant, 'delete'); $pages[$pageName]['adminGrant'] = $pages[$pageName]['adminGrant'] || StringUtils::SameText($grant, 'admin'); } } $dataset->Close(); return array_values($pages); } /** * @param int $userId * @param Captions $captions * @return string */ public function GetUserGrantsAsJson($userId, Captions $captions) { return SystemUtils::ToJSON(array('status' => 'OK', 'result' => $this->GetUserGrants($userId, $captions))); } public function GetAllUsersAsJson() { $usersDataset = $this->CreateUsersDataset(); $usersDataset->Open(); $users = array(); if ($this->allowGuest) array_push($users, array( 'id' => -1, 'name' => 'guest', 'password' => '******', 'editable' => false )); array_push($users, array( 'id' => 0, 'name' => 'PUBLIC (All users)', 'password' => '******', 'editable' => false )); while ($usersDataset->Next()) { $user = array( 'id' => $usersDataset->GetFieldValueByName($this->users_UserId), 'name' => $usersDataset->GetFieldValueByName($this->users_UserName), 'password' => '******', 'editable' => true ); array_push($users, $user); } $usersDataset->Close(); return SystemUtils::ToJSON($users); } public function FillEmptyPagePermsArray(&$pagePerms) { foreach($this->tableCaptions as $name => $caption) array_push( $pagePerms, array( 'pageName' => $name, 'pageCaption' => $caption, 'acl' => '' )); } public function AddUserGrant($user_id, $page_name, $grant) { if ($this->NormalizeGrant($grant) != null) { $userGrants = $this->CreateUserGrantsDataset(); $userGrants->Insert(); $userGrants->SetFieldValueByName($this->userPerms_UserId, $user_id); $userGrants->SetFieldValueByName($this->userPerms_PageName, $page_name); $userGrants->SetFieldValueByName($this->userPerms_Grant, $this->NormalizeGrant($grant)); $userGrants->Post(); } else throw new Exception("$grant is not valid grant name."); } public function RemoveUserGrant($user_id, $page_name, $grant) { if ($this->NormalizeGrant($grant) != null) { $userGrants = $this->CreateUserGrantsDataset(); $userGrants->AddFieldFilter($this->userPerms_PageName, new FieldFilter($page_name, '=')); $userGrants->AddFieldFilter($this->userPerms_UserId, new FieldFilter($user_id, '=')); $userGrants->Open(); while($userGrants->Next()) { if (StringUtils::SameText($userGrants->GetFieldValueByName($this->userPerms_Grant), $grant)) { $userGrants->Delete(); $userGrants->Close(); return true; } } $userGrants->Close(); throw new Exception("User with id = $user_id has no $grant grant."); } else throw new Exception("$grant is not valid grant name."); } private function NormalizeGrant($grant) { if (StringUtils::SameText($grant, 'SELECT')) return 'SELECT'; if (StringUtils::SameText($grant, 'UPDATE')) return 'UPDATE'; if (StringUtils::SameText($grant, 'INSERT')) return 'INSERT'; if (StringUtils::SameText($grant, 'DELETE')) return 'DELETE'; if (StringUtils::SameText($grant, 'ADMIN')) return 'ADMIN'; return null; } }