Skip to content

Commit 1ca4959

Browse files
committed
core: tube grant for roles
Adds ability to grant tubes for roles. Users ability to grant tubes is not affected.
1 parent e5383bd commit 1ca4959

10 files changed

Lines changed: 574 additions & 33 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
99

1010
### Added
1111

12+
- Ability to grant tubes to roles. All default tube drivers are supported (#249).
13+
Example: `queue.tube.my_tube:grant_role('queue_worker', {call = true})`
14+
1215
### Changed
1316

1417
### Fixed

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ align="right">
2929
* [Initialization](#initialization)
3030
* [Get the module version](#get-the-module-version)
3131
* [Creating a new queue](#creating-a-new-queue)
32+
* [Granting access to a queue](#granting-access-to-a-queue)
3233
* [Set queue settings](#set-queue-settings)
3334
* [Session identify](#session-identify)
3435
* [Putting a task in a queue](#putting-a-task-in-a-queue)
@@ -529,6 +530,33 @@ created.
529530

530531
Example: `queue.create_tube('list_of_sites', 'fifo', {temporary = true})`
531532

533+
## Granting access to a queue
534+
535+
```lua
536+
local tube = queue.create_tube('test_tube', 'fifo')
537+
tube:grant(user name [, {options} ])
538+
```
539+
540+
This function grants the user enough privileges to work with the tube using the
541+
Lua API (tube:put(), tube:take(), tube:ack(), etc.) when the code is executed
542+
inside Tarantool under that user.
543+
544+
Available `options`:
545+
* `call` - boolean - additionally grant permissions required to use the tube via remote
546+
calls (`net.box:call()`). When enabled, the module creates and grants execute privileges
547+
for `queue.identify`, `queue.statistics`, and `queue.tube.<tube_name>:*` functions.
548+
* `truncate` - boolean - additionally grant permission to truncate the tube via
549+
`queue.tube.<tube_name>:truncate` function. Useful when you want to allow clearing the
550+
tube contents.
551+
552+
```lua
553+
local tube = queue.create_tube('test_tube', 'fifo')
554+
tube:grant_role(role name [, {options} ])
555+
```
556+
557+
Same function as `tube:grant()`, but grants privileges to a role instead of a user.
558+
Any user who has this role will be able to access the tube. The options are the same.
559+
532560
## Set queue settings
533561

534562
```lua

queue/abstract.lua

Lines changed: 59 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -324,51 +324,79 @@ function tube.on_task_change(self, cb)
324324
return old_cb
325325
end
326326

327-
function tube.grant(self, user, args)
328-
if not check_state("grant") then
329-
return
327+
local function tube_grant_space(grantor, grantee, name, tp)
328+
grantor.grant(grantee, tp or 'read,write', 'space', name, {
329+
if_not_exists = true,
330+
})
331+
end
332+
333+
local function tube_grant_func(grantor, grantee, name)
334+
box.schema.func.create(name, { if_not_exists = true })
335+
grantor.grant(grantee, 'execute', 'function', name, {
336+
if_not_exists = true
337+
})
338+
end
339+
340+
local function grant_system_spaces(grantor, grantee)
341+
tube_grant_space(grantor, grantee, '_queue', 'read')
342+
tube_grant_space(grantor, grantee, '_queue_consumers')
343+
tube_grant_space(grantor, grantee, '_queue_taken_2')
344+
end
345+
346+
local function grant_args(grantor, grantee, args, name)
347+
if args.call then
348+
tube_grant_func(grantor, grantee, 'queue.identify')
349+
tube_grant_func(grantor, grantee, 'queue.statistics')
350+
local prefix = (args.prefix or 'queue.tube') .. ('.%s:'):format(name)
351+
tube_grant_func(grantor, grantee, prefix .. 'put')
352+
tube_grant_func(grantor, grantee, prefix .. 'take')
353+
tube_grant_func(grantor, grantee, prefix .. 'touch')
354+
tube_grant_func(grantor, grantee, prefix .. 'ack')
355+
tube_grant_func(grantor, grantee, prefix .. 'release')
356+
tube_grant_func(grantor, grantee, prefix .. 'peek')
357+
tube_grant_func(grantor, grantee, prefix .. 'bury')
358+
tube_grant_func(grantor, grantee, prefix .. 'kick')
359+
tube_grant_func(grantor, grantee, prefix .. 'delete')
330360
end
331-
local function tube_grant_space(user, name, tp)
332-
box.schema.user.grant(user, tp or 'read,write', 'space', name, {
333-
if_not_exists = true,
334-
})
361+
362+
if args.truncate then
363+
local prefix = (args.prefix or 'queue.tube') .. ('.%s:'):format(name)
364+
tube_grant_func(grantor, grantee, prefix .. 'truncate')
335365
end
366+
end
336367

337-
local function tube_grant_func(user, name)
338-
box.schema.func.create(name, { if_not_exists = true })
339-
box.schema.user.grant(user, 'execute', 'function', name, {
340-
if_not_exists = true
341-
})
368+
function tube.grant(self, user, args)
369+
if not check_state("grant") then
370+
return
342371
end
343372

344373
args = args or {}
345374

346-
tube_grant_space(user, '_queue', 'read')
347-
tube_grant_space(user, '_queue_consumers')
348-
tube_grant_space(user, '_queue_taken_2')
375+
grant_system_spaces(box.schema.user, user)
376+
349377
self.raw:grant(user, {if_not_exists = true})
350378
session.grant(user)
351379

352-
if args.call then
353-
tube_grant_func(user, 'queue.identify')
354-
tube_grant_func(user, 'queue.statistics')
355-
local prefix = (args.prefix or 'queue.tube') .. ('.%s:'):format(self.name)
356-
tube_grant_func(user, prefix .. 'put')
357-
tube_grant_func(user, prefix .. 'take')
358-
tube_grant_func(user, prefix .. 'touch')
359-
tube_grant_func(user, prefix .. 'ack')
360-
tube_grant_func(user, prefix .. 'release')
361-
tube_grant_func(user, prefix .. 'peek')
362-
tube_grant_func(user, prefix .. 'bury')
363-
tube_grant_func(user, prefix .. 'kick')
364-
tube_grant_func(user, prefix .. 'delete')
380+
grant_args(box.schema.user, user, args, self.name)
381+
end
382+
383+
function tube.grant_role(self, role, args)
384+
if not check_state("grant") then
385+
return
365386
end
366387

367-
if args.truncate then
368-
local prefix = (args.prefix or 'queue.tube') .. ('.%s:'):format(self.name)
369-
tube_grant_func(user, prefix .. 'truncate')
388+
args = args or {}
389+
390+
if self.raw.grant_role ~= nil then
391+
self.raw:grant_role(role, { if_not_exists = true })
392+
else
393+
error(('Tube %s driver does not support grant_role()'):format(self.name))
370394
end
371395

396+
grant_system_spaces(box.schema.role, role)
397+
session.grant_role(role)
398+
399+
grant_args(box.schema.role, role, args, self.name)
372400
end
373401

374402
-- methods

queue/abstract/driver/fifo.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ function method.grant(self, user, opts)
6666
box.schema.user.grant(user, 'read,write', 'space', self.space.name, opts)
6767
end
6868

69+
function method.grant_role(self, role, opts)
70+
box.schema.role.grant(role, 'read,write', 'space', self.space.name, opts)
71+
end
72+
6973
-- normalize task: cleanup all internal fields
7074
function method.normalize_task(self, task)
7175
return task

queue/abstract/driver/fifottl.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,10 @@ function method.grant(self, user, opts)
207207
box.schema.user.grant(user, 'read,write', 'space', self.space.name, opts)
208208
end
209209

210+
function method.grant_role(self, role, opts)
211+
box.schema.role.grant(role, 'read,write', 'space', self.space.name, opts)
212+
end
213+
210214
-- cleanup internal fields in task
211215
function method.normalize_task(self, task)
212216
return task and task:transform(3, 5)

queue/abstract/driver/utube.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,14 @@ function method.grant(self, user, opts)
134134
end
135135
end
136136

137+
function method.grant_role(self, role, opts)
138+
box.schema.role.grant(role, 'read,write', 'space', self.space.name, opts)
139+
if self.space_ready_buffer ~= nil then
140+
box.schema.role.grant(role, 'read,write', 'space',
141+
self.space_ready_buffer.name, opts)
142+
end
143+
end
144+
137145
-- normalize task: cleanup all internal fields
138146
function method.normalize_task(self, task)
139147
return task and task:transform(3, 1)

queue/abstract/driver/utubettl.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,14 @@ function method.grant(self, user, opts)
397397
end
398398
end
399399

400+
function method.grant_role(self, role, opts)
401+
box.schema.role.grant(role, 'read,write', 'space', self.space.name, opts)
402+
if self.space_ready_buffer ~= nil then
403+
box.schema.role.grant(role, 'read,write', 'space',
404+
self.space_ready_buffer.name, opts)
405+
end
406+
end
407+
400408
-- cleanup internal fields in task
401409
function method.normalize_task(self, task)
402410
return task and task:transform(i_next_event, i_data - i_next_event)

queue/abstract/queue_session.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,13 @@ local function grant(user)
292292
{ if_not_exists = true })
293293
end
294294

295+
local function grant_role(role)
296+
box.schema.role.grant(role, 'read, write', 'space', '_queue_session_ids',
297+
{ if_not_exists = true })
298+
box.schema.role.grant(role, 'read, write', 'space', '_queue_shared_sessions',
299+
{ if_not_exists = true })
300+
end
301+
295302
local function start()
296303
identification_init()
297304
queue_session.sync_chan = fiber.channel()
@@ -349,6 +356,7 @@ local method = {
349356
identify = identify,
350357
disconnect = disconnect,
351358
grant = grant,
359+
grant_role = grant_role,
352360
on_session_remove = on_session_remove,
353361
start = start,
354362
stop = stop,

0 commit comments

Comments
 (0)