You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1215 lines
27 KiB

<?php declare(strict_types = 0);
/*
** Zabbix
** Copyright (C) 2001-2023 Zabbix SIA
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
require_once dirname(__FILE__).'/../include/CAPITest.php';
/**
* @backup token
*/
class testToken extends CAPITest {
protected static $unique_counter = 1;
protected static function uniqueName(): string {
return 'name'.static::$unique_counter ++;
}
public static function token_create(): array {
return [
// Name field validation.
[
'tokens' => [
[
'name' => str_repeat('a', DB::getFieldLength('token', 'name'))
]
],
'expected_error' => null
],
[
'tokens' => [
[
'name' => str_repeat('a', DB::getFieldLength('token', 'name') + 1)
]
],
'expected_error' => 'Invalid parameter "/1/name": value is too long.'
],
[
'tokens' => [
[
'name' => ''
]
],
'expected_error' => 'Invalid parameter "/1/name": cannot be empty.'
],
// Description field validation.
[
'tokens' => [
[
'name' => static::uniqueName(),
'description' => str_repeat('a', DB::getFieldLength('token', 'description'))
]
],
'expected_error' => null
],
[
'tokens' => [
[
'name' => static::uniqueName(),
'description' => str_repeat('a', DB::getFieldLength('token', 'description') + 1)
]
],
'expected_error' => 'Invalid parameter "/1/description": value is too long.'
],
[
'tokens' => [
[
'name' => static::uniqueName(),
'description' => ''
],
[
'name' => static::uniqueName(),
'description' => 'test desctiption'
]
],
'expected_error' => null
],
// Userid field validation.
[
'tokens' => [
[
'name' => static::uniqueName(),
'userid' => 90001 // Non-existing user.
]
],
'expected_error' => 'User with ID "90001" is not available.'
],
[
'tokens' => [
[
'name' => static::uniqueName(),
'userid' => 90000
]
],
'expected_error' => null
],
// Status field validation.
[
'tokens' => [
[
'name' => static::uniqueName(),
'status' => ZBX_AUTH_TOKEN_ENABLED
]
],
'expected_error' => null
],
[
'tokens' => [
[
'name' => static::uniqueName(),
'status' => ZBX_AUTH_TOKEN_DISABLED
]
],
'expected_error' => null
],
[
'tokens' => [
[
'name' => static::uniqueName(),
'status' => 2
]
],
'expected_error' => 'Invalid parameter "/1/status": value must be one of 0, 1.'
],
// Expires_at field validation.
[
'tokens' => [
[
'name' => static::uniqueName(),
'expires_at' => time() + 3600
]
],
'expected_error' => null
],
[
'tokens' => [
[
'name' => static::uniqueName(),
'expires_at' => 0
]
],
'expected_error' => null
],
[
'tokens' => [
[
'name' => static::uniqueName(),
'expires_at' => -20
]
],
'expected_error' => null
],
// Successful multiple objects insert.
[
'tokens' => [
[
'name' => static::uniqueName()
],
[
'name' => static::uniqueName()
]
],
'expected_error' => null
],
// Unexpected fields.
[
'tokens' => [
[
'name' => static::uniqueName(),
'token' => 'attempted token'
]
],
'expected_error' => 'Invalid parameter "/1": unexpected parameter "token".'
],
[
'tokens' => [
[
'name' => static::uniqueName(),
'lastaccess' => time()
]
],
'expected_error' => 'Invalid parameter "/1": unexpected parameter "lastaccess".'
],
[
'tokens' => [
[
'name' => static::uniqueName(),
'created_at' => time()
]
],
'expected_error' => 'Invalid parameter "/1": unexpected parameter "created_at".'
],
[
'tokens' => [
[
'name' => static::uniqueName(),
'creator_userid' => 1
]
],
'expected_error' => 'Invalid parameter "/1": unexpected parameter "creator_userid".'
],
// Token name uniqueness within unique users.
[
'tokens' => [
[
'name' => 'the-same-1',
'userid' => 1
],
[
'name' => 'not-the-same',
'userid' => 1
],
[
'name' => 'the-same-1',
'userid' => 1
]
],
'expected_error' => 'Invalid parameter "/3": value (userid, name)=(1, the-same-1) already exists.'
],
[
'tokens' => [
[
'name' => 'the-same-2',
'userid' => 1
],
[
'name' => 'the-same-2',
'userid' => 90000
]
],
'expected_error' => null
],
// Token name uniqueness with DB lookup.
[
'tokens' => [
[
'name' => self::uniqueName()
],
[
'name' => 'test-token-exists',
'userid' => 2 // Guest user ID.
]
],
'expected_error' => 'API token "test-token-exists" already exists for userid "2".'
],
// Admin role.
[
'tokens' => [
[
'name' => self::uniqueName()
// 'userid' => 4 // Correct ID should be implied from session.
]
],
'expected_error' => null,
'auth' => [
'username' => 'zabbix-admin',
'password' => 'zabbix',
'userid' => 4
]
],
[
'tokens' => [
[
'name' => self::uniqueName(),
'userid' => 5
]
],
'expected_error' => 'User with ID "5" is not available.',
'auth' => [
'username' => 'zabbix-admin',
'password' => 'zabbix',
'userid' => 4
]
],
// User role.
[
'tokens' => [
[
'name' => self::uniqueName(),
'userid' => 4
]
],
'expected_error' => 'User with ID "4" is not available.',
'auth' => [
'username' => 'zabbix-user',
'password' => 'zabbix',
'userid' => 5
]
],
[
'tokens' => [
[
'name' => self::uniqueName()
// 'userid' => 5 // Correct ID should be implied from session.
]
],
'expected_error' => null,
'auth' => [
'username' => 'zabbix-user',
'password' => 'zabbix',
'userid' => 5
]
],
// Super admin role.
[
'tokens' => [
[
'name' => self::uniqueName(),
'userid' => 2 // Guest user id.
],
[
'name' => self::uniqueName(),
'userid' => 4
],
[
'name' => self::uniqueName(),
'userid' => 5
]
],
'expected_error' => null
]
];
}
/**
* @dataProvider token_create
*/
public function testToken_Create($tokens, $expected_error, array $auth = []): void {
if ($auth) {
$this->authorize($auth['username'], $auth['password']);
$session_userid = $auth['userid'];
}
else {
$session_userid = 1;
}
$result = $this->call('token.create', $tokens, $expected_error);
if ($expected_error === null) {
$this->assertEquals(count($result['result']['tokenids']), count($tokens));
$db_tokens = DB::select('token', [
'output' => ['name', 'description', 'userid', 'token', 'lastaccess', 'status', 'expires_at',
'created_at', 'creator_userid'
],
'tokenids' => $result['result']['tokenids']
]);
foreach ($db_tokens as $index => $db_token) {
$token = $tokens[$index];
$this->assertEquals($token['name'], $db_token['name']);
if (array_key_exists('description', $token)) {
$this->assertEquals($token['description'], $db_token['description']);
}
else {
$this->assertEquals('', $db_token['description']);
}
if (array_key_exists('userid', $token)) {
$this->assertEquals($token['userid'], $db_token['userid']);
}
else {
$this->assertEquals($session_userid, $db_token['userid'], 'Session user should be the default.');
}
$this->assertEquals('0', $db_token['token'], 'Token should be set to NULL.');
$this->assertEquals('0', $db_token['lastaccess'], 'Token lastaccess be set to 0.');
if (array_key_exists('status', $token)) {
$this->assertEquals($token['status'], $db_token['status']);
}
else {
$this->assertEquals(ZBX_AUTH_TOKEN_ENABLED, $db_token['status'], 'Token is enabled by default.');
}
if (array_key_exists('expires_at', $token)) {
$this->assertEquals($token['expires_at'], $db_token['expires_at']);
}
else {
$this->assertEquals('0', $db_token['expires_at'], 'Token never expires by default.');
}
$this->assertTrue(abs($db_token['created_at'] - time()) < 2, 'Expected created_at to be almost NOW().');
$this->assertEquals($session_userid, $db_token['creator_userid'], 'Session user should be the creator');
}
}
}
public static function token_delete(): array {
return [
[
'tokenids' => [2, 3, 4, 5],
'expected_error' => 'No permissions to referred object or it does not exist!',
'auth' => [
'username' => 'zabbix-user',
'password' => 'zabbix'
]
],
[
'tokenids' => [2, 5],
'expected_error' => null,
'auth' => [
'username' => 'zabbix-user',
'password' => 'zabbix'
]
],
[
'tokenids' => [2, 5],
'expected_error' => 'No permissions to referred object or it does not exist!',
'auth' => [
'username' => 'zabbix-user',
'password' => 'zabbix'
]
],
[
'tokenids' => [2, 3, 4, 5],
'expected_error' => 'No permissions to referred object or it does not exist!',
'auth' => [
'username' => 'Admin',
'password' => 'zabbix'
]
],
[
'tokenids' => [3, 4],
'expected_error' => null,
'auth' => [
'username' => 'Admin',
'password' => 'zabbix'
]
],
[
'tokenids' => [9, 9],
'expected_error' => 'Invalid parameter "/2": value (9) already exists.',
'auth' => [
'username' => 'Admin',
'password' => 'zabbix'
]
]
];
}
/**
* @dataProvider token_delete
*/
public function testToken_Delete($tokenids, $expected_error, array $auth = []): void {
if ($auth) {
$this->authorize($auth['username'], $auth['password']);
}
$db_tokens_before = DB::select('token', [
'output' => ['tokenid'],
'tokenids' => $tokenids
]);
$result = $this->call('token.delete', $tokenids, $expected_error);
$db_tokens_after = DB::select('token', [
'output' => ['tokenid'],
'tokenids' => $tokenids
]);
if ($expected_error === null) {
$this->assertEquals($result['result']['tokenids'], $tokenids, 'Response tokenids should match the request.');
$this->assertEmpty($db_tokens_after, 'DB records should be deleted.');
}
else {
$this->assertEquals($db_tokens_after, $db_tokens_before, 'No tokens got deleted.');
}
}
public static function token_get(): array {
return [
// Input validation.
[
'request' => [
'output' => [],
'tokenids' => 'x'
],
'expected' => [
'error' => 'Invalid parameter "/tokenids": an array is expected.',
'result' => []
]
],
[
'request' => [
'output' => [],
'tokenids' => ['x']
],
'expected' => [
'error' => 'Invalid parameter "/tokenids/1": a number is expected.',
'result' => []
]
],
[
'request' => [
'output' => [],
'userids' => 'x'
],
'expected' => [
'error' => 'Invalid parameter "/userids": an array is expected.',
'result' => []
]
],
[
'request' => [
'output' => [],
'userids' => ['x']
],
'expected' => [
'error' => 'Invalid parameter "/userids/1": a number is expected.',
'result' => []
]
],
[
'request' => [
'output' => [],
'token' => ['x']
],
'expected' => [
'error' => 'Invalid parameter "/token": a character string is expected.',
'result' => []
]
],
[
'request' => [
'output' => [],
'token' => str_repeat('x', 65)
],
'expected' => [
'error' => 'Invalid parameter "/token": value is too long.',
'result' => []
]
],
[
'request' => [
'output' => [],
'valid_at' => 'x'
],
'expected' => [
'error' => 'Invalid parameter "/valid_at": an integer is expected.',
'result' => []
]
],
[
'request' => [
'output' => [],
'expired_at' => 'x'
],
'expected' => [
'error' => 'Invalid parameter "/expired_at": an integer is expected.',
'result' => []
]
],
// Input validation, filter object.
[
'request' => [
'output' => [],
'filter' => [
'tokenid' => ['x']
]
],
'expected' => [
'error' => null,
'result' => []
]
],
[
'request' => [
'output' => [],
'filter' => [
'tokenid' => 'x'
]
],
'expected' => [
'error' => null,
'result' => []
]
],
[
'request' => [
'output' => [],
'filter' => [
'userid' => 'x'
]
],
'expected' => [
'error' => null,
'result' => []
]
],
[
'request' => [
'output' => [],
'filter' => [
'userid' => ['x']
]
],
'expected' => [
'error' => null,
'result' => []
]
],
[
'request' => [
'output' => [],
'filter' => [
'lastaccess' => ['x']
]
],
'expected' => [
'error' => null,
'result' => []
]
],
[
'request' => [
'output' => [],
'filter' => [
'lastaccess' => 'x'
]
],
'expected' => [
'error' => null,
'result' => []
]
],
[
'request' => [
'output' => [],
'filter' => [
'status' => [2]
]
],
'expected' => [
'error' => null,
'result' => []
]
],
[
'request' => [
'output' => [],
'filter' => [
'status' => 2
]
],
'expected' => [
'error' => null,
'result' => []
]
],
[
'request' => [
'output' => [],
'filter' => [
'expires_at' => ["x"]
]
],
'expected' => [
'error' => null,
'result' => []
]
],
[
'request' => [
'output' => [],
'filter' => [
'expires_at' => "x"
]
],
'expected' => [
'error' => null,
'result' => []
]
],
[
'request' => [
'output' => [],
'filter' => [
'created_at' => ["x"]
]
],
'expected' => [
'error' => null,
'result' => []
]
],
[
'request' => [
'output' => [],
'filter' => [
'created_at' => "x"
]
],
'expected' => [
'error' => null,
'result' => []
]
],
[
'request' => [
'output' => [],
'filter' => [
'creator_userid' => "x"
]
],
'expected' => [
'error' => null,
'result' => []
]
],
[
'request' => [
'output' => [],
'filter' => [
'creator_userid' => ["x"]
]
],
'expected' => [
'error' => null,
'result' => []
]
],
// Correct output using search.
[
'request' => [
'output' => [],
'search' => [
'name' => 'test-get'
],
'limit' => 1
],
'expected' => [
'error' => null,
'result' => [[]]
]
],
[
'request' => [
'output' => [],
'search' => [
'name' => 'test-get'
],
'countOutput' => true,
'sortfield' => ['name', 'status'] // Should not cause errors when used in conjunction with count.
],
'expected' => [
'error' => null,
'result' => 5
]
],
// Correct output using property fields select.
[
'request' => [
'output' => [],
'tokenids' => ["1"]
],
'expected' => [
'error' => null,
'result' => [[]]
]
],
[
'request' => [
'output' => [],
'userids' => ["12"]
],
'expected' => [
'error' => null,
'result' => [[], []]
]
],
[
'request' => [
'output' => [],
'token' => 'a26ddc6178485b5189b103e9775763bdc01e8d19fcbe6c7dea99ae2e2d50ae1a'
],
'expected' => [
'error' => null,
'result' => [[]]
]
],
[
'request' => [
'output' => [],
'valid_at' => "123",
'tokenids' => "12"
],
'expected' => [
'error' => null,
'result' => []
]
],
[
'request' => [
'output' => [],
'valid_at' => "122",
'tokenids' => "12"
],
'expected' => [
'error' => null,
'result' => [[]]
]
],
[
'request' => [
'output' => [],
'expired_at' => "123",
'tokenids' => "12"
],
'expected' => [
'error' => null,
'result' => [[]]
]
],
[
'request' => [
'output' => [],
'expired_at' => "122",
'tokenids' => "12"
],
'expected' => [
'error' => null,
'result' => []
]
],
// Permission check.
[
'request' => [
'output' => [],
'search' => [
'name' => 'test-get'
],
'countOutput' => true
],
'expected' => [
'error' => null,
'result' => 5
],
'auth' => [
'username' => 'Admin',
'password' => 'zabbix'
]
],
[
'request' => [
'output' => [],
'search' => [
'name' => 'test-get'
],
'countOutput' => true
],
'expected' => [
'error' => null,
'result' => 2
],
'auth' => [
'username' => 'zabbix-user',
'password' => 'zabbix'
]
]
];
}
/**
* @dataProvider token_get
*/
public function testToken_Get($request, $expected, array $auth = []): void {
if ($auth) {
$this->authorize($auth['username'], $auth['password']);
}
$result = $this->call('token.get', $request, $expected['error']);
if ($expected['error'] === null) {
$this->assertEquals($result['result'], $expected['result']);
}
}
public static function token_update(): array {
return [
'#1 case "tokenid is mandatory"' =>
[
'request' => [
[
'name' => 'test-name-y'
]
],
'expect_error' => 'Invalid parameter "/1": the parameter "tokenid" is missing.'
],
'#2 case "tokenid must be unique"' =>
[
'request' => [
[
'tokenid' => '1',
'name' => 'test-name-y'
],
[
'tokenid' => '1',
'name' => 'test-name-x'
]
],
'expect_error' => 'Invalid parameter "/2": value (tokenid)=(1) already exists.'
],
'#3 case "name field can be updated"' =>
[
'request' => [
[
'tokenid' => '15',
'name' => 'update-super-admin-1-updated'
]
],
'expect_error' => null
],
'#4 case "description field can be updated"' =>
[
'request' => [
[
'tokenid' => '15',
'description' => 'update-super-admin-1-updated'
]
],
'expect_error' => null
],
'#5 case "status field can be updated"' =>
[
'request' => [
[
'tokenid' => '15',
'status' => ZBX_AUTH_TOKEN_DISABLED
]
],
'expect_error' => null
],
'#6 case "status field can be updated #2"' =>
[
'request' => [
[
'tokenid' => '15',
'status' => ZBX_AUTH_TOKEN_ENABLED
]
],
'expect_error' => null
],
'#7 case "expires_at field can be updated"' =>
[
'request' => [
[
'tokenid' => '15',
'expires_at' => time() + 3600
]
],
'expect_error' => null
],
'#8 case "expires_at field can be updated #2"' =>
[
'request' => [
[
'tokenid' => '15',
'expires_at' => 0
]
],
'expect_error' => null
],
'#9 case "token field cannot be updated"' =>
[
'request' => [
[
'tokenid' => '15',
'token' => bin2hex(random_bytes(64))
]
],
'expect_error' => 'Invalid parameter "/1": unexpected parameter "token".'
],
'#10 case "userid field cannot be updated"' =>
[
'request' => [
[
'tokenid' => '15',
'userid' => '4'
]
],
'expect_error' => 'Invalid parameter "/1": unexpected parameter "userid".'
],
'#11 case "non-super admin cannot update tokens of other users"' =>
[
'request' => [
[
'tokenid' => '15', // Belongs to other user.
'name' => 'update-test-name-x'
],
[
'tokenid' => '18', // Belongs to this user.
'name' => 'update-test-name-y'
]
],
'expect_error' => 'No permissions to referred object or it does not exist!',
'auth' => [
'username' => 'zabbix-user',
'password' => 'zabbix'
]
],
'#12 case "super admin can update tokens for other users"' =>
[
'request' => [
[
'tokenid' => '15', // Belongs to this user.
'name' => 'update-test-name-x'
],
[
'tokenid' => '18', // Belongs to other user.
'name' => 'update-test-name-y'
]
],
'expect_error' => null
],
'#13 case "user can update token name to the same name"' =>
[
'request' => [
[
'tokenid' => '17',
'name' => 'update-user-1' // This name exists in DB.
],
[
'tokenid' => '19',
'name' => 'update-user-3', // This name exists in DB.
'description' => 'new description'
]
],
'expect_error' => null
],
'#14 case "user cannot update token Y name if such name is used in token X"' =>
[
'request' => [
[
'tokenid' => '20',
'name' => 'update-user-5' // This user has token (ID: 21) using this name.
]
],
'expect_error' => 'API token "update-user-5" already exists for userid "5".'
],
'#15 case "cannot update identical token names within request"' =>
[
'request' => [
[
'tokenid' => '20',
'name' => 'update-user-22'
],
[
'tokenid' => '21',
'name' => 'update-user-22'
]
],
'expected_error' => 'Invalid parameter "/2": value (userid, name)=(5, update-user-22) already exists.'
]
];
}
/**
* @dataProvider token_update
*/
public function testToken_Update($tokens, $expect_error = null, array $auth = []): void {
if ($auth) {
$this->authorize($auth['username'], $auth['password']);
}
$result = $this->call('token.update', $tokens, $expect_error);
if ($expect_error === null) {
$db_tokens = DB::select('token', [
'output' => ['tokenid', 'name', 'description', 'status', 'expires_at'],
'tokenids' => $result['result']['tokenids'],
'sortfield' => ['tokenid']
]);
foreach ($db_tokens as $index => $db_token) {
$token = $tokens[$index];
if (array_key_exists('name', $token)) {
$this->assertEquals($token['name'], $db_token['name']);
}
if (array_key_exists('description', $token)) {
$this->assertEquals($token['description'], $db_token['description']);
}
if (array_key_exists('status', $token)) {
$this->assertEquals($token['status'], $db_token['status']);
}
if (array_key_exists('expires_at', $token)) {
$this->assertEquals($token['expires_at'], $db_token['expires_at']);
}
}
}
}
public function testToken_Generate(): void {
$adminid = 1;
$userid = 5;
$this->authorize('Admin', 'zabbix'); // Super admin role (ID = 1)
['result' => ['tokenids' => $tokenids]] = $this->call('token.create', [
['name' => '1', 'userid' => 5],
['name' => '1', 'userid' => 1]
], null);
[$user_tokenid, $admin_tokenid] = $tokenids;
// Token ids must be unique.
$this->call('token.generate', [1, 1],
'Invalid parameter "/2": value (1) already exists.'
);
// User role cannot generate other tokens.
$this->authorize('zabbix-user', 'zabbix'); // User role (ID = 5)
$this->call('token.generate', [$user_tokenid, $admin_tokenid],
'No permissions to referred object or it does not exist!'
);
// After successful generate call, session user becomes the record creator.
$this->assertEquals($adminid,
CDBHelper::getValue('SELECT creator_userid FROM token WHERE tokenid='.zbx_dbstr($user_tokenid))
);
['result' => [['token' => $token]]] = $this->call('token.generate', [$user_tokenid]);
$this->assertEquals($userid,
CDBHelper::getValue('SELECT creator_userid FROM token WHERE tokenid='.zbx_dbstr($user_tokenid))
);
// The generated token hash matches record in DB.
$this->assertEquals(hash('sha512', $token),
CDBHelper::getValue('SELECT token FROM token WHERE tokenid='.zbx_dbstr($user_tokenid)),
'User token value updated'
);
// Super admin can generate/regenerate token for anyone.
$this->authorize('Admin', 'zabbix'); // Super admin role (ID = 1)
['result' => $tokens] = $this->call('token.generate', [$user_tokenid, $admin_tokenid]);
[['token' => $user_token], ['token' => $admin_token]] = $tokens;
// After successful generate call, session user becomes the record creator.
$this->assertEquals($adminid,
CDBHelper::getValue('SELECT creator_userid FROM token WHERE tokenid='.zbx_dbstr($user_tokenid))
);
$this->assertEquals($adminid,
CDBHelper::getValue('SELECT creator_userid FROM token WHERE tokenid='.zbx_dbstr($admin_tokenid))
);
// The generated token hash matches record in DB.
$this->assertEquals(hash('sha512', $user_token),
CDBHelper::getValue('SELECT token FROM token WHERE tokenid='.zbx_dbstr($user_tokenid)),
'User token value updated'
);
$this->assertEquals(hash('sha512', $admin_token),
CDBHelper::getValue('SELECT token FROM token WHERE tokenid='.zbx_dbstr($admin_tokenid)),
'Admin token value re-updated'
);
}
private function countAuditActions(int $action): int {
return count(DB::select('auditlog', ['output' => [], 'filter' => [
'resourcetype' => 45 /* CAudit::RESOURCE_AUTH_TOKEN */,
'action' => $action
]]));
}
public function testToken_auditlogs(): void {
$add_records = $this->countAuditActions(0 /* CAudit::ACTION_ADD */);
$update_records = $this->countAuditActions(1 /* CAudit::ACTION_UPDATE */);
$delete_records = $this->countAuditActions(2 /* CAudit::ACTION_DELETE */);
['result' => ['tokenids' => [$new_id]]] = $this->call('token.create', ['name' => 'audit 1']);
$this->assertEquals($add_records + 1, $this->countAuditActions(0 /* CAudit::ACTION_ADD */));
$this->call('token.update', ['tokenid' => $new_id, 'name' => 'audit 2']);
$this->assertEquals($update_records + 1, $this->countAuditActions(1 /* CAudit::ACTION_UPDATE */));
$this->call('token.generate', [$new_id]);
$this->assertEquals($update_records + 2, $this->countAuditActions(1 /* CAudit::ACTION_UPDATE */));
$this->call('token.delete', [$new_id]);
$this->assertEquals($delete_records + 1, $this->countAuditActions(2 /* CAudit::ACTION_DELETE */));
}
public function testToken_deleteTokenCreator(): void {
['result' => [['creator_userid' => $creator_userid]]] = $this->call('token.get', [
'output' => ['creator_userid'],
'tokenids' => 23
]);
$this->assertEquals(20, $creator_userid);
$this->call('user.delete', [20]);
['result' => [['creator_userid' => $creator_userid]]] = $this->call('token.get', [
'output' => ['creator_userid'],
'tokenids' => 23
]);
$this->assertEquals(0, $creator_userid);
}
}