Skip to content

Commit 0ef4f2e

Browse files
committed
[!!!][FEATURE] Support TYPO3 v8 & v9 by using DBAL
2 parents 2c5b39f + 9e903e6 commit 0ef4f2e

File tree

3 files changed

+171
-39
lines changed

3 files changed

+171
-39
lines changed

Classes/SecurityService.php

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,22 @@
1515
* GNU General Public License for more details.
1616
*/
1717

18-
use TYPO3\CMS\Core\Database\DatabaseConnection;
18+
use TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory;
19+
use TYPO3\CMS\Core\Crypto\Random;
20+
use TYPO3\CMS\Core\Database\ConnectionPool;
21+
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
1922
use TYPO3\CMS\Core\DataHandling\DataHandler;
2023
use TYPO3\CMS\Core\Utility\GeneralUtility;
21-
use TYPO3\CMS\Saltedpasswords\Salt\SaltFactory;
2224

2325
/**
2426
* Class SecurityService
2527
*/
2628
class SecurityService
2729
{
2830
/**
29-
* @var DatabaseConnection
31+
* @var ConnectionPool
3032
*/
31-
protected $database;
33+
protected $connectionPool;
3234

3335
/**
3436
* SecurityService constructor.
@@ -37,7 +39,7 @@ class SecurityService
3739
*/
3840
public function __construct()
3941
{
40-
$this->database = $GLOBALS['TYPO3_DB'];
42+
$this->connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
4143
}
4244

4345
/**
@@ -49,7 +51,7 @@ public function processDatamap_beforeStart(DataHandler $dataHandler)
4951
foreach (array_keys($dataHandler->datamap['tx_t3amserver_client']) as $uid) {
5052
if (is_string($uid) && 0 === strpos($uid, 'NEW')) {
5153
$dataHandler->datamap['tx_t3amserver_client'][$uid]['token'] = GeneralUtility::hmac(
52-
GeneralUtility::generateRandomBytes(256),
54+
GeneralUtility::makeInstance(Random::class)->generateRandomBytes(256),
5355
'tx_t3amserver_client'
5456
);
5557
}
@@ -66,8 +68,17 @@ public function isValid($token)
6668
if (!is_string($token)) {
6769
return false;
6870
}
69-
$where = 'token = ' . $this->database->fullQuoteStr($token, 'tx_t3amserver_client');
70-
return (bool)$this->database->exec_SELECTcountRows('*', 'tx_t3amserver_client', $where);
71+
72+
$queryBuilder = $this->connectionPool->getQueryBuilderForTable('tx_t3amserver_client');
73+
74+
return (bool)$queryBuilder
75+
->count('*')
76+
->from('tx_t3amserver_client')
77+
->where($queryBuilder
78+
->expr()
79+
->eq('token', $queryBuilder->createNamedParameter($token)))
80+
->execute()
81+
->fetchColumn();
7182
}
7283

7384
/**
@@ -85,29 +96,68 @@ public function createEncryptionKey()
8596
openssl_pkey_export($res, $privateKey);
8697
$pubKey = openssl_pkey_get_details($res);
8798

88-
$this->database->exec_INSERTquery('tx_t3amserver_keys', ['key_value' => base64_encode($privateKey)]);
89-
return ['pubKey' => base64_encode($pubKey['key']), 'encryptionId' => $this->database->sql_insert_id()];
99+
$this->getKeysQueryBuilder()
100+
->insert('tx_t3amserver_keys')
101+
->values(['key_value' => base64_encode($privateKey)])
102+
->execute();
103+
104+
return [
105+
'pubKey' => base64_encode($pubKey['key']),
106+
'encryptionId' => $this->connectionPool
107+
->getConnectionForTable('tx_t3amserver_keys')
108+
->lastInsertId()
109+
];
90110
}
91111

92112
public function authUser($user, $password, $encryptionId)
93113
{
94-
$where = 'uid = ' . (int)$encryptionId;
114+
$queryBuilder = $this->getKeysQueryBuilder();
115+
116+
$where = $queryBuilder
117+
->expr()
118+
->eq('uid', $queryBuilder->createNamedParameter((int)$encryptionId));
95119

96-
$keyRow = $this->database->exec_SELECTgetSingleRow('*', 'tx_t3amserver_keys', $where);
97-
if (!is_array($keyRow)) {
120+
$keyRow = $queryBuilder
121+
->select('*')
122+
->from('tx_t3amserver_keys')
123+
->where($where)
124+
->execute()
125+
->fetch();
126+
127+
if (empty($keyRow) || !is_array($keyRow)) {
98128
return false;
99129
}
100-
$this->database->exec_DELETEquery('tx_t3amserver_keys', $where);
130+
131+
$queryBuilder = $this->getKeysQueryBuilder();
132+
133+
$where = $queryBuilder
134+
->expr()
135+
->eq('uid', $queryBuilder->createNamedParameter((int)$encryptionId));
136+
137+
$queryBuilder
138+
->delete('tx_t3amserver_keys')
139+
->where($where)
140+
->execute();
101141

102142
$privateKey = base64_decode($keyRow['key_value']);
103143
$password = base64_decode(urldecode($password));
144+
104145
if (!@openssl_private_decrypt($password, $decryptedPassword, $privateKey)) {
105146
return false;
106147
}
107148

108149
$userRow = GeneralUtility::makeInstance(UserRepository::class)->getUser($user);
109150

110-
$saltingInstance = SaltFactory::getSaltingInstance($userRow['password']);
111-
return $saltingInstance->checkPassword($decryptedPassword, $userRow['password']);
151+
return GeneralUtility::makeInstance(PasswordHashFactory::class)
152+
->get($userRow['password'], 'BE')
153+
->checkPassword($decryptedPassword, $userRow['password']);
154+
}
155+
156+
/**
157+
* @return QueryBuilder
158+
*/
159+
private function getKeysQueryBuilder()
160+
{
161+
return $this->connectionPool->getQueryBuilderForTable('tx_t3amserver_keys');
112162
}
113163
}

Classes/UserRepository.php

Lines changed: 103 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,23 @@
1515
* GNU General Public License for more details.
1616
*/
1717

18-
use TYPO3\CMS\Backend\Utility\BackendUtility;
19-
use TYPO3\CMS\Core\Database\DatabaseConnection;
18+
use TYPO3\CMS\Core\Database\ConnectionPool;
19+
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
20+
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
2021
use TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException;
2122
use TYPO3\CMS\Core\Resource\File;
2223
use TYPO3\CMS\Core\Resource\ResourceFactory;
24+
use TYPO3\CMS\Core\Utility\GeneralUtility;
2325

2426
/**
2527
* Class UserRepository
2628
*/
2729
class UserRepository
2830
{
2931
/**
30-
* @var DatabaseConnection
32+
* @var ConnectionPool
3133
*/
32-
protected $connection = null;
34+
protected $connectionPool;
3335

3436
/**
3537
* @var array
@@ -59,7 +61,7 @@ class UserRepository
5961
*/
6062
public function __construct()
6163
{
62-
$this->connection = $GLOBALS['TYPO3_DB'];
64+
$this->connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
6365
}
6466

6567
/**
@@ -69,16 +71,40 @@ public function __construct()
6971
*/
7072
public function getUserState($user)
7173
{
72-
$where = 'username = ' . $this->connection->fullQuoteStr($user, 'be_users');
73-
$whereActive = $where . BackendUtility::deleteClause('be_users') . BackendUtility::BEenableFields('be_users');
74+
$queryBuilder = $this->getBeUserQueryBuilder();
7475

75-
if ($this->connection->exec_SELECTcountRows('*', 'be_users', $whereActive)) {
76+
$count = $queryBuilder
77+
->count('*')
78+
->from('be_users')
79+
->where($this->getWhereForUserName($queryBuilder, $user))
80+
->execute()
81+
->fetchColumn();
82+
83+
/** @var DeletedRestriction $restriction */
84+
$restriction = GeneralUtility::makeInstance(DeletedRestriction::class);
85+
86+
$queryBuilder = $this->getBeUserQueryBuilder();
87+
88+
$queryBuilder
89+
->getRestrictions()
90+
->removeAll()
91+
->add($restriction);
92+
93+
$countActive = $queryBuilder
94+
->count('*')
95+
->from('be_users')
96+
->where($this->getWhereForUserName($queryBuilder, $user))
97+
->execute()
98+
->fetchColumn();
99+
100+
if ($countActive) {
76101
return 'okay';
77102
}
78103

79-
if ($this->connection->exec_SELECTcountRows('*', 'be_users', $where)) {
104+
if ($count) {
80105
return 'deleted';
81106
}
107+
82108
return 'unknown';
83109
}
84110

@@ -89,8 +115,30 @@ public function getUserState($user)
89115
*/
90116
public function getUser($user)
91117
{
92-
$where = 'username = ' . $this->connection->fullQuoteStr($user, 'be_users');
93-
return $this->connection->exec_SELECTgetSingleRow(implode(',', $this->fields), 'be_users', $where);
118+
$queryBuilder = $this->getBeUserQueryBuilder();
119+
120+
return $queryBuilder
121+
->select(...$this->fields)
122+
->from('be_users')
123+
->where($this->getWhereForUserName($queryBuilder, $user))
124+
->execute()
125+
->fetch();
126+
}
127+
128+
/**
129+
* @param $queryBuilder QueryBuilder
130+
* @param $userName
131+
* @return String
132+
*/
133+
protected function getWhereForUserName($queryBuilder, $userName)
134+
{
135+
$queryBuilder
136+
->getRestrictions()
137+
->removeAll();
138+
139+
return $queryBuilder
140+
->expr()
141+
->eq('username', $queryBuilder->createNamedParameter($userName));
94142
}
95143

96144
/**
@@ -100,19 +148,45 @@ public function getUser($user)
100148
*/
101149
public function getUserImage($user)
102150
{
103-
$sql = '
104-
SELECT sys_file.* FROM sys_file
105-
RIGHT JOIN sys_file_reference ON sys_file.uid = sys_file_reference.uid_local
106-
RIGHT JOIN be_users ON sys_file_reference.uid_foreign = be_users.uid
107-
WHERE be_users.username = ' . $this->connection->fullQuoteStr($user, 'be_users') . '
108-
AND sys_file_reference.deleted = 0
109-
AND sys_file_reference.tablenames = "be_users"
110-
AND sys_file_reference.fieldname = "avatar"';
111-
112-
$file = $this->connection->admin_query($sql)->fetch_assoc();
151+
/** @var QueryBuilder $queryBuilder */
152+
$queryBuilder = $this->connectionPool->getQueryBuilderForTable('sys_file');
153+
154+
$file = $queryBuilder
155+
->select('sys_file.*')
156+
->from('sys_file')
157+
->rightJoin(
158+
'sys_file',
159+
'sys_file_reference',
160+
'sys_file_reference',
161+
$queryBuilder
162+
->expr()
163+
->eq('sys_file_reference.uid_local', $queryBuilder->quoteIdentifier('sys_file.uid')))
164+
->rightJoin(
165+
'sys_file',
166+
'be_users',
167+
'be_users',
168+
$queryBuilder
169+
->expr()
170+
->eq('be_users.uid', $queryBuilder->quoteIdentifier('sys_file_reference.uid_foreign')))
171+
->where(
172+
$queryBuilder
173+
->expr()
174+
->eq('be_users.username', $queryBuilder->createNamedParameter($user)))
175+
->andWhere(
176+
$queryBuilder
177+
->expr()
178+
->eq('sys_file_reference.tablenames', $queryBuilder->createNamedParameter('be_users')))
179+
->andWhere(
180+
$queryBuilder
181+
->expr()
182+
->eq('sys_file_reference.fieldname', $queryBuilder->createNamedParameter('avatar')))
183+
->execute()
184+
->fetch();
185+
113186
if (!empty($file['uid'])) {
114187
try {
115188
$resource = ResourceFactory::getInstance()->getFileObject($file['uid'], $file);
189+
116190
if ($resource instanceof File && $resource->exists()) {
117191
return [
118192
'identifier' => $resource->getName(),
@@ -122,6 +196,14 @@ public function getUserImage($user)
122196
} catch (FileDoesNotExistException $e) {
123197
}
124198
}
199+
125200
return null;
126201
}
202+
203+
/**
204+
* @return QueryBuilder
205+
*/
206+
private function getBeUserQueryBuilder() {
207+
return $this->connectionPool->getQueryBuilderForTable('be_users');
208+
}
127209
}

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
],
1212
"minimum-stability": "stable",
1313
"require": {
14-
"php": "^5.5 || ^7.0",
14+
"php": "^5.6 || ^7.0",
1515
"ext-openssl": "*",
16-
"typo3/cms-core": "^7.6 || ^8.7"
16+
"typo3/cms-core": "^8.7 || ^9.5"
1717
},
1818
"autoload": {
1919
"psr-4": {

0 commit comments

Comments
 (0)