diff --git a/src/box/alter.cc b/src/box/alter.cc index 4ee8487dbbc192d5bf809b680a3ac0b5e0d24288..19db22a8d315909ab89825fde6a3f9947c09c3ca 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 Binary files a/src/box/bootstrap.snap and b/src/box/bootstrap.snap differ diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index ccec0990bfa1595a4985f803b1d9da69ba325699..cd06564e7b2d009fab7d7b4ec16495c63a02cbcb 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 cb6dfba24a3944f115cadb642406aa8613b80c59..2c7da702eb6b07a1c3fc21d02d1d37c6ddbc78ac 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 cf7fc7ece80f2382e478ef648fd3182adb338881..39fd94fe3ff973a990cab7710a19932ef5264e4c 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 db3d719861148826666f44a9dc0d8df20c5b7ac6..4f5806e4273c44994cbcb2d3bc700712223b93a7 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 efeb9774cdcfd5bdeebd9ec34166e9b61c9c84e2..7acc525b6af7b0e7a5eee3a0a8ca6b7d42cda82d 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 Binary files /dev/null and b/test/box-luatest/upgrade/2.10.4/00000000000000000009.snap differ 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 0000000000000000000000000000000000000000..d834907e3d250ed91ad8dfd8b4e766454187093f --- /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 d24b5f0474a3ba15f17595c0fd78637b314ddd49..13101dec7caa8707794dc708ae4477aa699fb260 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 f70289caf4f8a0c35717d322f21060cde520f2b8..8148fd97d4daddf7af6e106445c4d580e8c08c20 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 b9608f2142bedf30f5bd3ea4b50e805aa655a2f3..9c81b11aa86f4b042d59a637a78ced33591c4737 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 7c720192ffac9a2deb0d2c520ec5ca625cd41abf..3028a5f1ea85ac86c33caa4550a882a27ac39d59 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 1678641df389a191c63c15f1edde5b050c741131..34606bf2b89f2493ae9b6b3b579ea7308590ca0c 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 683babd7cd045c99a924d90a7001f5ff9c8d7477..28df5263c739937ebe6ea98a7bba141770e4fadd 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')