diff options
Diffstat (limited to 'examples/redis-unstable/tests/unit/moduleapi/aclcheck.tcl')
| -rw-r--r-- | examples/redis-unstable/tests/unit/moduleapi/aclcheck.tcl | 207 |
1 files changed, 0 insertions, 207 deletions
diff --git a/examples/redis-unstable/tests/unit/moduleapi/aclcheck.tcl b/examples/redis-unstable/tests/unit/moduleapi/aclcheck.tcl deleted file mode 100644 index aa571b7..0000000 --- a/examples/redis-unstable/tests/unit/moduleapi/aclcheck.tcl +++ /dev/null | |||
| @@ -1,207 +0,0 @@ | |||
| 1 | set testmodule [file normalize tests/modules/aclcheck.so] | ||
| 2 | |||
| 3 | start_server {tags {"modules acl external:skip"}} { | ||
| 4 | r module load $testmodule | ||
| 5 | |||
| 6 | test {test module check acl for command perm} { | ||
| 7 | # by default all commands allowed | ||
| 8 | assert_equal [r aclcheck.rm_call.check.cmd set x 5] OK | ||
| 9 | # block SET command for user | ||
| 10 | r acl setuser default -set | ||
| 11 | catch {r aclcheck.rm_call.check.cmd set x 5} e | ||
| 12 | assert_match {*DENIED CMD*} $e | ||
| 13 | |||
| 14 | # verify that new log entry added | ||
| 15 | set entry [lindex [r ACL LOG] 0] | ||
| 16 | assert {[dict get $entry username] eq {default}} | ||
| 17 | assert {[dict get $entry context] eq {module}} | ||
| 18 | assert {[dict get $entry object] eq {set}} | ||
| 19 | assert {[dict get $entry reason] eq {command}} | ||
| 20 | } | ||
| 21 | |||
| 22 | test {test module check acl for key prefix permission} { | ||
| 23 | r acl setuser default +set resetkeys ~CART* %W~ORDER* %R~PRODUCT* ~ESCAPED_STAR\\* ~NON_ESCAPED_STAR\\\\* | ||
| 24 | |||
| 25 | # check for key permission of prefix CART* (READ+WRITE) | ||
| 26 | catch {r aclcheck.set.check.prefixkey "~" CAR CART_CLOTHES_7 5} e | ||
| 27 | assert_match "*DENIED KEY*" $e | ||
| 28 | assert_equal [r aclcheck.set.check.prefixkey "~" CART CART 5] OK | ||
| 29 | assert_equal [r aclcheck.set.check.prefixkey "W" CART_BOOKS CART_BOOKS_12 5] OK | ||
| 30 | assert_equal [r aclcheck.set.check.prefixkey "R" CART_CLOTHES CART_CLOTHES_7 5] OK | ||
| 31 | |||
| 32 | # check for key permission of prefix ORDER* (WRITE) | ||
| 33 | catch {r aclcheck.set.check.prefixkey "~" ORDE ORDER_2024_155351 5} e | ||
| 34 | assert_match "*DENIED KEY*" $e | ||
| 35 | assert_equal [r aclcheck.set.check.prefixkey "~" ORDER ORDER 5] OK | ||
| 36 | assert_equal [r aclcheck.set.check.prefixkey "W" ORDER_2024 ORDER_2024_564879 5] OK | ||
| 37 | assert_equal [r aclcheck.set.check.prefixkey "~" ORDER_2023 ORDER_2023_564879 5] OK | ||
| 38 | catch {r aclcheck.set.check.prefixkey "R" ORDER_2023 ORDER_2023_564879 5} | ||
| 39 | assert_match "*DENIED KEY*" $e | ||
| 40 | |||
| 41 | # check for key permission of prefix PRODUCT* (READ) | ||
| 42 | catch {r aclcheck.set.check.prefixkey "~" PRODUC PRODUCT_CLOTHES_753376 5} e | ||
| 43 | assert_match "*DENIED KEY*" $e | ||
| 44 | assert_equal [r aclcheck.set.check.prefixkey "~" PRODUCT PRODUCT 5] OK | ||
| 45 | assert_equal [r aclcheck.set.check.prefixkey "~" PRODUCT_BOOKS PRODUCT_BOOKS_753376 5] OK | ||
| 46 | |||
| 47 | # pattern ends with a escaped '*' character should not be counted as a prefix | ||
| 48 | catch {r aclcheck.set.check.prefixkey "~" ESCAPED_STAR ESCAPED_STAR_12 5} e | ||
| 49 | assert_match "*DENIED KEY*" $e | ||
| 50 | catch {r aclcheck.set.check.prefixkey "~" ESCAPED_STAR* ESCAPED_STAR* 5} e | ||
| 51 | assert_match "*DENIED KEY*" $e | ||
| 52 | assert_equal [r aclcheck.set.check.prefixkey "~" NON_ESCAPED_STAR\\ NON_ESCAPED_STAR\\clothes 5] OK | ||
| 53 | } | ||
| 54 | |||
| 55 | test {check ACL permissions versus empty string prefix} { | ||
| 56 | # The empty string should should match all keys permissions | ||
| 57 | r acl setuser default +set resetkeys %R~* %W~* ~* | ||
| 58 | assert_equal [r aclcheck.set.check.prefixkey "~" "" CART_BOOKS_12 5] OK | ||
| 59 | assert_equal [r aclcheck.set.check.prefixkey "W" "" ORDER_2024_564879 5] OK | ||
| 60 | assert_equal [r aclcheck.set.check.prefixkey "R" "" PRODUCT_BOOKS_753376 5] OK | ||
| 61 | |||
| 62 | # The empty string prefix should not match if cannot access all keys | ||
| 63 | r acl setuser default +set resetkeys %R~x* %W~x* ~x* | ||
| 64 | catch {r aclcheck.set.check.prefixkey "~" "" CART_BOOKS_12 5} e | ||
| 65 | assert_match "*DENIED KEY*" $e | ||
| 66 | } | ||
| 67 | |||
| 68 | test {test module check acl for key perm} { | ||
| 69 | # give permission for SET and block all keys but x(READ+WRITE), y(WRITE), z(READ) | ||
| 70 | r acl setuser default +set resetkeys ~x %W~y %R~z ~ESCAPED_STAR\\* | ||
| 71 | |||
| 72 | assert_equal [r aclcheck.set.check.key "*" x 5] OK | ||
| 73 | catch {r aclcheck.set.check.key "*" v 5} e | ||
| 74 | assert_match "*DENIED KEY*" $e | ||
| 75 | |||
| 76 | assert_equal [r aclcheck.set.check.key "~" x 5] OK | ||
| 77 | assert_equal [r aclcheck.set.check.key "~" y 5] OK | ||
| 78 | assert_equal [r aclcheck.set.check.key "~" z 5] OK | ||
| 79 | catch {r aclcheck.set.check.key "~" v 5} e | ||
| 80 | assert_match "*DENIED KEY*" $e | ||
| 81 | |||
| 82 | assert_equal [r aclcheck.set.check.key "W" y 5] OK | ||
| 83 | catch {r aclcheck.set.check.key "W" v 5} e | ||
| 84 | assert_match "*DENIED KEY*" $e | ||
| 85 | |||
| 86 | assert_equal [r aclcheck.set.check.key "R" z 5] OK | ||
| 87 | catch {r aclcheck.set.check.key "R" v 5} e | ||
| 88 | assert_match "*DENIED KEY*" $e | ||
| 89 | |||
| 90 | # check pattern ends with escaped '*' character | ||
| 91 | assert_equal [r aclcheck.set.check.key "~" ESCAPED_STAR* 5] OK | ||
| 92 | } | ||
| 93 | |||
| 94 | test {test module check acl for module user} { | ||
| 95 | # the module user has access to all keys | ||
| 96 | assert_equal [r aclcheck.rm_call.check.cmd.module.user set y 5] OK | ||
| 97 | } | ||
| 98 | |||
| 99 | test {test module check acl for channel perm} { | ||
| 100 | # block all channels but ch1 | ||
| 101 | r acl setuser default resetchannels &ch1 | ||
| 102 | assert_equal [r aclcheck.publish.check.channel ch1 msg] 0 | ||
| 103 | catch {r aclcheck.publish.check.channel ch2 msg} e | ||
| 104 | set e | ||
| 105 | } {*DENIED CHANNEL*} | ||
| 106 | |||
| 107 | test {test module check acl in rm_call} { | ||
| 108 | # rm call check for key permission (x: READ + WRITE) | ||
| 109 | assert_equal [r aclcheck.rm_call set x 5] OK | ||
| 110 | assert_equal [r aclcheck.rm_call set x 6 get] 5 | ||
| 111 | |||
| 112 | # rm call check for key permission (y: only WRITE) | ||
| 113 | assert_equal [r aclcheck.rm_call set y 5] OK | ||
| 114 | assert_error {*NOPERM*} {r aclcheck.rm_call set y 5 get} | ||
| 115 | assert_error {*NOPERM*No permissions to access a key*} {r aclcheck.rm_call_with_errors set y 5 get} | ||
| 116 | |||
| 117 | # rm call check for key permission (z: only READ) | ||
| 118 | assert_error {*NOPERM*} {r aclcheck.rm_call set z 5} | ||
| 119 | catch {r aclcheck.rm_call_with_errors set z 5} e | ||
| 120 | assert_match {*NOPERM*No permissions to access a key*} $e | ||
| 121 | assert_error {*NOPERM*} {r aclcheck.rm_call set z 6 get} | ||
| 122 | assert_error {*NOPERM*No permissions to access a key*} {r aclcheck.rm_call_with_errors set z 6 get} | ||
| 123 | |||
| 124 | # verify that new log entry added | ||
| 125 | set entry [lindex [r ACL LOG] 0] | ||
| 126 | assert {[dict get $entry username] eq {default}} | ||
| 127 | assert {[dict get $entry context] eq {module}} | ||
| 128 | assert {[dict get $entry object] eq {z}} | ||
| 129 | assert {[dict get $entry reason] eq {key}} | ||
| 130 | |||
| 131 | # rm call check for command permission | ||
| 132 | r acl setuser default -set | ||
| 133 | assert_error {*NOPERM*} {r aclcheck.rm_call set x 5} | ||
| 134 | assert_error {*NOPERM*has no permissions to run the 'set' command*} {r aclcheck.rm_call_with_errors set x 5} | ||
| 135 | |||
| 136 | # verify that new log entry added | ||
| 137 | set entry [lindex [r ACL LOG] 0] | ||
| 138 | assert {[dict get $entry username] eq {default}} | ||
| 139 | assert {[dict get $entry context] eq {module}} | ||
| 140 | assert {[dict get $entry object] eq {set}} | ||
| 141 | assert {[dict get $entry reason] eq {command}} | ||
| 142 | } | ||
| 143 | |||
| 144 | test {test blocking of Commands outside of OnLoad} { | ||
| 145 | assert_equal [r block.commands.outside.onload] OK | ||
| 146 | } | ||
| 147 | |||
| 148 | test {test users to have access to module commands having acl categories} { | ||
| 149 | r acl SETUSER j1 on >password -@all +@WRITE | ||
| 150 | r acl SETUSER j2 on >password -@all +@READ | ||
| 151 | assert_equal [r acl DRYRUN j1 aclcheck.module.command.aclcategories.write] OK | ||
| 152 | assert_equal [r acl DRYRUN j2 aclcheck.module.command.aclcategories.write.function.read.category] OK | ||
| 153 | assert_equal [r acl DRYRUN j2 aclcheck.module.command.aclcategories.read.only.category] OK | ||
| 154 | } | ||
| 155 | |||
| 156 | test {Unload the module - aclcheck} { | ||
| 157 | assert_equal {OK} [r module unload aclcheck] | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | start_server {tags {"modules acl external:skip"}} { | ||
| 162 | test {test existing users to have access to module commands loaded on runtime} { | ||
| 163 | r acl SETUSER j3 on >password -@all +@WRITE | ||
| 164 | assert_equal [r module load $testmodule] OK | ||
| 165 | assert_equal [r acl DRYRUN j3 aclcheck.module.command.aclcategories.write] OK | ||
| 166 | assert_equal {OK} [r module unload aclcheck] | ||
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| 170 | start_server {tags {"modules acl external:skip"}} { | ||
| 171 | test {test existing users without permissions, do not have access to module commands loaded on runtime.} { | ||
| 172 | r acl SETUSER j4 on >password -@all +@READ | ||
| 173 | r acl SETUSER j5 on >password -@all +@WRITE | ||
| 174 | assert_equal [r module load $testmodule] OK | ||
| 175 | catch {r acl DRYRUN j4 aclcheck.module.command.aclcategories.write} e | ||
| 176 | assert_equal {User j4 has no permissions to run the 'aclcheck.module.command.aclcategories.write' command} $e | ||
| 177 | catch {r acl DRYRUN j5 aclcheck.module.command.aclcategories.write.function.read.category} e | ||
| 178 | assert_equal {User j5 has no permissions to run the 'aclcheck.module.command.aclcategories.write.function.read.category' command} $e | ||
| 179 | } | ||
| 180 | |||
| 181 | test {test users without permissions, do not have access to module commands.} { | ||
| 182 | r acl SETUSER j6 on >password -@all +@READ | ||
| 183 | catch {r acl DRYRUN j6 aclcheck.module.command.aclcategories.write} e | ||
| 184 | assert_equal {User j6 has no permissions to run the 'aclcheck.module.command.aclcategories.write' command} $e | ||
| 185 | r acl SETUSER j7 on >password -@all +@WRITE | ||
| 186 | catch {r acl DRYRUN j7 aclcheck.module.command.aclcategories.write.function.read.category} e | ||
| 187 | assert_equal {User j7 has no permissions to run the 'aclcheck.module.command.aclcategories.write.function.read.category' command} $e | ||
| 188 | } | ||
| 189 | |||
| 190 | test {test if foocategory acl categories is added} { | ||
| 191 | r acl SETUSER j8 on >password -@all +@foocategory | ||
| 192 | assert_equal [r acl DRYRUN j8 aclcheck.module.command.test.add.new.aclcategories] OK | ||
| 193 | } | ||
| 194 | |||
| 195 | test {test permission compaction and simplification for categories added by a module} { | ||
| 196 | r acl SETUSER j9 on >password -@all +@foocategory -@foocategory | ||
| 197 | catch {r ACL GETUSER j9} res | ||
| 198 | assert_equal {-@all -@foocategory} [lindex $res 5] | ||
| 199 | assert_equal {OK} [r module unload aclcheck] | ||
| 200 | } | ||
| 201 | } | ||
| 202 | |||
| 203 | start_server {tags {"modules acl external:skip"}} { | ||
| 204 | test {test module load fails if exceeds the maximum number of adding acl categories} { | ||
| 205 | assert_error {ERR Error loading the extension. Please check the server logs.} {r module load $testmodule 1} | ||
| 206 | } | ||
| 207 | } | ||
