mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-23 00:28:26 -05:00
d616925835
SET is a R+W command, because it can also do `GET` on the data. SET without GET is a write-only command. SET with GET is a read+write command. In #9974, we added ACL to let users define write-only access. So when the user uses SET with GET option, and the user doesn't have the READ permission on the key, we need to reject it, but we rather not reject users with write-only permissions from using the SET command when they don't use GET. In this commit, we add a `getkeys_proc` function to control key flags in SET command. We also add a new key spec flag (VARIABLE_FLAGS) means that some keys might have different flags depending on arguments. We also handle BITFIELD command, add a `bitfieldGetKeys` function. BITFIELD GET is a READ ONLY command. BITFIELD SET or BITFIELD INCR are READ WRITE commands. Other changes: 1. SET GET was added in 6.2, add the missing since in set.json 2. Added tests to cover the changes in acl-v2.tcl 3. Fix some typos in server.h and cleanups in acl-v2.tcl Co-authored-by: Madelyn Olson <madelyneolson@gmail.com> Co-authored-by: Oran Agra <oran@redislabs.com>
86 lines
3.1 KiB
Tcl
86 lines
3.1 KiB
Tcl
set testmodule [file normalize tests/modules/aclcheck.so]
|
|
|
|
start_server {tags {"modules acl"}} {
|
|
r module load $testmodule
|
|
|
|
test {test module check acl for command perm} {
|
|
# by default all commands allowed
|
|
assert_equal [r aclcheck.rm_call.check.cmd set x 5] OK
|
|
# block SET command for user
|
|
r acl setuser default -set
|
|
catch {r aclcheck.rm_call.check.cmd set x 5} e
|
|
assert_match {*DENIED CMD*} $e
|
|
|
|
# verify that new log entry added
|
|
set entry [lindex [r ACL LOG] 0]
|
|
assert {[dict get $entry username] eq {default}}
|
|
assert {[dict get $entry context] eq {module}}
|
|
assert {[dict get $entry object] eq {set}}
|
|
}
|
|
|
|
test {test module check acl for key perm} {
|
|
# give permission for SET and block all keys but x(READ+WRITE), y(WRITE), z(READ)
|
|
r acl setuser default +set resetkeys ~x %W~y %R~z
|
|
|
|
assert_equal [r aclcheck.set.check.key "*" x 5] OK
|
|
catch {r aclcheck.set.check.key "*" v 5} e
|
|
assert_match "*DENIED KEY*" $e
|
|
|
|
assert_equal [r aclcheck.set.check.key "W" y 5] OK
|
|
catch {r aclcheck.set.check.key "W" v 5} e
|
|
assert_match "*DENIED KEY*" $e
|
|
|
|
assert_equal [r aclcheck.set.check.key "R" z 5] OK
|
|
catch {r aclcheck.set.check.key "R" v 5} e
|
|
assert_match "*DENIED KEY*" $e
|
|
}
|
|
|
|
test {test module check acl for module user} {
|
|
# the module user has access to all keys
|
|
assert_equal [r aclcheck.rm_call.check.cmd.module.user set y 5] OK
|
|
}
|
|
|
|
test {test module check acl for channel perm} {
|
|
# block all channels but ch1
|
|
r acl setuser default resetchannels &ch1
|
|
assert_equal [r aclcheck.publish.check.channel ch1 msg] 0
|
|
catch {r aclcheck.publish.check.channel ch2 msg} e
|
|
set e
|
|
} {*DENIED CHANNEL*}
|
|
|
|
test {test module check acl in rm_call} {
|
|
# rm call check for key permission (x: READ + WRITE)
|
|
assert_equal [r aclcheck.rm_call set x 5] OK
|
|
assert_equal [r aclcheck.rm_call set x 6 get] 5
|
|
|
|
# rm call check for key permission (y: only WRITE)
|
|
assert_equal [r aclcheck.rm_call set y 5] OK
|
|
assert_error {*NOPERM*} {r aclcheck.rm_call set y 5 get}
|
|
|
|
# rm call check for key permission (z: only READ)
|
|
assert_error {*NOPERM*} {r aclcheck.rm_call set z 5}
|
|
assert_error {*NOPERM*} {r aclcheck.rm_call set z 6 get}
|
|
|
|
# verify that new log entry added
|
|
set entry [lindex [r ACL LOG] 0]
|
|
assert {[dict get $entry username] eq {default}}
|
|
assert {[dict get $entry context] eq {module}}
|
|
assert {[dict get $entry object] eq {z}}
|
|
|
|
# rm call check for command permission
|
|
r acl setuser default -set
|
|
catch {r aclcheck.rm_call set x 5} e
|
|
assert_match {*NOPERM*} $e
|
|
|
|
# verify that new log entry added
|
|
set entry [lindex [r ACL LOG] 0]
|
|
assert {[dict get $entry username] eq {default}}
|
|
assert {[dict get $entry context] eq {module}}
|
|
assert {[dict get $entry object] eq {set}}
|
|
}
|
|
|
|
test "Unload the module - aclcheck" {
|
|
assert_equal {OK} [r module unload aclcheck]
|
|
}
|
|
}
|