From 1c33484d535ebe3ee53a681c29a719050b9ff30b Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Wed, 21 Dec 2022 16:01:28 +0300 Subject: [PATCH] box: add auth_history and last_modified fields to _user space See the doc bot request for the description of the new fields. Note that we only store the value of the 'last_modified' field in struct user_def, because 'auth_history' will be used only in Lua code. Needed for https://github.com/tarantool/tarantool-ee/issues/298 Needed for https://github.com/tarantool/tarantool-ee/issues/299 NO_CHANGELOG=no user-visible effects in CE; will be added to EE @TarantoolBot document Title: Document auth_history and last_modified _user space fields Field name: auth_history. Field no: 6. Type: array. Description: The field stores an array of previous authentication data: when a user password is changed, the last value of the 'auth' field is appended to 'auth_history'. The length of the history is configured by the `box.cfg.password_history_length` option, which is available only in Tarantool EE, where it's used to prevent users from reusing old passwords. In Tarantool CE, the array is always empty. Field name: last_modified. Field no: 7. Type: unsigned. Description: The field stores the timestamp (seconds since Unix epoch) of the last user password update. It's never used in Tarantool CE. In Tarantool EE, it's used to disable users that haven't changed the password for more than `box.cfg.password_lifetime_days`. `box.schema.upgrade()` sets the new field values to an empty array and 0 for users that haven't updated them yet. --- src/box/alter.cc | 4 + src/box/bootstrap.snap | Bin 4908 -> 4938 bytes src/box/lua/schema.lua | 11 +- src/box/lua/upgrade.lua | 19 +++ src/box/schema_def.h | 2 + src/box/user_def.c | 1 + src/box/user_def.h | 5 + .../upgrade/2.10.4/00000000000000000009.snap | Bin 0 -> 5114 bytes ...uth_history_last_modified_upgrade_test.lua | 99 +++++++++++ test/box-py/bootstrap.result | 16 +- test/box/access.result | 157 ++++++++++++------ test/box/access.test.lua | 89 +++++++--- test/box/access_bin.result | 2 +- test/box/access_misc.result | 8 +- test/box/access_misc.test.lua | 2 +- 15 files changed, 327 insertions(+), 88 deletions(-) create mode 100644 test/box-luatest/upgrade/2.10.4/00000000000000000009.snap create mode 100644 test/box-luatest/user_auth_history_last_modified_upgrade_test.lua diff --git a/src/box/alter.cc b/src/box/alter.cc index 4ee8487dbbc1..19db22a8d315 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -3001,6 +3001,10 @@ user_def_new_from_tuple(struct tuple *tuple) if (user_def_fill_auth_data(user, auth_data) != 0) return NULL; } + if (tuple_field_count(tuple) > BOX_USER_FIELD_LAST_MODIFIED && + tuple_field_u64(tuple, BOX_USER_FIELD_LAST_MODIFIED, + &user->last_modified) != 0) + return NULL; def_guard.is_active = false; return user; } diff --git a/src/box/bootstrap.snap b/src/box/bootstrap.snap index 150881c170aab7b2c83ff23a8817e09db49f16c0..43701a0dbda46fc857228bee8d58fe35c23a2965 100644 GIT binary patch delta 4910 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 diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index ccec0990bfa1..cd06564e7b2d 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -5,6 +5,7 @@ local msgpack = require('msgpack') local fun = require('fun') local log = require('log') local buffer = require('buffer') +local fiber = require('fiber') local session = box.session local internal = require('box.internal') local utf8 = require('utf8') @@ -3391,7 +3392,9 @@ end local function chpasswd(uid, new_password) local _user = box.space[box.schema.USER_ID] check_password(new_password) - _user:update({uid}, {{"=", 5, prepare_auth_list(new_password)}}) + _user:update({uid}, {{'=', 5, prepare_auth_list(new_password)}, + {'=', 6, {}}, + {'=', 7, math.floor(fiber.time())}}) end box.schema.user.passwd = function(name, new_password) @@ -3430,7 +3433,8 @@ box.schema.user.create = function(name, opts) auth_list = setmap({}) end local _user = box.space[box.schema.USER_ID] - uid = _user:auto_increment{session.euid(), name, 'user', auth_list}.id + uid = _user:auto_increment{session.euid(), name, 'user', auth_list, {}, + math.floor(fiber.time())}.id -- grant role 'public' to the user box.schema.user.grant(uid, 'public') -- Grant privilege 'alter' on itself, so that it can @@ -3697,7 +3701,8 @@ box.schema.role.create = function(name, opts) return end local _user = box.space[box.schema.USER_ID] - _user:auto_increment{session.euid(), name, 'role', setmap({})} + _user:auto_increment{session.euid(), name, 'role', setmap({}), {}, + math.floor(fiber.time())} end box.schema.role.drop = function(name, opts) diff --git a/src/box/lua/upgrade.lua b/src/box/lua/upgrade.lua index cb6dfba24a39..2c7da702eb6b 100644 --- a/src/box/lua/upgrade.lua +++ b/src/box/lua/upgrade.lua @@ -1333,9 +1333,28 @@ local function convert_sql_constraints_to_tuple_constraints() end end +local function add_user_auth_history_and_last_modified() + log.info("add auth_history and last_modified fields to space _user") + local _space = box.space[box.schema.SPACE_ID] + local _user = box.space[box.schema.USER_ID] + local _vuser = box.space[box.schema.VUSER_ID] + for _, v in _user:pairs() do + if #v == 5 then + _user:update(v[1], {{'=', 6, {}}, {'=', 7, 0}}) + end + end + local ops = { + {'=', '[7][6]', {name = 'auth_history', type = 'array'}}, + {'=', '[7][7]', {name = 'last_modified', type = 'unsigned'}}, + } + _space:update({_user.id}, ops) + _space:update({_vuser.id}, ops) +end + local function upgrade_to_2_11_0() revoke_write_access_on__collation_from_role_public() convert_sql_constraints_to_tuple_constraints() + add_user_auth_history_and_last_modified() end -------------------------------------------------------------------------------- diff --git a/src/box/schema_def.h b/src/box/schema_def.h index cf7fc7ece80f..39fd94fe3ff9 100644 --- a/src/box/schema_def.h +++ b/src/box/schema_def.h @@ -154,6 +154,8 @@ enum { BOX_USER_FIELD_NAME = 2, BOX_USER_FIELD_TYPE = 3, BOX_USER_FIELD_AUTH = 4, + BOX_USER_FIELD_AUTH_HISTORY = 5, + BOX_USER_FIELD_LAST_MODIFIED = 6, }; /** _priv fields. */ diff --git a/src/box/user_def.c b/src/box/user_def.c index db3d71986114..4f5806e4273c 100644 --- a/src/box/user_def.c +++ b/src/box/user_def.c @@ -53,6 +53,7 @@ user_def_new(uint32_t uid, uint32_t owner, enum schema_object_type type, def->owner = owner; def->type = type; def->auth = NULL; + def->last_modified = 0; def->name = grp_alloc_create_str(&all, name, name_len); assert(grp_alloc_size(&all) == 0); return def; diff --git a/src/box/user_def.h b/src/box/user_def.h index efeb9774cdcf..7acc525b6af7 100644 --- a/src/box/user_def.h +++ b/src/box/user_def.h @@ -146,6 +146,11 @@ struct user_def { * reside in the user struct. */ struct authenticator *auth; + /** + * Last modification timestamp (seconds since UNIX epoch) + * or 0 if unknown. + */ + uint64_t last_modified; /** User name - for error messages and debugging */ char *name; }; diff --git a/test/box-luatest/upgrade/2.10.4/00000000000000000009.snap b/test/box-luatest/upgrade/2.10.4/00000000000000000009.snap new file mode 100644 index 0000000000000000000000000000000000000000..d21bba921962fc4a1602f651e9af35e1d361bebb GIT binary patch literal 5114 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 literal 0 HcmV?d00001 diff --git a/test/box-luatest/user_auth_history_last_modified_upgrade_test.lua b/test/box-luatest/user_auth_history_last_modified_upgrade_test.lua new file mode 100644 index 000000000000..d834907e3d25 --- /dev/null +++ b/test/box-luatest/user_auth_history_last_modified_upgrade_test.lua @@ -0,0 +1,99 @@ +local server = require('luatest.server') +local t = require('luatest') + +local g = t.group() + +g.before_all(function(cg) + t.tarantool.skip_if_not_debug() + cg.server = server:new({ + alias = 'master', + datadir = 'test/box-luatest/upgrade/2.10.4', + env = {ERRINJ_AUTO_UPGRADE = 'true'}, + }) + cg.server:start() +end) + +g.after_all(function(cg) + cg.server:drop() +end) + +g.test_upgrade = function(cg) + cg.server:exec(function() + local t = require('luatest') + local fiber = require('fiber') + t.assert_equals(box.space._user:select(), { + {0, 1, 'guest', 'user', + {['chap-sha1'] = 'vhvewKp0tNyweZQ+cFKAlsyphfg='}}, + {1, 1, 'admin', 'user', {}}, + {2, 1, 'public', 'role', {}}, + {3, 1, 'replication', 'role', {}}, + {31, 1, 'super', 'role', {}}, + {32, 1, 'eve', 'user', {}}, + {33, 1, 'bob', 'user', + {['chap-sha1'] = 'FOZVZ6vbUTXQz9mnCzAywXmknuc='}}, + {34, 1, 'test', 'role', {}}, + }) + box.schema.user.create('alice') + box.schema.user.create('sarah', {password = 'SARAH'}) + box.schema.user.passwd('bob', 'BOB') + box.schema.role.create('dev') + t.assert_equals(box.space._user:select(), { + {0, 1, 'guest', 'user', + {['chap-sha1'] = 'vhvewKp0tNyweZQ+cFKAlsyphfg='}}, + {1, 1, 'admin', 'user', {}}, + {2, 1, 'public', 'role', {}}, + {3, 1, 'replication', 'role', {}}, + {31, 1, 'super', 'role', {}}, + {32, 1, 'eve', 'user', {}}, + {33, 1, 'bob', 'user', + {['chap-sha1'] = 'Ll5w6uuDmXlEaz2b8kmjHZu1SLg='}, {}, + box.space._user:get(33)[7]}, + {34, 1, 'test', 'role', {}}, + {35, 0, 'alice', 'user', {}, {}, + box.space._user:get(35)[7]}, + {36, 0, 'sarah', 'user', + {['chap-sha1'] = '973rCIFsYhe7gupdgOPCSJoPRNU='}, {}, + box.space._user:get(36)[7]}, + {37, 0, 'dev', 'role', {}, {}, + box.space._user:get(37)[7]}, + }) + local time = fiber.time() + local margin = 60 + t.assert_almost_equals(box.space._user:get(33)[7], time, margin) + t.assert_almost_equals(box.space._user:get(35)[7], time, margin) + t.assert_almost_equals(box.space._user:get(36)[7], time, margin) + t.assert_almost_equals(box.space._user:get(37)[7], time, margin) + box.schema.upgrade() + local format = { + {name = "id", type = "unsigned"}, + {name = "owner", type = "unsigned"}, + {name = "name", type = "string"}, + {name = "type", type = "string"}, + {name = "auth", type = "map"}, + {name = "auth_history", type = "array"}, + {name = "last_modified", type = "unsigned"}, + } + t.assert_equals(box.space._user:format(), format) + t.assert_equals(box.space._vuser:format(), format) + t.assert_equals(box.space._user:select(), { + {0, 1, 'guest', 'user', + {['chap-sha1'] = 'vhvewKp0tNyweZQ+cFKAlsyphfg='}, {}, 0}, + {1, 1, 'admin', 'user', {}, {}, 0}, + {2, 1, 'public', 'role', {}, {}, 0}, + {3, 1, 'replication', 'role', {}, {}, 0}, + {31, 1, 'super', 'role', {}, {}, 0}, + {32, 1, 'eve', 'user', {}, {}, 0}, + {33, 1, 'bob', 'user', + {['chap-sha1'] = 'Ll5w6uuDmXlEaz2b8kmjHZu1SLg='}, {}, + box.space._user:get(33)[7]}, + {34, 1, 'test', 'role', {}, {}, 0}, + {35, 0, 'alice', 'user', {}, {}, + box.space._user:get(35)[7]}, + {36, 0, 'sarah', 'user', + {['chap-sha1'] = '973rCIFsYhe7gupdgOPCSJoPRNU='}, {}, + box.space._user:get(36)[7]}, + {37, 0, 'dev', 'role', {}, {}, + box.space._user:get(37)[7]}, + }) + end) +end diff --git a/test/box-py/bootstrap.result b/test/box-py/bootstrap.result index d24b5f0474a3..13101dec7caa 100644 --- a/test/box-py/bootstrap.result +++ b/test/box-py/bootstrap.result @@ -73,10 +73,12 @@ box.space._space:select{} 'type': 'string'}, {'name': 'last_altered', 'type': 'string'}]] - [304, 1, '_user', 'memtx', 0, {}, [{'name': 'id', 'type': 'unsigned'}, {'name': 'owner', 'type': 'unsigned'}, {'name': 'name', 'type': 'string'}, {'name': 'type', - 'type': 'string'}, {'name': 'auth', 'type': 'map'}]] + 'type': 'string'}, {'name': 'auth', 'type': 'map'}, {'name': 'auth_history', + 'type': 'array'}, {'name': 'last_modified', 'type': 'unsigned'}]] - [305, 1, '_vuser', 'sysview', 0, {}, [{'name': 'id', 'type': 'unsigned'}, {'name': 'owner', 'type': 'unsigned'}, {'name': 'name', 'type': 'string'}, {'name': 'type', - 'type': 'string'}, {'name': 'auth', 'type': 'map'}]] + 'type': 'string'}, {'name': 'auth', 'type': 'map'}, {'name': 'auth_history', + 'type': 'array'}, {'name': 'last_modified', 'type': 'unsigned'}]] - [312, 1, '_priv', 'memtx', 0, {}, [{'name': 'grantor', 'type': 'unsigned'}, { 'name': 'grantee', 'type': 'unsigned'}, {'name': 'object_type', 'type': 'string'}, {'name': 'object_id', 'type': 'scalar'}, {'name': 'privilege', 'type': 'unsigned'}]] @@ -166,11 +168,11 @@ box.space._index:select{} ... box.space._user:select{} --- -- - [0, 1, 'guest', 'user', {'chap-sha1': 'vhvewKp0tNyweZQ+cFKAlsyphfg='}] - - [1, 1, 'admin', 'user', {}] - - [2, 1, 'public', 'role', {}] - - [3, 1, 'replication', 'role', {}] - - [31, 1, 'super', 'role', {}] +- - [0, 1, 'guest', 'user', {'chap-sha1': 'vhvewKp0tNyweZQ+cFKAlsyphfg='}, [], 0] + - [1, 1, 'admin', 'user', {}, [], 0] + - [2, 1, 'public', 'role', {}, [], 0] + - [3, 1, 'replication', 'role', {}, [], 0] + - [31, 1, 'super', 'role', {}, [], 0] ... for _, v in box.space._func:pairs{} do r = {} table.insert(r, v:update({{"=", 18, ""}, {"=", 19, ""}})) return r end --- diff --git a/test/box/access.result b/test/box/access.result index f70289caf4f8..8148fd97d4da 100644 --- a/test/box/access.result +++ b/test/box/access.result @@ -74,6 +74,21 @@ test_run:cmd("setopt delimiter ';'") --- - true ... +function delete_user(uid_or_name) + local t + if type(uid_or_name) == 'string' then + t = box.space._user.index.name:delete({uid_or_name}) + else + t = box.space._user:delete({uid_or_name}) + end + if box.tuple.is(t) and type(t[7]) == 'number' then + t = t:totable() + t[7] = 0 + end + return t +end; +--- +... function usermax() local i = 1 while true do @@ -125,14 +140,14 @@ box.schema.func.create('dummy') session.su('admin') --- ... -box.space['_user']:delete{uid} +delete_user(uid) --- - error: 'Failed to drop user or role ''rich'': the user has objects' ... box.schema.func.drop('dummy') --- ... -box.space['_user']:delete{uid} +delete_user(uid) --- - error: 'Failed to drop user or role ''rich'': the user has objects' ... @@ -155,9 +170,9 @@ box.schema.user.disable("rich") box.schema.user.disable("rich") --- ... -box.space['_user']:delete{uid} +delete_user(uid) --- -- [33, 1, 'rich', 'user', {}] +- [33, 1, 'rich', 'user', {}, [], 0] ... box.schema.user.drop('test') --- @@ -353,6 +368,48 @@ box.snapshot() - ok ... test_run:cmd('restart server default') +test_run:cmd("setopt delimiter ';'") +--- +- true +... +function delete_user(uid_or_name) + local t + if type(uid_or_name) == 'string' then + t = box.space._user.index.name:delete({uid_or_name}) + else + t = box.space._user:delete({uid_or_name}) + end + if box.tuple.is(t) and type(t[7]) == 'number' then + t = t:totable() + t[7] = 0 + end + return t +end; +--- +... +function select_user(uid_or_name) + local ret + if type(uid_or_name) == 'string' then + ret = box.space._user.index.name:select({uid_or_name}) + else + ret = box.space._user:select({uid_or_name}) + end + local ret2 = {} + for _, t in ipairs(ret) do + if box.tuple.is(t) and type(t[7]) == 'number' then + t = t:totable() + t[7] = 0 + end + table.insert(ret2, t) + end + return ret2 +end; +--- +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... net = require('net.box') --- ... @@ -449,11 +506,11 @@ box.schema.user.drop('grantor') session.su('guest') --- ... -box.space._user:select{0} +select_user(0) --- - error: Read access to space '_user' is denied for user 'guest' ... -box.space._user:select{1} +select_user(1) --- - error: Read access to space '_user' is denied for user 'guest' ... @@ -467,9 +524,9 @@ session.su('admin') box.schema.user.create('user1') --- ... -box.space._user.index.name:select{'user1'} +select_user('user1') --- -- - [32, 1, 'user1', 'user', {}] +- - [32, 1, 'user1', 'user', {}, [], 0] ... session.su('user1') --- @@ -480,16 +537,16 @@ box.schema.user.passwd('new_password') session.su('admin') --- ... -box.space._user.index.name:select{'user1'} +select_user('user1') --- -- - [32, 1, 'user1', 'user', {'chap-sha1': 'CRO/LiziDOIb+xlhrxJNSSBFjl8='}] +- - [32, 1, 'user1', 'user', {'chap-sha1': 'CRO/LiziDOIb+xlhrxJNSSBFjl8='}, [], 0] ... box.schema.user.passwd('user1', 'extra_new_password') --- ... -box.space._user.index.name:select{'user1'} +select_user('user1') --- -- - [32, 1, 'user1', 'user', {'chap-sha1': 'nMc3F1oaUtz37IYbgGYYPZawmfE='}] +- - [32, 1, 'user1', 'user', {'chap-sha1': 'nMc3F1oaUtz37IYbgGYYPZawmfE='}, [], 0] ... box.schema.user.passwd('invalid_user', 'some_password') --- @@ -513,7 +570,7 @@ session.su('admin') box.schema.user.drop('user1') --- ... -box.space._user.index.name:select{'user1'} +select_user('user1') --- - [] ... @@ -595,11 +652,11 @@ box.space._priv:select{id} utils = require('utils') --- ... -box.space._user:insert{10, 1, 'name', 'strange-object-type', utils.setmap({})} +box.space._user:insert{10, 1, 'name', 'strange-object-type', utils.setmap({}), {}, 0} --- - error: 'Failed to create user ''name'': unknown user type' ... -box.space._user:insert{10, 1, 'name', 'role', utils.setmap{'password'}} +box.space._user:insert{10, 1, 'name', 'role', utils.setmap{'password'}, {}, 0} --- - error: 'Failed to create role ''name'': authentication data can not be set for a role' @@ -806,11 +863,11 @@ box.schema.role.drop('guest') --- - error: Role 'guest' is not found ... -box.space._user.index.name:delete{'guest'} +delete_user('guest') --- - error: 'Failed to drop user or role ''guest'': the user or the role is a system' ... -box.space._user:delete{box.schema.GUEST_ID} +delete_user(box.schema.GUEST_ID) --- - error: 'Failed to drop user or role ''guest'': the user or the role is a system' ... @@ -826,11 +883,11 @@ box.schema.role.drop('admin') --- - error: Role 'admin' is not found ... -box.space._user.index.name:delete{'admin'} +delete_user('admin') --- - error: 'Failed to drop user or role ''admin'': the user or the role is a system' ... -box.space._user:delete{box.schema.ADMIN_ID} +delete_user(box.schema.ADMIN_ID) --- - error: 'Failed to drop user or role ''admin'': the user or the role is a system' ... @@ -846,11 +903,11 @@ box.schema.role.drop('public') --- - error: 'Failed to drop user or role ''public'': the user or the role is a system' ... -box.space._user.index.name:delete{'public'} +delete_user('public') --- - error: 'Failed to drop user or role ''public'': the user or the role is a system' ... -box.space._user:delete{box.schema.PUBLIC_ROLE_ID} +delete_user(box.schema.PUBLIC_ROLE_ID) --- - error: 'Failed to drop user or role ''public'': the user or the role is a system' ... @@ -866,11 +923,11 @@ box.schema.user.drop('super') --- - error: User 'super' is not found ... -box.space._user.index.name:delete{'super'} +delete_user('super') --- - error: 'Failed to drop user or role ''super'': the user or the role is a system' ... -box.space._user:delete{box.schema.SUPER_ROLE_ID} +delete_user(box.schema.SUPER_ROLE_ID) --- - error: 'Failed to drop user or role ''super'': the user or the role is a system' ... @@ -2035,16 +2092,16 @@ box.schema.user.grant("user1", "write", "space", "_user") box.schema.user.grant("user1", "read", "space", "_user") --- ... -box.space._user:select{} +select_user() --- -- - [0, 1, 'guest', 'user', {'chap-sha1': 'vhvewKp0tNyweZQ+cFKAlsyphfg='}] - - [1, 1, 'admin', 'user', {}] - - [2, 1, 'public', 'role', {}] - - [3, 1, 'replication', 'role', {}] - - [31, 1, 'super', 'role', {}] - - [32, 1, 'user1', 'user', {}] - - [33, 1, 'user2', 'user', {}] - - [34, 1, 'user3', 'user', {}] +- - [0, 1, 'guest', 'user', {'chap-sha1': 'vhvewKp0tNyweZQ+cFKAlsyphfg='}, [], 0] + - [1, 1, 'admin', 'user', {}, [], 0] + - [2, 1, 'public', 'role', {}, [], 0] + - [3, 1, 'replication', 'role', {}, [], 0] + - [31, 1, 'super', 'role', {}, [], 0] + - [32, 1, 'user1', 'user', {}, [], 0] + - [33, 1, 'user2', 'user', {}, [], 0] + - [34, 1, 'user3', 'user', {}, [], 0] ... box.session.su("user1") --- @@ -2060,16 +2117,16 @@ box.schema.user.passwd("user2", "abcd") box.session.su("admin") --- ... -box.space._user:select{} +select_user() --- -- - [0, 1, 'guest', 'user', {'chap-sha1': 'vhvewKp0tNyweZQ+cFKAlsyphfg='}] - - [1, 1, 'admin', 'user', {}] - - [2, 1, 'public', 'role', {}] - - [3, 1, 'replication', 'role', {}] - - [31, 1, 'super', 'role', {}] - - [32, 1, 'user1', 'user', {'chap-sha1': 'oVTFJWXp5/lL/Aih/nAmJO2O/9o='}] - - [33, 1, 'user2', 'user', {}] - - [34, 1, 'user3', 'user', {}] +- - [0, 1, 'guest', 'user', {'chap-sha1': 'vhvewKp0tNyweZQ+cFKAlsyphfg='}, [], 0] + - [1, 1, 'admin', 'user', {}, [], 0] + - [2, 1, 'public', 'role', {}, [], 0] + - [3, 1, 'replication', 'role', {}, [], 0] + - [31, 1, 'super', 'role', {}, [], 0] + - [32, 1, 'user1', 'user', {'chap-sha1': 'oVTFJWXp5/lL/Aih/nAmJO2O/9o='}, [], 0] + - [33, 1, 'user2', 'user', {}, [], 0] + - [34, 1, 'user3', 'user', {}, [], 0] ... box.schema.user.grant("user1", "alter", "user", "user2") --- @@ -2088,16 +2145,16 @@ box.schema.user.passwd("user3", "qewr") box.session.su("admin") --- ... -box.space._user:select{} +select_user() --- -- - [0, 1, 'guest', 'user', {'chap-sha1': 'vhvewKp0tNyweZQ+cFKAlsyphfg='}] - - [1, 1, 'admin', 'user', {}] - - [2, 1, 'public', 'role', {}] - - [3, 1, 'replication', 'role', {}] - - [31, 1, 'super', 'role', {}] - - [32, 1, 'user1', 'user', {'chap-sha1': 'oVTFJWXp5/lL/Aih/nAmJO2O/9o='}] - - [33, 1, 'user2', 'user', {'chap-sha1': 'oVTFJWXp5/lL/Aih/nAmJO2O/9o='}] - - [34, 1, 'user3', 'user', {}] +- - [0, 1, 'guest', 'user', {'chap-sha1': 'vhvewKp0tNyweZQ+cFKAlsyphfg='}, [], 0] + - [1, 1, 'admin', 'user', {}, [], 0] + - [2, 1, 'public', 'role', {}, [], 0] + - [3, 1, 'replication', 'role', {}, [], 0] + - [31, 1, 'super', 'role', {}, [], 0] + - [32, 1, 'user1', 'user', {'chap-sha1': 'oVTFJWXp5/lL/Aih/nAmJO2O/9o='}, [], 0] + - [33, 1, 'user2', 'user', {'chap-sha1': 'oVTFJWXp5/lL/Aih/nAmJO2O/9o='}, [], 0] + - [34, 1, 'user3', 'user', {}, [], 0] ... box.schema.user.drop("user1") --- diff --git a/test/box/access.test.lua b/test/box/access.test.lua index b9608f2142be..9c81b11aa86f 100644 --- a/test/box/access.test.lua +++ b/test/box/access.test.lua @@ -33,6 +33,19 @@ session.su('admin') box.schema.user.grant('test', 'write', 'space', '_space') test_run:cmd("setopt delimiter ';'") +function delete_user(uid_or_name) + local t + if type(uid_or_name) == 'string' then + t = box.space._user.index.name:delete({uid_or_name}) + else + t = box.space._user:delete({uid_or_name}) + end + if box.tuple.is(t) and type(t[7]) == 'number' then + t = t:totable() + t[7] = 0 + end + return t +end; function usermax() local i = 1 while true do @@ -57,9 +70,9 @@ session.su('rich') uid = session.uid() box.schema.func.create('dummy') session.su('admin') -box.space['_user']:delete{uid} +delete_user(uid) box.schema.func.drop('dummy') -box.space['_user']:delete{uid} +delete_user(uid) box.schema.user.revoke('rich', 'public') box.schema.user.revoke('rich', 'read,write', 'space', '_func') box.schema.user.revoke('rich', 'alter', 'user', 'rich') @@ -67,7 +80,7 @@ box.schema.user.revoke('rich', 'create', 'function') box.schema.user.disable("rich") -- test double disable is a no op box.schema.user.disable("rich") -box.space['_user']:delete{uid} +delete_user(uid) box.schema.user.drop('test') -- gh-944 name is too long @@ -156,6 +169,38 @@ box.schema.user.grant('testus', 'write', 'space', 'admin_space') s:drop() box.snapshot() test_run:cmd('restart server default') +test_run:cmd("setopt delimiter ';'") +function delete_user(uid_or_name) + local t + if type(uid_or_name) == 'string' then + t = box.space._user.index.name:delete({uid_or_name}) + else + t = box.space._user:delete({uid_or_name}) + end + if box.tuple.is(t) and type(t[7]) == 'number' then + t = t:totable() + t[7] = 0 + end + return t +end; +function select_user(uid_or_name) + local ret + if type(uid_or_name) == 'string' then + ret = box.space._user.index.name:select({uid_or_name}) + else + ret = box.space._user:select({uid_or_name}) + end + local ret2 = {} + for _, t in ipairs(ret) do + if box.tuple.is(t) and type(t[7]) == 'number' then + t = t:totable() + t[7] = 0 + end + table.insert(ret2, t) + end + return ret2 +end; +test_run:cmd("setopt delimiter ''"); net = require('net.box') box.schema.user.drop('testus') -- ------------------------------------------------------------ @@ -199,21 +244,21 @@ box.schema.user.drop('grantor') -- guest can't read _user table, add a test case -- ---------------------------------------------------------- session.su('guest') -box.space._user:select{0} -box.space._user:select{1} +select_user(0) +select_user(1) session.su('admin') -- ---------------------------------------------------------- -- A test case for gh-358 Change user does not work from lua -- Correct the update syntax in schema.lua -- ---------------------------------------------------------- box.schema.user.create('user1') -box.space._user.index.name:select{'user1'} +select_user('user1') session.su('user1') box.schema.user.passwd('new_password') session.su('admin') -box.space._user.index.name:select{'user1'} +select_user('user1') box.schema.user.passwd('user1', 'extra_new_password') -box.space._user.index.name:select{'user1'} +select_user('user1') box.schema.user.passwd('invalid_user', 'some_password') box.schema.user.passwd() session.su('user1') @@ -221,7 +266,7 @@ session.su('user1') box.schema.user.passwd('admin', 'xxx') session.su('admin') box.schema.user.drop('user1') -box.space._user.index.name:select{'user1'} +select_user('user1') -- ---------------------------------------------------------- -- A test case for gh-421 Granting a privilege revokes an -- existing grant @@ -246,8 +291,8 @@ box.space._priv:select{id} -- Be a bit more rigorous in what is accepted in space _user -- ----------------------------------------------------------- utils = require('utils') -box.space._user:insert{10, 1, 'name', 'strange-object-type', utils.setmap({})} -box.space._user:insert{10, 1, 'name', 'role', utils.setmap{'password'}} +box.space._user:insert{10, 1, 'name', 'strange-object-type', utils.setmap({}), {}, 0} +box.space._user:insert{10, 1, 'name', 'role', utils.setmap{'password'}, {}, 0} session = nil -- ----------------------------------------------------------- -- admin can't manage grants on not owned objects @@ -317,23 +362,23 @@ box.schema.user.passwd('guest', 'sesame') -- gh-1205 box.schema.user.info fails box.schema.user.drop('guest') box.schema.role.drop('guest') -box.space._user.index.name:delete{'guest'} -box.space._user:delete{box.schema.GUEST_ID} +delete_user('guest') +delete_user(box.schema.GUEST_ID) #box.schema.user.info('guest') > 0 box.schema.user.drop('admin') box.schema.role.drop('admin') -box.space._user.index.name:delete{'admin'} -box.space._user:delete{box.schema.ADMIN_ID} +delete_user('admin') +delete_user(box.schema.ADMIN_ID) #box.schema.user.info('admin') > 0 box.schema.user.drop('public') box.schema.role.drop('public') -box.space._user.index.name:delete{'public'} -box.space._user:delete{box.schema.PUBLIC_ROLE_ID} +delete_user('public') +delete_user(box.schema.PUBLIC_ROLE_ID) #box.schema.role.info('public') > 0 box.schema.role.drop('super') box.schema.user.drop('super') -box.space._user.index.name:delete{'super'} -box.space._user:delete{box.schema.SUPER_ROLE_ID} +delete_user('super') +delete_user(box.schema.SUPER_ROLE_ID) #box.schema.role.info('super') > 0 -- gh-944 name is too long @@ -785,20 +830,20 @@ box.schema.user.create("user2") box.schema.user.create("user3") box.schema.user.grant("user1", "write", "space", "_user") box.schema.user.grant("user1", "read", "space", "_user") -box.space._user:select{} +select_user() box.session.su("user1") -- can alter itself, but can't alter others without privileges. box.schema.user.passwd("user1", "abcd") box.schema.user.passwd("user2", "abcd") box.session.su("admin") -box.space._user:select{} +select_user() box.schema.user.grant("user1", "alter", "user", "user2") box.session.su("user1") box.schema.user.passwd("user2", "abcd") -- still fails box.schema.user.passwd("user3", "qewr") box.session.su("admin") -box.space._user:select{} +select_user() box.schema.user.drop("user1") box.schema.user.drop("user2") box.schema.user.drop("user3") diff --git a/test/box/access_bin.result b/test/box/access_bin.result index 7c720192ffac..3028a5f1ea85 100644 --- a/test/box/access_bin.result +++ b/test/box/access_bin.result @@ -210,7 +210,7 @@ c:close() ... box.space._user:replace(u) --- -- [1, 1, 'admin', 'user', {}] +- [1, 1, 'admin', 'user', {}, [], 0] ... -- -- gh-2763: test that universal access of an authenticated session diff --git a/test/box/access_misc.result b/test/box/access_misc.result index 1678641df389..34606bf2b89f 100644 --- a/test/box/access_misc.result +++ b/test/box/access_misc.result @@ -270,7 +270,7 @@ box.space.admin_space:select() ... box.space._user:select(1) --- -- - [1, 1, 'admin', 'user', {}] +- - [1, 1, 'admin', 'user', {}, [], 0] ... box.space._space:select(280) --- @@ -367,7 +367,7 @@ box.space._user:select(1) --- - error: Read access to space '_user' is denied for user 'testuser' ... -uid = box.space._user:insert{maxuid+1, session.uid(), 'someone', 'user', EMPTY_MAP}[1] +uid = box.space._user:insert{maxuid+1, session.uid(), 'someone', 'user', EMPTY_MAP, {}, 0}[1] --- ... _ = box.space._user:delete(uid) @@ -378,7 +378,7 @@ session.su('admin') ... box.space._user:select(1) --- -- - [1, 1, 'admin', 'user', {}] +- - [1, 1, 'admin', 'user', {}, [], 0] ... _ = box.space._user:delete(testuser_uid) --- @@ -402,7 +402,7 @@ _ = box.space._user:delete(2) ... box.space._user:select(1) --- -- - [1, 1, 'admin', 'user', {}] +- - [1, 1, 'admin', 'user', {}, [], 0] ... box.space._user:insert{uid, session.uid(), 'someone2', 'user'} --- diff --git a/test/box/access_misc.test.lua b/test/box/access_misc.test.lua index 683babd7cd04..28df5263c739 100644 --- a/test/box/access_misc.test.lua +++ b/test/box/access_misc.test.lua @@ -152,7 +152,7 @@ session.su('testuser') testuser_uid = session.uid() _ = box.space._user:delete(2) box.space._user:select(1) -uid = box.space._user:insert{maxuid+1, session.uid(), 'someone', 'user', EMPTY_MAP}[1] +uid = box.space._user:insert{maxuid+1, session.uid(), 'someone', 'user', EMPTY_MAP, {}, 0}[1] _ = box.space._user:delete(uid) session.su('admin')